2011-08-06 144 views
3

我工作的一个PE加载程序,就像Windows装载机虚拟内存处理

我的目标是可执行不是DLL,我第一次尝试调用LoadLibrary但面临重新分配的问题,得到了一些代码来修复它,但它没“T与所有目标工作(在同一BaseAdress要加载一些exe文件的需求或许工作

,所以我到了一点,我实现我的装载机,确保BaseAddress问题,不需要重新分配

我迫使我的应用程序加载到一个高地址(0x10000000),同时使用VirtualAlloc为标头分配内存&个部分目标应用

我使用VirtualQuery来看看我想分配,如果不是免费的,我使用UnMapViewOfFile如果页面类型MEM_MAPPED地址的状态,否则VirtualFree(MEM_RELEASE)

的问题是,如果内存页MEM_MAPPED & MEM_COMMIT(总页面文件备份页)所有的方法失败,错误代码0×57 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

对不起提出这样一个老问题,我只是认为它可能有助于某人。
据我所知,fork一个进程你必须使用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); 
}