虚拟内存处理

发布于 2024-11-28 06:05:59 字数 1998 浏览 0 评论 0原文

我正在开发一个PE加载器,就像Windows加载器一样

,我的目标是一个可执行文件而不是DLL,我首先尝试了loadlibrary,但遇到了重新分配问题,得到了一些代码来修复它,但它不适用于所有目标(某些exe的需要可能要在同一个 BaseAdress 处加载才能工作

,所以我说到了重点,我必须实现我的加载程序以确保 BaseAddress 问题并且不需要重新分配

我强制我的应用程序以较高的速度加载addr(0x10000000),在使用 VirtualAlloc 为目标应用程序的标头和部分分配内存时,

我使用 VirtualQuery 来查看要分配的地址的状态,如果没有空闲,则如果页面类型为 MEM_MAPPED,则使用 UnMapViewOfFile,否则 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 );

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

对岸观火 2024-12-05 06:05:59

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

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 );
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文