如何在PE文件中获取函数入口点

时间:2012-02-14 14:09:26

标签: c

如果我有exampleA.exe进程,并使用FindEntryPointAddress()函数获取main()进程的exampleB.exe入口点

FindEntryPointAddress()exampleA.exe

的函数
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) // 0x00004550(IMAGE_NT_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()

知道我有一个问题是如何编辑FindEntryPointAddress()以获取func()

exampleB.exe入口点

exampleB.exe

  void func()
  {
    char str[10];

    strcpy( str, "iambuffer\n" );

    printf( "%s", str );
  } // func()

  int main()
  {
    func();

    return 0;
  } // main()

非常感谢

2 个答案:

答案 0 :(得分:0)

除非导出该功能(例如__declspec(dllexport)),否则你运气不好。如果没有导出表中的条目,则无法获得除入口点之外的函数的地址。

此外,即使您在其他地方找到了与该功能相关的一些数据(例如,在调试符号中),您可能仍然无法获取该地址,因为该功能可能在任何地方被内联或被淘汰原因及其相关数据不是。导出的函数不受此影响,因为编译器和链接器足够小心以便始终发出它们。

答案 1 :(得分:0)

如果您正在考虑制作自定义GetProcAddress,请查看here,但是,除非您有pdb或函数符号位于EAT(导出地址表)中,否则您将无法找到它。