如何找到流程的入口点(或基地址) - 处理ASLR

问题描述 投票:0回答:3

由于ASLR(地址空间布局随机化,自Windows Vista以来),exe的基地址是随机的,因此无法在PE文件中找到它。

在Visual C ++中,现在/ DYNAMICBASE选项是默认启用的,因此exe的基地址是随机的 - 每当加载器加载它时,它就会发生。

在谷歌做了一些研究后,我试图使用这种模式,但它不起作用。

请看一下这个简单的代码示例:

#include <iostream>

#include <vector>
#include <stdio.h>

#include <windows.h>
#include <psapi.h>

int main()
{
    STARTUPINFOA startupInfo = {0};
    startupInfo.cb = sizeof(startupInfo);
    PROCESS_INFORMATION processInformation = {0};

    if (CreateProcessA("UseCase01.exe", NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &startupInfo, &processInformation))
    {
        std::vector<HMODULE> buf(128);
        DWORD needed = 0;
        for (;;) {
            if (EnumProcessModulesEx(processInformation.hProcess, &buf[0], DWORD(buf.size()*sizeof(HMODULE)), &needed, LIST_MODULES_ALL) == FALSE) {
                DWORD ec = GetLastError();
                std::cout << ec << std::endl;
                break;
            }
            else if (needed <= buf.size() * sizeof(HMODULE)) {
                break;
            }
            else {
                const size_t oldSize = buf.size();
                buf.resize(oldSize * 2);
            }
        }
        ResumeThread(processInformation.hThread);
    }
}

我的操作系统是Windows 7 64位专业版,我的编译器是VS2013,这是一个32位控制台程序,而UseCase01.exe也是一个32位控制台程序。

EnumProcessModulesEx总是失败,GetLastError()返回的错误代码是299,MSDN说明了这个错误代码:ERROR_PARTIAL_COPY,“只完成了ReadProcessMemory或WriteProcessMemory请求的一部分。”

关于此错误代码,在MSDN的EnumProcessModules页面上,“如果从WOW64上运行的32位应用程序调用此函数,它只能枚举32位进程的模块。如果进程是64位进程,此函数失败,最后一个错误代码为ERROR_PARTIAL_COPY(299)。“

但我确信我的程序是32位,并且,我在64位程序上测试,它也失败了,错误299,所以它没有出现。

“CreateProcess函数返回的句柄具有对进程对象的PROCESS_ALL_ACCESS访问权限。” - 来自MSDN,所以它不能成为访问权限问题?

然后我尝试使用CreateToolhelp32Snapshot,它失败了,错误代码299,32位和64位。

我只是想不出来。

我的目标是以安全的方式找到子流程的切入点,无论是32位还是64位流程。

我发现这是关于这个问题的“最深刻的”答案:http://winprogger.com/getmodulefilenameex-enumprocessmodulesex-failures-in-wow64/

不幸的是,64位程序也将失败,不仅仅是对于Wow64,所以它没有出现。

如果这是不可行的,那么有什么好办法(找到暂停子流程的基地址或入口点)?

dll-injection
3个回答
2
投票

您正在创建暂停的流程。虽然将创建关键内核数据结构,但不会加载任何模块(这将涉及在模块入口点(dllmain)中执行代码)。

因此错误是有道理的:跟踪加载的模块的数据结构将是空的,并且很可能根本不分配。


0
投票

在所有Windows操作系统(32/64位)上:

DWORD ImageBaseAddress = ((LPDWORD)PEB)[2]

0
投票

放一些等待它会帮助你看起来目前资源不可用。

© www.soinside.com 2019 - 2024. All rights reserved.