【问题标题】:How to know the address range when searching for a function by its signature?通过签名搜索函数时如何知道地址范围?
【发布时间】:2012-06-02 00:59:32
【问题描述】:

我正在尝试通过其“签名”来搜索功能。

但是我不知道我应该搜索什么地址范围?

我已经查看了 VirtualQuery() 和 GetNativeSystemInfo(),但我不是在正确的道路上。

编辑:问题重新尝试。

使用 Win32 API,我试图找出如何获取我的代码正在执行的进程的可执行页面的开始和结束地址。

这是我尝试过的:

        SYSTEM_INFO info;
    ZeroMemory( &info, sizeof( SYSTEM_INFO ) );
    GetNativeSystemInfo( &info ); // GetSystemInfo() might be wrong on WOW64.

    info.lpMinimumApplicationAddress;
    info.lpMaximumApplicationAddress;

    HANDLE thisProcess = GetCurrentProcess();

    MEMORY_BASIC_INFORMATION memInfo;
    ZeroMemory( &memInfo, sizeof( memInfo )  );
    DWORD addr = (DWORD)info.lpMinimumApplicationAddress;
    do
    {
        if ( VirtualQueryEx( thisProcess, (LPVOID)addr, &memInfo, sizeof( memInfo ) ) == 0 )
        {
            DWORD gle = GetLastError();
            if ( gle != ERROR_INVALID_PARAMETER )
            {
                std::stringstream str;
                str << "VirtualQueryEx failed with: " << gle;
                MessageBoxA( NULL, str.str().c_str(), "Error", MB_OK );
            }
            break;
        }

        if ( memInfo.Type == MEM_IMAGE  )
        {
            // TODO: Scan this memory block for the the sigature
        }

        addr += info.dwPageSize;
    }
    while ( addr < (DWORD)info.lpMaximumApplicationAddress );

这样做的原因是我正在通过其签名寻找一个未导出的函数,如下所示:

Find a function by it signature in Windows DLL

查看“代码签名扫描”的答案。

虽然这是在枚举地址范围,但我不知道这是否正确,因为我不知道预期的范围应该是什么。它只是我环顾 MSDN 所能想到的最好的。

【问题讨论】:

  • 您的问题表述得不好。可以推断出其中的一部分(即您正在谈论某种 Windows),但您肯定可以做得更好。例如,您所说的签名到底是什么意思?
  • 请更清楚地解释 1) 你到底想要做什么,2) 你在哪个平台上工作,3) 你试图使用什么工具/程序 4) 一个例子什么是“不工作”

标签: c assembly reverse-engineering


【解决方案1】:

签名扫描模块时的地址范围是从代码段开始到开始+段大小。代码段的开头及其大小在 PE 中。大多数工具采用惰性路由并扫描整个模块(再次使用 PE 获取大小,但以模块句柄作为起始地址)。

【讨论】:

  • 我想这就是我想要的,所以我可以使用 Win32 API 以某种方式读取 PE 标头来获取代码段的起始地址和大小?例如,如果二进制文件已使用 UPX 压缩或以某种方式受到保护,会发生什么情况?读取PE头还可靠吗?读取 PE 标头的代码在所述二进制文件中的 DLL 中执行。
  • @paulm:您可以通过ImageNtHeader(使用HMODULE 作为基础)从windows.h 获取PE,然后将IMAGE_SECTION_HEADER 条目插入所需部分,至于打包的二进制文件,这取决于 PE 是否完好无损,或者它是否只有被修改的 EP(您需要在扫描 ofc 之前对要解密的部分进行编码),这取决于打包程序。
  • 令人讨厌的是,我发现我所追求的实际上是“基地址”和“图像大小”。我设法使用以下方法获取该信息: HINSTANCE instance = GetModuleHandle( NULL ); MODULEINFO 模块信息; ZeroMemory( &modInfo, sizeof( modInfo ) ); GetModuleInformation(GetCurrentProcess(), instance, &modInfo, sizeof(modInfo));我会将您的答案标记为已接受,干杯!
  • 这是非常正确的,考虑到现在很多游戏的文件大小,这非常烦人。 .exe 文件很大,其中大部分不是代码。
猜你喜欢
  • 2016-02-04
  • 1970-01-01
  • 2016-07-14
  • 2010-11-05
  • 2012-05-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-20
相关资源
最近更新 更多