2

I am trying to read a value of an address but i can't really seem to do it. I'm trying to get : client.dll + 0xA9C0DC + 0x00FC . I'm just trying to read the health of the player from a game. This is my code :

#include <iostream>
#include <Windows.h>
#include <string>

DWORD pid;
DWORD Address = 0xA9C0DC;
int cHealth;

int main()
{
    HWND hWnd = FindWindowA(0, ("Counter-Strike: Global Offensive"));

        GetWindowThreadProcessId(hWnd, &pid);
        HANDLE pHandle = OpenProcess(PROCESS_VM_READ, FALSE, pid);

        while(true)
        {
            ReadProcessMemory(pHandle, (LPVOID)(Address + 0x00FC), &cHealth, 
                                                      sizeof(cHealth), 0);
        std::cout << cHealth <<std::endl;
        Sleep(200);
    }
    return 0;
}

Instead of (Address + 0x00FC) i've tried DWORD Address = 0xA9C0DC + 0x00FC; or

DWORD Address1 = 0xA9C0DC;
DWORD offset = 0x00FC;
DWORD Address = Address1 + offset; //or DWORD Address = (DWORD)(Address1 + offset)

Nothing seems to work. Can i get some help ?

wkup
  • 79
  • 1
  • 1
  • 8
  • not that I expect people to help you on this (because it seems you may be trying to cheat) but would you care to elaborate on "Nothing seems to work."? And where did you get that address from? – Borgleader Jan 11 '18 at 14:04
  • Check the return values of the WinAPI functions. Probably protected memory. – Hatted Rooster Jan 11 '18 at 14:05
  • @Borgleader this is an output (everytime i restart the game it's different probably because there are dynamic addresses) https://i.imgur.com/XzGp71n.png – wkup Jan 11 '18 at 14:17
  • @RickAstley don't think so . after searching with cheatengine i could found an address for the health . if i put the address in my program the output is perfect but this address is dynamic so i would have to change it everytime .. – wkup Jan 11 '18 at 14:24
  • @wkup anything I need to add to my answer to get you to mark it as best answer? – GuidedHacking May 23 '18 at 00:26
  • @Borgleader Bold of you to assume that we are too noble to use our powers for evil – Some Guy Feb 07 '22 at 02:48

2 Answers2

4

You must first get the base address of the client.dll module. To do this, you can walk the module list using ToolHelp32Snapshot(), find the matching module and read the modBaseAddr member variable.

Here is a sample code to do so:

uintptr_t GetModuleBaseAddress(DWORD dwProcID, char* szModuleName)
{
    uintptr_t ModuleBaseAddress = 0;
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, dwProcID);
    if (hSnapshot != INVALID_HANDLE_VALUE)
    {
        MODULEENTRY32 ModuleEntry32;
        ModuleEntry32.dwSize = sizeof(MODULEENTRY32);
        if (Module32First(hSnapshot, &ModuleEntry32))
        {
            do
            {
                if (strcmp(ModuleEntry32.szModule, szModuleName) == 0)
                {
                    ModuleBaseAddress = (uintptr_t)ModuleEntry32.modBaseAddr;
                    break;
                }
            } while (Module32Next(hSnapshot, &ModuleEntry32));
        }
        CloseHandle(hSnapshot);
    }
    return ModuleBaseAddress;
}

Then do:

//get base address
uintptr_t clientdllbaseaddr = GetModuleBaseAddress(dwProcId, "client.dll");

//add relative offset to get to pointer
uintptr_t playerPtr = clientdllbaseaddr + 0xA9C0DC;

//dereference the pointer using RPM, this gives you the dynamic address of the player object
uintptr_t playerObjectAddr;
ReadProcessMemory(pHandle, (LPVOID)playerPtr, &playerObjectAddr, sizeof(playerObjectAddr), NULL);

//add health offset
uintptr_t healthAddress = playerObjectAddr + 0xFC;

//Overwrite the value
int newValue = 1337;
WriteProcessMemory(pHandle, (LPVOID)healthAddress, &newvalue, sizeof(newValue), NULL);

Please note I'm using uintptr_t which is an architecture agnostic typedef: it will resolve to a 32-bit variable when compiled in x86 and a 64-bit value in x64, so you will want to compile your project in whatever architecture the game uses. It is helpful to start doing this now so you don't have to change all your code when you move to x64 games in the future.

Also note I do not use VirtualProtectEx() to take read/write permissions because it's typically not necessary for data sections, but if you mess with code sections you will need to use it.

Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
GuidedHacking
  • 3,628
  • 1
  • 9
  • 59
0
DWORD Address = 0xA9C0DC;
long long Address = 0xA9C0DC;

I would just change this to a long long. If this dosen't work then there is some problem with the address.

It could also be that you are using the wrong bit (I do not know that much about bits, 32, 64, 84) because I think you may be using the wrong one

Boiling T
  • 1
  • 1