Есть ли возможность получить функцию входа в память? - PullRequest
3 голосов
/ 11 января 2012

Я создал дочерний процесс из моего процесса с помощью 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 ]

1 голос
/ 11 января 2012

Можно спросить - зачем? Если вы хотите запустить дочерний процесс, CreateProcess() сделает это за вас. Запуск процесса из произвольной функции не имеет смысла; поскольку RTL не будет инициализирован, вполне вероятно, что процесс завершится сбоем.

Если вы хотите вызвать функцию для / из процесса создателя, для этого предназначены LoadLibrary () / GetProcAddress (). CreateProcess() это нечто совершенно другое.

Если вы хотите выполнить отладку с точки зрения отдельных функций, лучше всего проанализировать файл MAP и / или символы отладки. Если функция оказывается глобальной и экспортированной, может помочь анализ таблицы экспорта PE.

Кроме того, в современных компиляторах функция времени компиляции может не иметь одной определенной точки входа в EXE-файл. Подкладка и все такое.

0 голосов
/ 11 января 2012

используйте EXPORTS в файле .DEF вашей дочерней программы процесса, тогда ваша программа может выполнить поиск в таблице IAT, чтобы найти адрес.

Вы также можете выполнить поиск кода, чтобы найти те инструкции, которые устанавливают указатель кадра, затем найдите возможную точку входа.Но вы не можете полностью доверять этому адресу.

0 голосов
/ 11 января 2012

Я работал над чем-то похожим давно и точно не помню, так что это может быть не так.Но я полагаю, что вы можете получить адрес функции из SymFromName , если имеется достаточно информации о символах.Или, если он экспортирован, просто получите адрес напрямую через GetProcAddress .

. Чтобы исправить точку входа, вы можете либо сделать статическое исправление для точки входа через заголовок PE, либо приостановитьобработайте, как только вы запустите его и измените EIP через SetThreadContext .

...