有没有可能获取函数的内存入口点?

3

我使用CreateProcess()从我的进程中创建了一个子进程,并暂停了该子进程。我可以在子进程的内存中获取主入口点,但是如何获取子进程的函数入口点呢?

以下是我获取子进程主入口点的方法:

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()

如果子进程的内容恰好是这样的,那么foo函数在EXE中将没有入口点 - 编译器会将其内联。 - Seva Alekseyev
3个回答

1

可以问一下 - 为什么?如果你想运行子进程,CreateProcess()会为你做到这一点。从任意函数运行进程毫无意义;因为RTL不会被初始化,进程很可能会崩溃。

如果你想调用创建者进程的函数/从中调用函数,那就是 LoadLibrary()/GetProcAddress() 的作用。而 CreateProcess() 则完全不同。

如果你想以单个函数为单位进行调试,解析MAP文件和/或调试符号是方法。如果该函数恰好是全局导出的,则解析PE导出表可能有所帮助。

此外,在现代编译器中,编译时函数在EXE文件中可能没有一个明确的入口点。内联等等。


我的目的是,如果我没有子进程的源代码而只有一个 .exe 文件,能否获取子进程的函数入口点。 - johnnys0318
一旦你获得了入口点(一个地址),你打算怎么处理它?如果你没有源代码,你怎么知道这个函数的存在? - Seva Alekseyev

0

我很久以前曾经做过类似的事情,但是我不记得具体细节了,所以这可能有些偏差。但是我相信如果有足够的符号信息,你可以从SymFromName获取函数地址。或者如果它被导出,直接通过GetProcAddress获取地址。

要修补入口点,你可以通过PE头对入口点进行静态修补,或者在运行进程时暂停进程并通过SetThreadContext更改EIP。


我的目的是,如果我没有子进程的源代码,是否可以获取子进程函数入口点。 - johnnys0318
你不需要源代码。可执行文件中嵌入了符号表提供有限的信息。如果它甚至没有这些符号信息,那么你将需要通过其他启发式方法确定目标函数的地址。 - Mike Kwan

0

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

您还可以搜索代码以查找设置帧指针的指令,然后找到可能的入口点。 但是您不能完全信任该地址。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接