Introduction
I've always wondered how debuggers could read and edit the memory of ordinary
programs. I used to think it was a complicated process and that it involved low-level
programming techniques. Much to my disappointment, I couldn't find any articles
covering this subject.
After some research (and asking around on the boards) I found it's possible to read
the memory of processes by calling a few Win32 APIs. It only works under WinNT with
admin access, though.
How does the class work?
Basically, there are two things that need to be done in order to get full memory access.
Getting the Process ID of the program that needs debugging. This can be easily
achieved using GetWindowThreadProcessId(hWnd, The_Process_ID)
Opening the process :
handle_to_Process = OpenProcess(PROCESS_VM_READ
|PROCESS_VM_WRITE|
PROCESS_VM_OPERATION
|PROCESS_QUERY_INFORMATION,
FALSE, The_Process_ID);
Reading and writing to the memory
Now we have a handle to an opened process, we can write and read at will.
DWORD iAddress = 0x234343;
DWORD dummy;
int value;
if (!ReadProcessMemory(handle_to_Process
,(void*) iAddress,
(void*) &value,
sizeof(value)
,&dummy))
{
m_sError = _T("Failed to read memory.");
return FALSE;
}
The last parameter doesn't contain valuable information. It can be used to check how
many bytes are actually written into the memory, but if one uses fixed sized variables
there's nothing that can go wrong.
The CProcessMem class
This class makes editing memory even easier, it has the following functions:
bool InitModule (HWND hWnd);
bool InitModule (DWORD processID);
bool InitModule (CString wndTitle);
bool ReadVal (DWORD iAddress, BYTE &value);
bool WriteVal (DWORD iAddress, BYTE value);
bool ReadVal (DWORD iAddress, short int &value);
bool WriteVal (DWORD iAddress, short int value);
bool ReadVal (DWORD iAddress, int &value);
bool WriteVal (DWORD iAddress, int value);
bool ReadVal (DWORD iAddress, CString &text);
bool WriteVal (DWORD iAddress, CString text);
At the moment there is no support for searching within the virtual memory. It
can be done fairly easily with QueryVirtualEx()
though.
Notes:
- All functions return a boolean value. If a function returns
FALSE
, then you can
get a more specific error message by checking CProcessMem::m_sError
- The
ProcessInfo
structure contains information on the process. For
instance: After you ran CProcessMem::InitModule("A window Caption")
you can
get the process ID by checking CProcessMem::ProcessInfo.pID
- Although I'm fairly sure this code works well, don't be surprised to find a bug. If you
do, please contact me.
- I hope somebody finds this class useful.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.