有没有可能获得函数的内存入口点?
我使用 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()
I created a child process from within my process with CreateProcess()
and suspend the child process. I can get the main entry point in the memory of child process, but how should I get function entry point of child process?
This is how I get the main entry point of child process
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()
And how should I get the function foo()
entry point of child process?
child process like this
void foo()
{
char str[10];
strcpy( str, "buffer\n" );
} // foo()
int main()
{
foo();
return 0;
} // main()
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
有人会问——为了什么?如果您想运行子进程,
CreateProcess()
会为您执行此操作。从任意函数运行该进程毫无意义;由于 RTL 不会被初始化,因此该进程很可能崩溃。如果您想为创建者进程调用函数或从创建者进程调用函数,则可以使用 LoadLibrary()/GetProcAddress()。
CreateProcess()
是完全不同的东西。如果您想根据单个函数进行调试,则可以解析 MAP 文件和/或调试符号。如果该函数恰好是全局且导出的,则解析 PE 导出表可能会有所帮助。
另外,在现代编译器中,编译时函数在 EXE 文件中可能没有明确的入口点。内联等等。
May one ask - what for? If you want to run the child process,
CreateProcess()
does that for you. Running the process from an arbitrary function makes zero sense; since the RTL won't be initialized, the process is quite likely to crash.If you want to call a function for/from the creator process, that's what LoadLibrary()/GetProcAddress() are for.
CreateProcess()
is something completely different.If you want to debug in terms of individual functions, parsing the MAP file and/or the debug symbols is the way. If the function happens to be global and exported, parsing the PE export table might help.
Also, in modern compilers, the compile-time function may not have one definite entry point in the EXE file. Inlining and all that.
我很久以前就做过类似的事情,但记不太清了,所以这可能会失败。但我相信你可以从 SymFromName 如果有足够的符号信息。或者,如果是导出的,只需通过 GetProcAddress。
要修补入口点,您可以通过 PE 标头对入口点进行静态修补,或者在运行进程后暂停该进程并通过 SetThreadContext。
I worked on something similar a long time ago and don't remember exactly so this might be off. But I believe you can get the function address from SymFromName if there is enough symbol information. Or if it's exported, just get the address directly via GetProcAddress.
To patch the entry point, you can either do a static patch on the entry point through the PE header, or suspend the process once you run it and change EIP through SetThreadContext.
在子进程程序的 .DEF 文件中使用 EXPORTS,
那么你的程序就可以搜索IAT表来找到地址。
您还可以搜索代码以查找设置帧指针的指令,
然后找到一个可能的切入点。
但您不能完全信任该地址。
use EXPORTS in the .DEF file of your child process program,
then your program can search the IAT table to find the address.
You can also search the code to find those instructions that sets the frame pointer ,
then find a possible entry point .
But you can not totally trust that address.