返回介绍

26.3 Appcall

发布于 2024-10-11 21:05:51 字数 2527 浏览 0 评论 0 收藏 0

调试器的 Appcall 特性有效地扩展了 IDC 或 IDAPython 通过脚本调用活动进程中的任何函数的功能。上述功能的用途非常广泛,包括将额外的内存映射到进程地址空间中(通过调用 VirtualAlloc 或类似函数),以及将新库注入到所调试的进程中(通过调用 LoadLibrary ,或通过调用进程中的函数来执行你宁愿手动执行的任务,如解码数据块或计算散列值)。

要使用 Appcall,必须将你要调用的函数加载到所调试进程的地址空间中,并且 IDA 必须了解或获知该函数的原型,以便正确编列或解列参数。保存当前调试器线程的状态(与该线程有关的所有注册)后,你所作的任何 Appcall 调用将置于该线程中。Appcall 完成后,IDA 将恢复线程状态,调试器也将恢复执行,好像 Appcall 从未发生一样。

下面我们来看一个示例,该示例使用 Appcall 将一个 4096 字节的内存块分配到当前(Windows)进程地址空间中。在本例中,我们希望调用的 Windows API 函数名为 VirtualAlloc ,其原型如下所示:

LPVOID WINAPI VirtualAlloc(LPVOID lpAddress, SIZE_T dwSize,  
                           DWORD flAllocationType, DWORD flProtect);

如果以 C 语言编写代码,使用 Appcall 调用 VirtualAlloc 函数的代码如下所示:

VirtualAlloc(NULL, 4096, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);

解析所有常量后,此函数调用最终变为:

VirtualAlloc(0, 4096, 0x3000, 4);

如前所述,在调试 Windows 进程时,IDA 会将函数所属的库的名称作为每个库函数的名称的前缀。因此,激活调试器后, VirtualAlloc 将被命名为 kernel32_VirtualAlloc ,如下面的代码所示:

kernel32.dll:766B2FB6 ; ====== S U B R O U T I N E ========  
kernel32.dll:766B2FB6  
kernel32.dll:766B2FB6 ; Attributes: bp-based frame  
kernel32.dll:766B2FB6  
kernel32.dll:766B2FB6 kernel32_VirtualAlloc proc near

由于 IDA 的类型库对名为 kernel32_VirtualAlloc 的函数一无所知,所以不会显示任何类型信息。由于 Appcall 需要了解函数的类型签名,因此我们需要使用 Set Function Type 命令将相关信息添加到数据库中。只要我们指定的签名允许 IDA 将参数正确传送给所调用的函数,就不需要具体的类型签名了。在本例中,我们提供了以下签名:

kernel32.dll:766B2FB6 ; Attributes: bp-based frame  
kernel32.dll:766B2FB6  
kernel32.dll:766B2FB6 ; int __stdcall kernel32_VirtualAlloc(int, int, int, int)  
kernel32.dll:766B2FB6 kernel32_VirtualAlloc proc near

现在,我们已经作好准备,可以使用 Appcall 为我们的进程分配更多内存。使用 IDC 可以轻松完成这个任务,因为我们只需要调用 VirtualAlloc ,就像调用 IDC 函数一样。在 IDA 命令行中输入函数调用,并使用 Message 函数显示结果,将生成以下输出:

IDC>Message("%x\n", kernel32_VirtualAlloc(0, 4096, 0x3000, 4));  
3c0000

结果,一个 4096 字节的新内存块分配给了地址 0x3c0000 处的进程。要在 IDA 中显示这个新内存块,我们必须使用 Debugger ▶Refresh 内存命令,或等候 IDA 执行刷新及其他调试器操作。

在 Python 中执行 Appcall 的语法会略有不同,需要用到在 idaapi 模块中定义的 Appcall 变量。但是,你仍然需要提供命名函数与类型签名。以 Python 编写的、使用 Appcall 调用 VirtualAlloc 函数的代码如下所示:

Python>Message("%x\n" % Appcall.kernel32_VirtualAlloc(0, 4096, 0x3000, 4))  
3d0000

有关 Appcall 及其用法的其他信息与示例,请参阅 Hex-Rays 博客1

1. 参见 http://www.hexblog.com/?p=113

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

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

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文