由于ASLR(地址空间布局随机化,自Windows Vista以来),exe的基地址是随机的,因此无法在PE文件中找到它。
在Visual C ++中,现在默认启用/ DYNAMICBASE选项,因此基地址 一个exe是随机的 - 每次加载器加载它时,都会发生。
在谷歌做了一些研究后,我试图使用这种模式, 但它没有用。
请看一下这个简单的代码示例:
#include <iostream>
#include <vector>
#include <stdio.h>
#include <windows.h>
#include <psapi.h>
int main()
{
STARTUPINFOA startupInfo = {0};
startupInfo.cb = sizeof(startupInfo);
PROCESS_INFORMATION processInformation = {0};
if (CreateProcessA("UseCase01.exe", NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &startupInfo, &processInformation))
{
std::vector<HMODULE> buf(128);
DWORD needed = 0;
for (;;) {
if (EnumProcessModulesEx(processInformation.hProcess, &buf[0], DWORD(buf.size()*sizeof(HMODULE)), &needed, LIST_MODULES_ALL) == FALSE) {
DWORD ec = GetLastError();
std::cout << ec << std::endl;
break;
}
else if (needed <= buf.size() * sizeof(HMODULE)) {
break;
}
else {
const size_t oldSize = buf.size();
buf.resize(oldSize * 2);
}
}
ResumeThread(processInformation.hThread);
}
}
我的操作系统是Windows 7 64位专业版,我的编译器是VS2013,这是一个32位控制台程序,而UseCase01.exe也是一个32位控制台程序。
EnumProcessModulesEx总是失败,GetLastError()返回的错误代码是299,MSDN说明了这个错误代码:ERROR_PARTIAL_COPY,&#34;只完成了ReadProcessMemory或WriteProcessMemory请求的一部分。&#34;
关于此错误代码,在MSDN的EnumProcessModules页面上,&#34;如果从WOW64上运行的32位应用程序调用此函数,它只能枚举32位进程的模块。如果进程是64位进程,则此函数失败,最后一个错误代码为ERROR_PARTIAL_COPY(299)。&#34;
但我确信我的程序是32位,而且,我在64位程序上测试过,它也会因错误299而失败,所以它没有结果。
&#34; CreateProcess函数返回的句柄具有对进程对象的PROCESS_ALL_ACCESS访问权限。&#34; - 来自MSDN,所以它不能成为访问权限问题吗?
然后我尝试使用CreateToolhelp32Snapshot,它失败了,错误代码299,32位和64位。
我无法弄清楚。
我的目标是以安全的方式找到子流程的切入点,无论它是32位还是64位流程。
我发现这是最深的&#34;回答这个问题:http://winprogger.com/getmodulefilenameex-enumprocessmodulesex-failures-in-wow64/
不幸的是,64位程序也会失败,不仅仅适用于Wow64,所以它并没有出现。
如果这是不可行的,那么有什么好办法(找到暂停子流程的基地址或入口点)?
答案 0 :(得分:2)
您正在创建暂停的流程。虽然将创建关键内核数据结构,但不会加载任何模块(这将涉及在模块入口点(dllmain
)中执行代码。)
因此错误是有道理的:跟踪加载模块的数据结构将为空,很可能根本没有分配。
答案 1 :(得分:0)
在所有Windows操作系统(32/64位)上:
DWORD ImageBaseAddress = ((LPDWORD)PEB)[2]
答案 2 :(得分:0)
请稍等,它会帮助您看起来当前资源不可用。