I'm not going to touch this, it's clear from your WPM and RPM function calls you don't know what you're doing. And you're using
Read a guide on RPM. Will give you a better understanding of why you're getting an error.Code:using namespace std;
Hello, im having major issues with using the pointer and offsets provided by the Cheat Engine pointer scan.
I know i need to:
-Get address of exe
-Add it to the base address provided
-Read address in memory
-Add offsets
-Write to memory
I'm using GetLastError() and getting error 487 which is an invalid address error, please help
Code:#include <iostream> #include <windows.h> #include <TlHelp32.h> using namespace std; DWORD moneyBaseAddress = 0x011FE910; DWORD moneyOffset1 = 0x40; DWORD moneyOffset2 = 0x30; int desiredMoney = 500; DWORD GetModuleBase(LPSTR lpModuleName, DWORD dwProcessId) { MODULEENTRY32 lpModuleEntry = { 0 }; HANDLE hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwProcessId); if (!hSnapShot) return NULL; lpModuleEntry.dwSize = sizeof(lpModuleEntry); BOOL bModule = Module32First(hSnapShot, &lpModuleEntry); while (bModule) { if (!strcmp((const char*)lpModuleEntry.szModule, lpModuleName)) { CloseHandle(hSnapShot); return (DWORD)lpModuleEntry.modBaseAddr; } bModule = Module32Next(hSnapShot, &lpModuleEntry); } CloseHandle(hSnapShot); return NULL; } void ModifyMoneyMemory() { HWND hWnd = FindWindow(NULL, L"American Truck Simulator"); if (hWnd == 0) { cout << "Could not find American Truck Simulator Process :(. Please make sure it is running." << endl; } else { DWORD pId; GetWindowThreadProcessId(hWnd, &pId); HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pId); if (!hProc) { cout << "Cannot open process. Make sure this hack is running in administrator." << endl; } else { cout << "Enter desired money amount: " << endl; cin >> desiredMoney; DWORD modBase = GetModuleBase("American Truck Simulator", pId); cout << modBase << endl; DWORD address = (DWORD)(modBase + 0x011FE910); ReadProcessMemory(hProc, (LPCVOID)address, &address, sizeof(address), NULL); address += 0x40 + 0x30; //VirtualProtectEx(hProc, (LPVOID)addy, 1, PAGE_READWRITE, &oldProtect); if (WriteProcessMemory(hProc, (LPVOID)address,&desiredMoney, 4, NULL)) { cout << "Memory successfully written to. Enjoy :)" << endl; } else { cout << "Cannot write to memory :(. Please try again." << " Error: " << GetLastError() << endl; } // VirtualProtectEx(hProc, (LPVOID)offsetedMoneyAddress, 1, oldProtect, &oldProtect); CloseHandle(hProc); } } }
I'm not going to touch this, it's clear from your WPM and RPM function calls you don't know what you're doing. And you're using
Read a guide on RPM. Will give you a better understanding of why you're getting an error.Code:using namespace std;
Hey we all start somewhere. I have programming experience, however I am completely new to the whole Read/Write memory thing. Only even trying it the past few days. I understand more than enough how the WPM and RPM work. I am following the steps I perceive to be necessary to edit memory. I appreciate the link to the article which I will have a shift through. Thanks!
Last edited by DaedricWolf; 02-21-2016 at 05:39 PM.
..so why not just add 0x70? doesn't make sense.ReadProcessMemory(hProc, (LPCVOID)address, &address, sizeof(address), NULL);
address += 0x40 + 0x30;
I'd guess you're meant to add 0x40 and read an addr from that loc...then add 0x30 to that (read) value.
ex.
x = [base + offset] <-- read pointer from this address
y = [x + offset1] <-- read pointer from this address
z = y + offset2 <-- final location
..depending on the game, you might have to follow 100 pointers, or maybe just 1..all depends on the game and how its classes/ memory/etc are laid out.
And that last offset, maybe you're supposed to read a pointer from it to get the final location, or maybe it is the final location..there is no rule saying which it is: could be the version above, or the one below.
x = [base + offset] <-- read pointer from this address
y = [x + offset1] <-- read pointer from this address
z = [y + offset2] <-- read pointer from this address. read value is final loc.
CE shows you.. [ ]'s == read a pointer from the location ie. y = [x+offset] <-- read 4 bytes from [x+offset]
If there aren't []'s, just add the items together to get the loc. <-- final loc is x+offset
Last edited by abuckau907; 02-21-2016 at 06:37 PM.
'Some things that can be counted, don't matter. And some things that matter, can't be counted' - A.E.
--
So, i took a large stab at it tonight. One issue was that getting the base address of the exe wasn't working, i fixed this then ran into some issues realizing that the function gave me it out in decimal values instead of hexadecimal, i've edited it but now am getting an ouput of 0 in decimal and lots of c's in hex. Here is the code
Any help would be appreciated, I know a lot of people on here don't like giving proper answers so a point in the right direction will doCode:DWORD modBase = dwGetModuleBaseAddress("amtrucks.exe"); if (modBase == NULL) cout << "Mod base is null" << endl; //Covert module base address to hexadecimal stringstream ss; ss >> hex >> modBase; cout << modBase << endl; DWORD buffer, buffer2, buffer3; DWORD address, address2; ReadProcessMemory(hProc, (LPCVOID)(modBase + 0x011FE910), &buffer, sizeof(buffer), 0); address = buffer + 0x40; ReadProcessMemory(hProc, (LPCVOID)address, &buffer2, sizeof(buffer2), 0); address2 = buffer2 + 0x30;
- - - Updated - - -
It is actually bad coding, and i know this. If you need an excuse i just threw it in to see if i could get this program working, i only expected it to take a few hours to complete to be utterly honest.
(instead of importing the namespace, you can use something like "using std::cout; using std::endl;" to import only those 2 items)
1. if 'modBase' is actually 0, you're letting the rest of the code run, which is almost guaranteed not to work as you expect and/or crash.
2. based on the code you provided: I don't see how you could be getting "lots of CC's" because you don't actually use the 'ss' variable. Don't answer that, I know you "changed it because it wasn't working"
-- did you verify (im not going to tell you..) this is a correct way to convert to/display as a hex string? Or did you just 'throw it in the mix'...logically, if modBase isn't 0, then the problem is with your method of converting to hex and/or displaying it (why not cout << hex << modBase; ?) Test it in a separate function and verify that it is a good way to convert/display as hex string.
--if modBase is actually 0, set a breakpoint on the code in your dwGetModuleBaseAddr function where it's comparing the argument you passed in to all the module names..does dwGetModuleBaseAddr actually enumerate over the module you're expecting (perhaps without .exe in the name?)
3. after you've solved the above issues, make sure ReadProcessMemory isn't the problem...maybe you called OpenProcess() with the wrong permission value(s) -- check the return value of rpm() and make sure it's not telling you there was an error. Similarly, you should be checking the return value from OpenProcess() to make sure it went good..looks ok in your first example, but I can only guess how many changes you've made since then : p
^^this isn't C++ specific, it's common sense.
Last edited by abuckau907; 02-22-2016 at 07:07 PM.
'Some things that can be counted, don't matter. And some things that matter, can't be counted' - A.E.
--
I was expecting this answer. Wrong. using namespace std; is perfectly fine if used within a translation unit. It's bad when used in header files (you can't know in which context the header file will be included). Ambiguity.
Or, to better, you can just use it in more particular portions of the code:
But it wasn't anyway relevant to the problem: it's the classic irrilevant thing.Code:void hello() { using namespace std; ... }
Last edited by maestro1994; 02-23-2016 at 04:45 AM.
So, i gave in and wrote an injector then preceded to change it into a DLL for direct memory access. Would like to get this finished so needing some final help regarding the addresses. Just to make sure im doing this right. In cheat engine i have:
offset of 30 401FAA900+30 = 401FAA930
offset of 40 [401F326C0+40] -> 401FAA900
"amtrucks.exe" + +011FE910 -> 401F326C0
my code is:
Could someone tell me if what i am doing with the pointers is correct?Code:// ATSD.cpp : Defines the exported functions for the DLL application. // #include "stdafx.h" #include "ATSD.h" #define MONEY_ADDR 0x011FE910 #define MONEY_OFS1 0x00000040 #define MONEY_OFS2 0x00000030 void ATSD::Debug() { AllocConsole(); han = GetStdHandle(STD_OUTPUT_HANDLE); WriteConsole(han, "hello", 6, new DWORD, 0); } DWORD ATSD::GetAddress(DWORD processBaseAddress, DWORD baseAddress, DWORD offsets[], int offsetCount) { DWORD address; // Where the final address will be stored address = *(DWORD*)(processBaseAddress + baseAddress); // Add the base address to the modules base address. // Loop through each offset for (int i = 0; i < offsetCount; i++) { address = *(DWORD*)(address + offsets[i]); } return address; } DWORD ATSD::GetProcessBaseAddress() { MODULEENTRY32 me32 = { sizeof(MODULEENTRY32) }; HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, GetCurrentProcessId()); if (hSnapshot == INVALID_HANDLE_VALUE) return 0; if (Module32First(hSnapshot, &me32)) { CloseHandle(hSnapshot); return (DWORD)me32.modBaseAddr; } CloseHandle(hSnapshot); return 0; } void ATSD::MoneyModify() { DWORD base = GetProcessBaseAddress(); DWORD offsets[] = {MONEY_OFS1, MONEY_OFS2}; // DWORD address = GetAddress(base, MONEY_ADDR , offsets, 2); DWORD x = *(DWORD*)(base + MONEY_ADDR); DWORD y = *(DWORD*)(x + offsets[0]); DWORD z = (DWORD)(y + offsets[1]); int* moneyPointer = (int*)z; *moneyPointer = 1; }
my .h is:
My injector works fineCode:#pragma once #include <Windows.h> #include <TlHelp32.h> class ATSD { public: void Debug(); void MoneyModify(); private: DWORD GetProcessBaseAddress(); DWORD GetAddress(DWORD processBaseAddress, DWORD baseAddress, DWORD offsets[], int offsetCount); HANDLE han; };
Last edited by DaedricWolf; 02-24-2016 at 08:50 AM.