由於ASLR(地址空間佈局隨機化,自Windows Vista以來),exe的基地址是隨機的,所以它不能在PE文件中找到了。如何查找進程的入口點(或基址) - 處理ASLR
在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,「只有ReadProcessMemory或WriteProcessMemory請求的一部分已經完成。」
關於此錯誤代碼,在MSDN的EnumProcessModules頁面上,「如果此函數是從運行在WOW64上的32位應用程序調用的,則它只能枚舉32位進程的模塊,如果進程是64位進程,此功能失敗,最後一個錯誤代碼爲ERROR_PARTIAL_COPY(299)。「
但是我確定我的程序是32位的,而且,我在64位程序上測試過,它也會因爲錯誤299而失敗,所以它不會讓你感興趣。
「CreateProcess函數返回的句柄具有PROCESS_ALL_ACCESS訪問過程對象的權限。」 - 來自MSDN,所以它不能成爲訪問權限問題?
然後我嘗試使用CreateToolhelp32Snapshot,它也失敗,錯誤代碼299也是32位和64位。我只是想不出來。
我的目標是以安全的方式找到子進程的入口點,無論它是32位還是64位進程。
,我發現這是關於這個問題的「最深處」的答案:http://winprogger.com/getmodulefilenameex-enumprocessmodulesex-failures-in-wow64/
不幸的是,64位程序將也會失敗,不僅對WOW64的,所以它不會使SENCE。
如果這是不可行的,什麼是好方法(找到暫停子進程的基地址或入口點)?
「子流程的入口點」 你的意思是'main'(或'WinMain')的可執行文件?爲什麼不使用'dumpbin'或API讀取PE可執行文件?總結:這聽起來像是[XY問題](http://www.google.co.uk/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&uact=8&ved=0CCMQFjAA&url=http%3A%2F %2Fmeta.stackexchange.com%2Fquestions%2F66377%2Fwhat-is-the-xy-problem&ei = lcCBVKX_E4r5ULu6geAP&usg = AFQjCNG6PdyCWEgR_NXZkL96ZR4G9aJ-wA&sig2 = B5Bex9sUiMUvmpTYVyV_hw&bvm = bv.80642063,d.d24):您爲什麼想要入口點? – Richard 2014-12-05 14:26:56
@Richard入口點通常是mainCRTStatup(http://msdn.microsoft.com/en-us/library/f9t8842e.aspx),它在main之前。我想要切入點,因爲下一步是修補它,準備進行DLL注入,DLL注入是另一回事。 – amanjiang 2014-12-05 14:45:40
爲什麼你需要修補入口點以「準備DLL注入」?你準備準備什麼? DLL注入通常不需要事先準備。 – 2014-12-05 16:41:37