【发布时间】:2011-10-21 11:27:50
【问题描述】:
我正在开发一个 PE 加载器,就像 windows 加载器一样
我的目标是可执行文件而不是 DLL,我尝试了第一次加载库,但遇到了重新分配问题,得到了一些代码来修复它,但它不适用于所有目标(某些 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 );
【问题讨论】:
标签: memory virtual kernel allocation