Обработка виртуальной памяти - PullRequest
3 голосов
/ 06 августа 2011

Я работаю над PE Loader, как и Windows Loader

моя цель - исполняемый файл, а не DLL, я сначала попробовал loadlibrary, но столкнулся с проблемами перераспределения, получил некоторый код, чтобы исправить это, но он не работал со всеми целями (некоторые 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 );

1 Ответ

0 голосов
/ 08 мая 2013

Извините, что поднял такой старый вопрос, я просто подумал, что это может кому-то помочь.
Насколько я знаю, для форка процесса вы должны использовать функцию 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 );
}
...