开发者

Virtual Memory Handling

I'm working on a PE Loader, just like windows loader

my target is an executable not DLL,i tried first loadlibrary but faced reallocation problems,got some code to fix it, but it didn't work with all targets (some exe's needs to be loaded at the same BaseAdress to work probably

so i got to the point, i've to implement my loader to ensure the BaseAddress issue and no need for reallocation

I'm forcing my application to load at a high addr(0x10000000),while using VirtualAlloc to allocate memory for headers & sections for the target app

i use VirtualQuery to see the state of the address i want to allocate, if not free i use UnMapViewOfFile if Page type MEM_MAPPED else VirtualFree(MEM_RELEASE)

The problem is that if the memory pages are MEM_MAPPED & MEM_COMMIT (always page file backed pages) all methods fails with error code 0x57 ERROR_INVALID_PARAMETER

looking for solutions/ideas here's the code :

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


Sorry for bringing up such an old question, I just thought it might help someone.
As far as I know, to fork a process you must have used CreateProcess function. Therefore you need to use VirtualQueryEx and VirtualAllocEx instead of VirtualQuery and VirtualAlloc. Also replace hProc value with a handle to your created process. I also noticed that you have explicitly used 0x20 as dwLength that you probably need to change it with dwSize.

In summary:

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜