0

I am trying to create a game trainer for a game. I have found the needed memory addresses and now I want to write my values into that address.

For example: address of ammo is: 0x0E9AFD07

The WriteProcessMemory() function in the Windows API can do this.

My source:

int main(){
    DWORD pid;
    int address = 0x0E9AFD07;
    const int data = 20;
    HWND hwnd = FindWindow(0 , "Max Payne v1.05");
    GetWindowThreadProcessId(hwnd , &pid);
    HANDLE hndl = OpenProcess(PROCESS_ALL_ACCESS , false ,pid);
    WriteProcessMemory(hndl , &address , &data , 4 , NULL); 

    return 0;
}

But this code does not work!

If I should use WriteProcessMemory like below:

WriteProcessMemory(hndl , (void*)0x0E9AFD07 , &data , 4 , NULL); 

then the second parameter of the function is LPVOID type and I read that LPVOID is a pointer to anything.

So, why I can't pass a pointer to int (address variable) for the second parameter?

And why should I use (void*)?

Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
  • oh sorry . why we use (void*) before the address ? – Hossein Ahmadi Mar 22 '21 at 11:16
  • Sorry about the multiple edits. But please clarify which language (C or C++). The use of `false` *suggests* C++ but that may be defined (as 0) in C. And the `OpenProcess` process takes a `BOOL` second parameter. – Adrian Mole Mar 22 '21 at 11:31

2 Answers2

2
  • Why should I use (void*)

    Because that's what the manual tells you that the function expects. Specifically:

    lpBaseAddress

    A pointer to the base address in the specified process to which data is written. Before data transfer occurs, the system verifies that all data in the base address and memory of the specified size is accessible for write access, and if it is not accessible, the function fails.

  • For the same reason, you can't pass the address of your local variable in turn containing the address, because that's not what the function expects.

  • LPVOID is just Windows gibberish for void*, they are identical types.

  • In order to turn an integer address into a pointer type, you need to cast, because that's how C and C++ were designed. You can't assign an integer to a pointer, see "Pointer from integer/integer from pointer without a cast" issues.

  • Notably 0x0E9AFD07 is a misaligned address, so writing a 4 byte integer to that address is fishy.

Lundin
  • 195,001
  • 40
  • 254
  • 396
0

Note that your two code snippets are not equivalent; rather, they are asking the WriteProcessMemory function to write data to different locations.

In the second snippet, you pass 0x0E9AFD07 (as a void*), which tells the function to write the data to memory starting at the given address (the hex value passed).

However, in the first snippet, you are passing the address of the int variable (which just happens to contain the value 0x0E9AFD07); this will instruct the function to write data to the location of that variable - thus, overwriting the 0x0E9AFD07 value that is there (or failing in the attempt to do so).

If you want to pass an address stored in a local variable, then you need to cast the value of that variable to a void* pointer, like this:

int main(){
    DWORD pid;
    int address = 0x0E9AFD07;
    const int data = 20;
    HWND hwnd = FindWindow(0 , "Max Payne v1.05");
    GetWindowThreadProcessId(hwnd , &pid);
    HANDLE hndl = OpenProcess(PROCESS_ALL_ACCESS , false ,pid);
    // The "int" variable's VALUE is the target address, so cast/pass that...
    WriteProcessMemory(hndl , (void*)address , &data , 4 , NULL); 

    return 0;
}
Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
  • Although it is a relatively common C extension, it *is* an extension for `int` to be converted to any pointer type without a cast. Even with C compilers that provide such an extension, it typically depends on compile options whether such conversions will be performed. – John Bollinger Mar 22 '21 at 11:37
  • "if using C, the compiler will implicitly cast the int to a void*" No, that is plain wrong. If you are using a conforming compiler, there will be a diagnostic message since you wrote invalid C. https://stackoverflow.com/questions/52186834/pointer-from-integer-integer-from-pointer-without-a-cast-issues – Lundin Mar 22 '21 at 11:44