2014-12-05 20 views
0

由於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。

如果這是不可行的,什麼是好方法(找到暫停子進程的基地址或入口點)?

+0

「子流程的入口點」 你的意思是'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

+0

@Richard入口點通常是mainCRTStatup(http://msdn.microsoft.com/en-us/library/f9t8842e.aspx),它在main之前。我想要切入點,因爲下一步是修補它,準備進行DLL注入,DLL注入是另一回事。 – amanjiang 2014-12-05 14:45:40

+0

爲什麼你需要修補入口點以「準備DLL注入」?你準備準備什麼? DLL注入通常不需要事先準備。 – 2014-12-05 16:41:37

回答

2

您正在創建暫停的進程。雖然將創建關鍵內核數據結構,但不會加載模塊(這將涉及在模塊入口點(dllmain)中執行代碼)。

因此,這個錯誤是有道理的:跟蹤加載的模塊的數據結構將是空的,很可能根本就沒有分配。

+0

我刪除了CREATE_SUSPENDED標誌和在CreateProcess之後,我插入一個Sleep(100),子進程運行,並且再次出現錯誤299。順便說一句CreateToolhelp32Snapshot也失敗了299。 – amanjiang 2014-12-05 14:33:32

+0

嘗試使用'WaitForInputIdle()'而不是'Sleep()'。 – 2014-12-05 16:38:47

+0

@RemyLebeau其實我需要它被暫停。 – amanjiang 2014-12-05 17:14:55

0

在所有的Windows操作系統(32位/ 64位):

DWORD ImageBaseAddress = ((LPDWORD)PEB)[2] 
相關問題