使用 VirtualAllocEx 如何为代码洞穴腾出空间?

Posted

技术标签:

【中文标题】使用 VirtualAllocEx 如何为代码洞穴腾出空间?【英文标题】:How does one use VirtualAllocEx do make room for a code cave? 【发布时间】:2011-03-01 22:39:47 【问题描述】:

如何使用 VirtualAllocEx 为code cave 腾出空间?我目前拥有一个“可用空间”很少的软件,我读到 VirtualAllocEx 用于创建这个空间..

【问题讨论】:

请澄清您的问题。当您说该软件的“可用空间”非常少时,您是什么意思-它是否在RAM有限的设备上运行,可执行文件本身很小,还是什么?什么是“代码洞穴”? @JSBangs:代码洞穴是一块未使用的内存块,您可以使用它来注入自定义编程代码以修改程序的行为。这是一个晦涩的术语,直到今天我自己才听说过。 到目前为止你有什么?您只需要VirtualAllocEx 方面的帮助,还是需要先决条件代码方面的帮助? 我认为“代码洞穴”对于执行相当于“猴子补丁”的 C 或 ASM 很有用。 我只需要帮助为 exe 文件中的 codecave 腾出空间 :-) 【参考方案1】:

解决“代码洞穴”的问题后,您可以找到以下有趣的代码,这些代码枚举了当前进程中VirtualAllocEx分配的块,并找到所有PE(DLL和EXE本身)。

SYSTEM_INFO si;
MEMORY_BASIC_INFORMATION mbi;

DWORD nOffset = 0, cbReturned, dwMem;
GetSystemInfo(&si);

for (dwMem = 0; dwMem<(DWORD)si.lpMaximumApplicationAddress;
                dwMem+=mbi.RegionSize) 
    cbReturned = VirtualQueryEx (GetCurrentProcess(),  (LPCVOID)dwMem, &mbi,
                                 sizeof(mbi));
    if (cbReturned) 
        if ((mbi.AllocationProtect & PAGE_EXECUTE_WRITECOPY) &&
            (mbi.Protect & (PAGE_EXECUTE | PAGE_EXECUTE_READ | 
                            PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY))) 

            if (*(LPWORD)mbi.AllocationBase == IMAGE_DOS_SIGNATURE) 
                IMAGE_DOS_HEADER *pDosHeader =
                    (IMAGE_DOS_HEADER *)mbi.AllocationBase;

                if (pDosHeader->e_lfanew) 
                    IMAGE_NT_HEADERS32 *pNtHeader = (IMAGE_NT_HEADERS32 *)
                        ((PBYTE)pDosHeader + pDosHeader->e_lfanew);

                    if (pNtHeader->Signature != IMAGE_NT_SIGNATURE)
                        continue;

                    // now you can examine of module loaded in current process
                
            
        
    

代码可能看起来像一个大循环。实际上,它是一个典型的应用程序,它进行了大约 200 个循环,因此在加载 EXE 所有依赖的 DLL 期间,可以非常快速地遍历分配给 VirtualAllocEx 的所有块。

【讨论】:

这不能回答问题。 另外,还有调试器。 @Abyx:我不确定你的意思。问题主要是调试器如何工作以及如何访问他自己或另一个进程的内存。第一个问题是分析虚拟空间并了解谁是内存的所有者。首先应该在它自己的过程中完成它。只需拥有足够的权限或激活SE_DEBUG_NAME 权限即可与另一个进程进行关闭操作。最重要的找到IMAGE_DOS_HEADER(模块开头),其他的都知道了。 问题是“我该怎么做X”。你的回答是“在你解决了 X 之后,你也可以做 Y”。这不是答案。 @Abyx:我理解你的意见。通常,提出问题的人会写 cmets,他想要其他东西或其他人写下他自己的答案。问这个问题的 Jake 没有写任何 cmets 并接受了这个问题。这是我的第一个答案,我的声誉很低,用英语表达得不够好。【参考方案2】:
#include <stdio.h>
#include <windows.h>
#include <commctrl.h>   

unsigned long pid;
HANDLE process;
GetWindowThreadProcessId(listview, &pid);
process = OpenProcess(PROCESS_VM_OPERATION|PROCESS_VM_READ | PROCESS_VM_WRITE|PROCESS_QUERY_INFORMATION, FALSE, pid);

int *vptr = (int *)VirtualAllocEx(process, NULL, sizeof(int), MEM_COMMIT, PAGE_READWRITE);

参考文献 - MSDN VirtualAllocEx Function - 代码项目Stealing Program's Memory - StackOver What is a code cave... ?

HTH,

【讨论】:

顺便说一句,谢谢你,直到看到这个问题,我才知道“代码洞穴”是什么。我从快速谷歌上学到了以上内容,并在工作中询问了我旁边的一个 h@cker 朋友。

以上是关于使用 VirtualAllocEx 如何为代码洞穴腾出空间?的主要内容,如果未能解决你的问题,请参考以下文章

如何为使用 vs 代码打开的 jupyter notebook 选择特定内核

如何为 C++ 代码使用 cppcheck 的内联抑制过滤器选项?

QForkMasterInit: system error caught. error code=0x000005af, message=VirtualAllocEx failed.(遇到还没试过)(

如何为在 C 中使用 C++ 代码创建包装器?

如何为 Android 构建和简化 Java 代码

内嵌补丁(洞穴代码)