I'm new to Win32 API and though doing a trainer would be a good introduction. I'm using Borland C++ free command line tools 5.5 as my implementation language. Running on XP Pro SP1.

For some reason the code below always fails at the WriteProcessMemory stage (returns false). Can anyone suggest why?

------------------ start code ---------------------------
#include <windows.h>

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
DWORD aMoney = 0x09660106; //money address in C&C Gold
BYTE poke[]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

HWND hWndTarget = FindWindow(NULL, "Command & Conquer");
if(hWndTarget == NULL)
{
MessageBox(NULL, "Command & Conquer not running.", "Error", MB_OK);
return 1;
}

DWORD dwProcessId;
GetWindowThreadProcessId(hWndTarget, &dwProcessId);
HANDLE p_hand = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
if(p_hand == NULL)
{
MessageBox(NULL, "Could not attach to process.", "Error", MB_OK);
return 1;
}

BOOL ebx = WriteProcessMemory(p_hand, &aMoney, &poke, 4, NULL);
if(!ebx)
{
DWORD error = GetLastError();
MessageBox(NULL, "Error writing to process.", "Error", MB_OK);
CloseHandle(p_hand);
return 1;
}

CloseHandle(p_hand);
MessageBox(NULL, "All done!", "Done", MB_OK);
return 0;
}
------------------- end code ----------------------------
Posted on 2004-07-27 08:00:23 by
Hmmm, I just realised this is an ASM only board. Sry, but if you can help me out I'm still interested.
Posted on 2004-07-27 08:12:21 by
Check the return value from GetLastError, you can convert it into readable text using the FormatMessage API, it will tell you more about why WriteProcessMemory is failing.
Posted on 2004-07-27 08:19:17 by donkey
Originally posted by kufudo
DWORD aMoney = 0x09660106; //money address in C&C Gold
BYTE poke[]={0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

:
:

BOOL ebx = WriteProcessMemory(p_hand, &aMoney, &poke, 4, NULL);
if(!ebx)
{
DWORD error = GetLastError();
MessageBox(NULL, "Error writing to process.", "Error", MB_OK);
CloseHandle(p_hand);
return 1;
}

:
:

}


first about... we got code-tags here :)
two mistakes here:
&aMoney should be aMoney. &aMoney gives the address of the variable in your program. aMoney is the value of the variable (containing the address you want to write to).
the second mistake is the &poke, it should be poke. writing poke is already the address of the array. if you write &poke, it'll be the address of the array-pointer (the location where the array-pointer is in your program)
Posted on 2004-07-27 13:44:27 by hartyl



&aMoney should be aMoney. &aMoney gives the address of the variable in your program. aMoney is the value of the variable (containing the address you want to write to).
the second mistake is the &poke, it should be poke. writing poke is already the address of the array. if you write &poke, it'll be the address of the array-pointer (the location where the array-pointer is in your program)


I tried that (aMoney instead of &aMoney) but I get a compile error.

Error E2034 main.cpp 25: Cannot convert 'unsigned long' to 'void *' in function

__stdcall WinMain(HINSTANCE__ *,HINSTANCE__ *,char *,int)
Error E2342 main.cpp 25: Type mismatch in parameter 'lpBaseAddress' (wanted 'voi
d *', got 'unsigned long') in function __stdcall WinMain(HINSTANCE__ *,HINSTANCE
__ *,char *,int)
Posted on 2004-07-27 17:27:38 by
It is critical that you specify the error code you received from GetLastError, it is there for a reason and will tell you much about why the function is failing.
Posted on 2004-07-27 17:33:43 by donkey

It is critical that you specify the error code you received from GetLastError, it is there for a reason and will tell you much about why the function is failing.


Yep. Just learned that the hardway I guess. I used this piece of code to get the error message being generated:

LPVOID lpMessageBuffer;

FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(),
LANG_USER_DEFAULT, (LPSTR)&lpMessageBuffer, 0, NULL);
MessageBox(NULL, (char*)lpMessageBuffer, "Error", MB_OK);


The error was 'Attempt to access invalid address'. Turns out when I jotted the address down on paper I wrote a 6 instead of a C. How's that for a stupid error? Good thing my code didn't work. haha
Posted on 2004-07-27 18:08:54 by



Yep. Just learned that the hardway I guess. I used this piece of code to get the error message being generated:

LPVOID lpMessageBuffer;

FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(),
LANG_USER_DEFAULT, (LPSTR)&lpMessageBuffer, 0, NULL);
MessageBox(NULL, (char*)lpMessageBuffer, "Error", MB_OK);


The error was 'Attempt to access invalid address'. Turns out when I jotted the address down on paper I wrote a 6 instead of a C. How's that for a stupid error? Good thing my code didn't work. haha


Try it with following code:



char szErrMsgBuf [255];

LPVOID lpMessageBuffer = &szErrMsgBuf;

FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(),
LANG_USER_DEFAULT, (LPSTR)&lpMessageBuffer, 0, NULL);

MessageBox(NULL, (char*)lpMessageBuffer, "Error", MB_OK);
Posted on 2004-07-28 03:29:32 by purpleendurer