有没有可能获得功能的内存入口点?

时间:2012-01-11 02:31:08

标签: c windows portable-executable

我使用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()

3 个答案:

答案 0 :(得分:1)

可能有人问 - 为什么?如果您想运行子进程,CreateProcess()会为您执行此操作。从任意函数运行该过程是没有意义的;由于RTL不会被初始化,因此该过程很可能会崩溃。

如果要为创建者进程调用函数,那就是LoadLibrary()/ GetProcAddress()的用途。 CreateProcess()是完全不同的东西。

如果要根据各个函数进行调试,则可以解析MAP文件和/或调试符号。如果函数恰好是全局函数并导出,则解析PE导出表可能会有所帮助。

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

答案 1 :(得分:0)

我很久以前就做过类似的事情而且不记得确实如此。但是我相信如果有足够的符号信息,你可以从SymFromName获得函数地址。或者如果它已导出,只需通过GetProcAddress直接获取地址。

要修补入口点,您可以通过PE标头在入口点上执行静态修补程序,或者在运行该过程后暂停该过程并通过SetThreadContext更改EIP。

答案 2 :(得分:0)

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

您还可以搜索代码以查找设置帧指针的指令, 然后找到一个可能的切入点。 但你不能完全相信那个地址。