【问题标题】:Virtual Memory Handling虚拟内存处理
【发布时间】: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


    【解决方案1】:

    很抱歉提出这么老的问题,我只是认为它可能会对某人有所帮助。
    据我所知,要分叉一个进程,您必须使用 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 );
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-07-18
      • 2012-07-04
      • 1970-01-01
      • 2023-03-15
      相关资源
      最近更新 更多