编辑:
这个问题的答案在这里:
https://stackoverflow.com/a/27317947/996540
在msvc中创建项目时,默认启用选项/ DYNAMICBASE 现在。由于ASLR(地址空间布局随机化,自Windows Vista以来), 每次运行exe时,它的加载地址都是随机的。
我最近在做DLL注入工作,所以我做了一些研究 谷歌,并阅读了一些项目。获取的加载地址(基址) exe很重要。
似乎有两个简单的API可以做到这一点:EnumProcessModulesEx和 CreateToolHelp32Snapshot函数。但我从未成功过。
所以这是代码示例:
void TestEnumProcessModulesEx(const char* app)
{
std::cout << "Begin TestEnumProcessModulesEx(" << mybit() << ")" << std::endl;
STARTUPINFOA startupInfo = {0};
startupInfo.cb = sizeof(startupInfo);
PROCESS_INFORMATION processInformation = {0};
if (CreateProcessA(app, 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 << "GetLastError() = " << 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);
WaitForSingleObject(processInformation.hProcess, INFINITE);
}
std::cout << "End TestEnumProcessModulesEx(" << mybit() << ")" << std::endl;
}
为了减少这个问题的长度,完整的代码 - 包括 CreateToolhelp32Snapshot的测试代码 - 此处未列出,但您可以获得它 从:
https://dl.dropboxusercontent.com/u/235920/enum_proc_mods_sample.7z 要么 https://www.mediafire.com/?cry3pnra8392099
“如果从WOW64上运行的32位应用程序调用此函数,它可以 仅枚举32位进程的模块。如果进程是64位 进程,此函数失败,最后一个错误代码是ERROR_PARTIAL_COPY (299)。“ - 来自MSDN。
这是一篇关于这个问题的博文: http://winprogger.com/getmodulefilenameex-enumprocessmodulesex-failures-in-wow64/
不幸的是,这并没有出现,因为无论指定什么 进程是32位或64位,它失败了299;无论调用者进程是什么 32位或64位,2912失败。
这是我的样本的输出:
Begin TestEnumProcessModulesEx(32bit)
GetLastError() = 299
hello world 32bit
End TestEnumProcessModulesEx(32bit)
Begin TestEnumProcessModulesEx(32bit)
GetLastError() = 299
hello world 64bit
End TestEnumProcessModulesEx(32bit)
Begin TestEnumProcessModulesEx(64bit)
GetLastError() = 299
hello world 32bit
End TestEnumProcessModulesEx(64bit)
Begin TestEnumProcessModulesEx(64bit)
GetLastError() = 299
hello world 64bit
End TestEnumProcessModulesEx(64bit)
如您所见,任何组合都失败了。
我的操作系统是Windows 7 64位专业版,我的编译器是VS2013。
那么,我该怎么办?
答案 0 :(得分:0)
我不知道EnumProcessModulesEx和 CreateToolhelp32Snapshot,请将此问题留给专家。
我的目标是获取子进程的加载地址(基址),查找 入口点并修补它 - 修补入口点的原因在于: https://opcode0x90.wordpress.com/2011/01/15/injecting-dll-into-process-on-load/
由于DLL注入是我的主要目的,我不得不重新考虑这一点 题。我会使用&#34; CreateRemoteThread&amp; LoadLibrary技术&#34; http://www.codeproject.com/Articles/4610/Three-Ways-to-Inject-Your-Code-into-Another-Proces#section_2 做DLL注入(实际上ASLR不是这种技术的障碍), 虽然DLLMain有很多限制 http://msdn.microsoft.com/en-us/library/windows/desktop/dn633971%28v=vs.85%29.aspx ,但做一点工作是可以的:找到一个exe的基地址使用 GetModuleHandleA(NULL),保存返回共享内存的HMODULE, 接下来,调用者进程读取共享内存并获取HMODULE。 当然,同步机制是必要的。
所以,答案是IPC。 (顺便说一下,并非每个IPC机制在DLLMain中都是安全的)