2012-01-11 20 views
3

我在的進程中創建了一個子進程,並暫停子進程。我可以在子進程的內存中獲取主入口點,但我應該如何獲取子進程的函數入口點?有沒有可能獲得函數的內存入口點?

這是我如何得到子進程

DWORD FindEntryPointAddress(TCHAR *exeFile) 
{ 
    BY_HANDLE_FILE_INFORMATION bhfi; 
    HANDLE hMapping; 
    char *lpBase; 

    HANDLE hFile = CreateFile(exeFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); 

    if (hFile == INVALID_HANDLE_VALUE) 
    ; 

    if (!GetFileInformationByHandle(hFile, &bhfi)) 
    ; 

    hMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, bhfi.nFileSizeHigh, bhfi.nFileSizeLow, NULL); 

    if (!hMapping) 
    ; 

    lpBase = (char *)MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, bhfi.nFileSizeLow); 

    if (!lpBase) 
    ; 

    PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)lpBase; 

    if (dosHeader->e_magic != IMAGE_DOS_SIGNATURE) 
    ; 

    PIMAGE_NT_HEADERS32 ntHeader = (PIMAGE_NT_HEADERS32)(lpBase + dosHeader->e_lfanew); 

    if (ntHeader->Signature != IMAGE_NT_SIGNATURE) 
    ; 

    DWORD pEntryPoint = ntHeader->OptionalHeader.ImageBase + ntHeader->OptionalHeader.AddressOfEntryPoint; 

    UnmapViewOfFile((LPCVOID)lpBase); 

    CloseHandle(hMapping); 

    CloseHandle(hFile); 

    printf("test.exe entry point: %p\n", pEntryPoint); 

    return pEntryPoint; 
} // FindEntryPointAddress() 

的主入口點,我應該怎麼弄子進程的功能foo()切入點?

這樣

void foo() 
{ 
    char str[10]; 
    strcpy(str, "buffer\n"); 
} // foo() 

int main() 
{ 
    foo(); 
    return 0; 
} // main() 
+0

如果這*完全是*內容子進程,則foo函數在EXE中將沒有入口點 - 編譯器會將其內聯。 – 2012-01-11 16:08:51

回答

1

子進程可以問問 - 什麼?如果你想運行子進程,CreateProcess()爲你做。從任意函數運行該進程使其毫無意義;由於RTL不會被初始化,所以這個過程很可能會崩潰。

如果您想爲創作者進程調用函數,那麼這就是LoadLibrary()/ GetProcAddress()的作用。 CreateProcess()是完全不同的東西。

如果您想根據各個功能進行調試,則解析MAP文件和/或調試符號是一種方法。如果函數碰巧是全局的並且導出,則解析PE導出表可能會有所幫助。

此外,在現代編譯器中,編譯時函數在EXE文件中可能沒有明確的入口點。內聯等等。

+0

我的目的是,如果我沒有子進程源代碼,我只是得到一個.exe文件,我可以得到子進程的函數入口點。 – johnnys0318 2012-01-11 03:13:50

+0

一旦你獲得了這個入口點(一個地址),你將如何處理它?如果你沒有資料來源,你怎麼知道這個函數的存在? – 2012-01-11 14:30:07

0

我很久以前就曾在類似的事情上工作過,不記得確切的事情,所以這可能是關閉的。但是如果有足夠的符號信息,我相信你可以從SymFromName得到函數地址。或者,如果已導出,只需通過GetProcAddress直接獲取地址即可。

要修補入口點,您可以通過PE頭在入口點上執行靜態修補程序,或者在運行該進程後暫停該進程並通過SetThreadContext更改EIP。

+0

我的目的是,如果我沒有子進程源代碼,我可以得到子進程的函數入口點。 – johnnys0318 2012-01-11 02:47:39

+0

所以我沒有足夠的信息,我只是得到一個.exe文件 – johnnys0318 2012-01-11 02:50:20

+0

你不需要源代碼。嵌入在可執行文件中的符號表提供了有限的信息量。如果它甚至沒有那個符號信息,那麼你將不得不通過其他啓發式來確定目標函數的地址。 – 2012-01-11 03:42:45

0

在您的子進程程序的.DEF文件中使用EXPORTS, 然後您的程序可以搜索IAT表以查找地址。

您也可以搜索代碼來查找設置幀指針的指令,然後找到可能的入口點。 但是你不能完全相信那個地址。

相關問題