我尝试编写简单的调试器。为简单起见,假设调试器在 Windows XP 下运行。
首先,我创建新流程如下:
CreateProcess(processName,
NULL,
NULL,
NULL,
false,
DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS,
NULL,
NULL,
&startInfo,
&openedProcessInfo);
当我尝试在调试过程的内存中读取或写入某些内容时,会出现一些问题。例如:
DWORD oldProtect;
if(!VirtualProtectEx(hProcess, breakpointAddr, 1, PAGE_EXECUTE_READWRITE, &oldProtect)) {
printf("Error: %d\n", GetLastError());
}
SIZE_T bytesRead = 0;
SIZE_T bytesWritten = 0;
BYTE instruction;
BOOL isOk = ReadProcessMemory(hProcess, breakpointAddr, &instruction, 1, &bytesRead);
BYTE originalByte = instruction;
instruction = 0xCC;
if(isOk && bytesRead == 1) {
isOk = WriteProcessMemory(hProcess, breakpointAddr, &instruction, 1, &bytesWritten);
if(isOk) {
isOk = FlushInstructionCache(hProcess, breakpointAddr, 1);
}
}
if(!isOk) {
printf("Error: %d\n", GetLastError());
}
它有效,但并非无处不在。当我要写入(读取)某些内容的地址位于可执行模块(.exe)中时,它可以工作。
但是当我尝试在 DLL 库中写入(读取)某些内容时(例如,在函数 VirtualAlloc 的地址处读取)VirtualProtectEx 返回 false 和 GetLastError = 487(尝试访问无效地址)并且ReadProcessMemory 也返回 false 和 GetLastError = 299(仅部分ReadProcessMemory 或 WriteProcessMemory 请求已完成。)
调试权限已启用,但没有效果。