我正在研究PE Loader,就像windows loader
一样我的目标是一个可执行文件而不是DLL,我尝试了第一个loadlibrary但遇到了重新分配问题,得到了一些代码来修复它,但是它不适用于所有目标(某些exe需要在同一个BaseAdress上加载才能工作)
所以我明白了,我要实现我的加载器以确保BaseAddress问题而不需要重新分配
我正在强制我的应用程序加载到高地址(0x10000000),同时使用VirtualAlloc为标题分配内存和目标应用的部分
我使用VirtualQuery来查看我想要分配的地址的状态,如果不是免费的话我使用UnMapViewOfFile如果页面类型为MEM_MAPPED,则为VirtualFree(MEM_RELEASE)
问题是如果内存页面是MEM_MAPPED& MEM_COMMIT(始终是页面文件支持的页面)所有方法都失败,错误代码为0x57 ERROR_INVALID_PARAMETER
在这里寻找解决方案/想法是代码:
MylpAddr = (DWORD)lpAddr ;
MemInfo.RegionSize = 0 ;
NtUnmapViewOfSection= (NTUNMAPVIEWOFSECTION)GetProcAddress(LoadLibrary(TEXT("ntdll.dll")), "NtUnmapViewOfSection");
NtProtectVirtualMemory= (NTPROTECTVIRTUALMEMORY)GetProcAddress(LoadLibrary(TEXT("ntdll.dll")), "NtProtectVirtualMemory");
NtUnlockVirtualMemory= (NTUNLOCKVIRTUALMEMORY)GetProcAddress(LoadLibrary(TEXT("ntdll.dll")), "NtUnlockVirtualMemory");
GetSystemInfo(&siSysInfo);
szPage = siSysInfo.dwPageSize ;
i = VirtualQuery( (LPCVOID)MylpAddr , &MemInfo , 0x20 ) ;
if (!i) return NULL ;
if ( !(MemInfo.State & MEM_FREE) )
{
if ( MemInfo.Type & MEM_MAPPED )
{
hProc = GetCurrentProcess() ;
szPage = MemInfo.RegionSize ;
i = NtUnlockVirtualMemory(hProc , (PVOID *)MemInfo.AllocationBase , (PULONG)szPage , LOCK_VM_IN_WORKING_SET | LOCK_VM_IN_RAM );
i = NtProtectVirtualMemory(hProc , (PVOID *)MemInfo.AllocationBase , (PULONG)szPage , PAGE_READWRITE , &OldProt ) ;
i = NtUnmapViewOfSection( hProc , (LPVOID)MemInfo.AllocationBase );
i = UnmapViewOfFile( (LPVOID)MemInfo.AllocationBase );
if (!i) i =1 ;
}
else
{
j = VirtualUnlock(MemInfo.BaseAddress , MemInfo.RegionSize);
i = VirtualFree( (LPVOID)MemInfo.AllocationBase , NULL , MEM_RELEASE ) ;
}
if (!i) return NULL ;
}
MylpAddr = (DWORD)VirtualAlloc( lpAddr , dwSize , AllocType , ProtFlags );
答案 0 :(得分:0)
很抱歉提出这么老的问题,我只是觉得这对某人有帮助。
据我所知,要分叉一个进程,你必须使用CreateProcess函数。因此,您需要使用VirtualQueryEx和VirtualAllocEx而不是VirtualQuery和VirtualAlloc。还可以使用创建过程的句柄替换hProc值。我还注意到你已明确使用0x20作为dwLength,你可能需要用dwSize来改变它。
总结:
PROCESS_INFORMATION piProcessInformation;
ZeroMemory(&piProcessInformation,sizeof(PROCESS_INFORMATION));
if(CreateProcess(NULL,processName,NULL,NULL,false,CREATE_SUSPENDED,NULL,NULL,&suStartUpInformation,&piProcessInformation))
{
cContext.ContextFlags = CONTEXT_FULL;
GetThreadContext(piProcessInformation.hThread,&cContext);
i = VirtualQueryEx(piProcessInformation.hProcess, (LPCVOID)MylpAddr , &MemInfo , dwSize ) ;
if (!i) return NULL ;
if ( !(MemInfo.State & MEM_FREE) )
{
if ( MemInfo.Type & MEM_MAPPED )
{
// hProc = GetCurrentProcess() ; No need to this line
szPage = MemInfo.RegionSize ;
i = NtUnlockVirtualMemory(piProcessInformation.hProcess , (PVOID *)MemInfo.AllocationBase , (PULONG)szPage , LOCK_VM_IN_WORKING_SET | LOCK_VM_IN_RAM );
i = NtProtectVirtualMemory(piProcessInformation.hProcess , (PVOID *)MemInfo.AllocationBase , (PULONG)szPage , PAGE_READWRITE , &OldProt ) ;
i = NtUnmapViewOfSection( piProcessInformation.hProcess , (LPVOID)MemInfo.AllocationBase );
i = UnmapViewOfFile( (LPVOID)MemInfo.AllocationBase );
if (!i) i =1 ;
}
else
{
j = VirtualUnlock(MemInfo.BaseAddress , MemInfo.RegionSize);
i = VirtualFreeEx(piProcessInformation.hProcess, (LPVOID)MemInfo.AllocationBase , NULL , MEM_RELEASE ) ;
}
if (!i) return NULL ;
}
MylpAddr = (DWORD)VirtualAllocEx(piProcessInformation.hProcess, lpAddr , dwSize , AllocType , ProtFlags );
}