Memory 虚拟内存处理

Memory 虚拟内存处理,memory,virtual,kernel,allocation,Memory,Virtual,Kernel,Allocation,我正在使用PE加载程序,就像windows加载程序一样 我的目标是一个可执行文件而不是DLL,我尝试了第一个loadlibrary,但遇到了重新分配问题,得到了一些代码来修复它,但它不能与所有目标一起工作(一些exe可能需要在相同的baseAddress加载才能工作) 所以我要说的是,我必须实现我的加载器以确保基址问题,并且不需要重新分配 我强制我的应用程序以高地址(0x10000000)加载,同时使用VirtualAlloc为目标应用程序的头和节分配内存 我使用VirtualQuery查看我想

我正在使用PE加载程序,就像windows加载程序一样

我的目标是一个可执行文件而不是DLL,我尝试了第一个loadlibrary,但遇到了重新分配问题,得到了一些代码来修复它,但它不能与所有目标一起工作(一些exe可能需要在相同的baseAddress加载才能工作)

所以我要说的是,我必须实现我的加载器以确保基址问题,并且不需要重新分配

我强制我的应用程序以高地址(0x10000000)加载,同时使用VirtualAlloc为目标应用程序的头和节分配内存

我使用VirtualQuery查看我想要分配的地址的状态,如果不是免费的,我使用UnMapViewOfFile如果页面类型MEM\u MAPPED else VirtualFree(MEM\u RELEASE)

问题是,如果内存页是MEM_映射的&MEM_提交(始终是页面文件支持的页),则所有方法都会失败,错误代码为0x57 error_INVALID_参数

寻找解决方案/想法以下是代码:

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 );

很抱歉提出了这么一个老问题,我只是觉得这可能会对某人有所帮助。
据我所知,要分叉一个进程,您必须使用CreateProcess函数。因此,您需要使用VirtualQueryEx和VirtualAllocEx,而不是VirtualQuery和VirtualAlloc。还要用创建的进程的句柄替换hProc值。我还注意到,您显式使用0x20作为dwLength,因此可能需要使用d对其进行更改wSize.

总之:

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 );
}