Win32 WriteProcessMemory () magic offset value
I am trying to read data in a Win32 ListView owned by another process. Unfortunately, my call to WriteProcessMemory () failed with the error "This function is not supported on this system." when I specify "NULL" for the base address in my VirtualAlloc () call. If, however, I compensated for this VirtualAlloc () address with some "magic" value, which I was lucky enough to pick at random at the moment of disappointment, the call works on my system, but does not work on others. (see code below)
Can anyone suggest that this is a magic offset for me? Through trial and error, I can find values ββthat work on certain systems, but I cannot find a general solution to this problem.
Thanks, PaulH
#define MAGIC_OFFSET (DWORD)0x01020000
LVHITTESTINFO hti = { 0 };
hti.pt = clientPoint;
LPVOID lpBuffer = ::VirtualAlloc( NULL, 1, MEM_RESERVE, PAGE_READWRITE );
::VirtualFree( lpBuffer, 0, MEM_RELEASE );
lpBuffer = ::VirtualAlloc( (LPVOID)((DWORD)lpBuffer + MAGIC_OFFSET), sizeof( hti ), MEM_RESERVER, PAGE_READWRITE );
DWORD dwBuffer = (DWORD)lpBuffer + MAGIC_OFFSET - sizeof( hti );
if( !::WriteProcessMemory( hProcess, (LPVOID)dwBuffer, (LPVOID)&hti, sizeof( hti ), NULL ) )
return 0;
if( ListView_HitTest( hWndListView, (LPVOID)dwBuffer ) < 0 )
return 0;
if( !::ReadProcessMemory( hProcess, (LPVOID)dwBuffer, (LPVOID)&hti, sizeof( hti ), NULL ) )
return 0;
::VirtualFree( lpBuffer, 0, MEM_RELEASE );
Clarification (Cd-MaN added): This is on Windows Mobile platform, possibly non-x86 architecture. So the situation can be different (are there separate address spaces in ARM processors?).
source to share
Instead of trying to allocate memory in another process, why not use named shared memory instead. This article will walk you through the basic setup of shared memory , and I did a quick test to make sure these features are supported by Windows Mobile 5 .
source to share
VirtualAlloc allocates memory in YOUR address space . It is absolutely wrong to use this address when writing the memory space of another process. You have to use VirualAllocEx and pass to hProcess.
You just get lucky and write on a random chunk of memory when it works.
If specifying NULL on the first parameter of VirtualAllocEx is not supported when requesting another process (don't know if it is or not) ... then you can use VirtualQueryEx to map the address space of the other process and find a valid free area to navigate to VirtualAlloc.
You will most likely have to put this in a loop, as the state of another address space might change while you are looking for an empty space.
source to share
You must keep in mind that you are writing the virtual address space of the program. On Windows, this often starts with an address such as your magic number.
Have you ever debugged a program? What do the addresses look like?
On my system, executables are usually loaded around 00400000 or 01000000. They change from executable to executable, and I believe that Windows can change this address even in successive runs of the same executable.
In addition, executable files have sections that have their own (and relatively smaller) offsets. For example, the code section is usually +1000, followed by data, zeroed data sections, etc.
All this means that if your executable has a base 00400000, and the data section has an offset of +2000, the first byte of data will be at 00402000. To read / write this byte, you will have to specify the base address 00402000, not 2000, and definitely not 0.
Try to print the pointer value. If the object that the object is pointing to has a static lifetime, it will probably be in the data section and you will get an address such as 00402000. Then, if you WriteProcessMemory to that address, you change the object.
The various Win32 executable formats contain this base address "0040000" as well as the offsets of the various sections, but since such a hack reading different process memory is likely to target a specific version of a particular executable anyway, you might be better off leaving magic number as it is.
source to share