編輯:EnumProcessModulesEx和CreateToolHelp32Snapshot函數失敗 - 無論32位或64位
這個問題的答案就在這裏:
https://stackoverflow.com/a/27317947/996540
當你在MSVC裏創建一個項目,選項/ DYNAMICBASE是默認啓用 現在。由於ASLR(地址空間佈局隨機化,自Windows Vista以來), 每次運行一個exe時,它的加載地址都是隨機的。
我最近在做DLL注入工作,所以我在google上做了一些關於 的研究,並且讀過一些項目。獲取 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
「如果這個函數是從3稱爲在WOW64上運行的2位應用程序,它可以 只枚舉32位進程的模塊。如果這個過程是一個64位 過程中,此函數失敗,最後錯誤代碼是ERROR_PARTIAL_COPY (299)「 - 從MSDN
這是一個博客帖子這個問題: http://winprogger.com/getmodulefilenameex-enumprocessmodulesex-failures-in-wow64/
。不幸的是,這並沒有讓SENCE,因爲無論指定 過程爲32位或64位時,出現299;無論主叫過程 32位或64位時,出現299
這是輸出我的樣品:
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。
那麼,我該怎麼辦?
「如果在目標進程模塊列表中被損壞或尚未初始化... EnumProcessModulesEx可能失敗或返回不正確的信息」 - 也許是因爲過程中已創建在暫停狀態下,它一直沒有運行,所以它的模塊列表是「尚未初始化」? – 2014-12-06 11:19:18
@JonathanPotter所以我已刪除CREATE_SUSPENDED,讓運行的過程,但它仍然失敗,299 – amanjiang 2014-12-06 11:21:19
@JonathanPotter你是對的。今天,我再次測試程序,沒有CREATE_SUSPENDED標誌,保持運行一段子過程,它的工作原理。 – amanjiang 2014-12-08 03:54:15