有什么方法可以获取与 IDC 一起使用的函数参数列表?

逆向工程 艾达 idapro插件
2021-06-14 21:50:21

我使用的是 IDA Pro 6.5,我得到了一个函数及其参数的偏移量。它看起来像这样:

.text:0000C0DE        int __cdecl func(char* a1, int a2, int a3, int a4, int a5, int a6, char* a7)

但是,它有大量的外部参照(超过 200 个!)

是否有倾销的任何方式a1a7每次调用的参数列表?
我无法在运行时挂钩和转储参数。

我知道我可以使用 IDC 遍历外部参照列表,但是一旦我按照call func指令,我不知道如何从堆栈中获取参数。

3个回答

如果您有六角射线反编译器,我建议你反编译整个二进制,然后用grep “荷兰国际集团对所产生的反编译func(

这应该会为您提供比您可以开发的任何 IDC 脚本更有用的结果。

手动方法:您可以在每次调用后编写相关参数值(和其他相关信息)作为注释。这样信息就会显示在交叉引用列表中。

这也可以编写脚本,但这涉及在每次调用之前执行指令并以有限的方式模拟指令。到达调用指令后,您可以访问模拟的迷你堆栈和模拟寄存器以查看它们是否具有常量(已知)值,并相应地生成上述注释。

问题是这些参数可能并且在大多数情况下会被计算,而不是常量,因此您实际上并没有一条指令可以为您提供参数。考虑这个测试程序:

#include <stdio.h>

int a, b, c, d, e, f, g, h, i, j;

void func(int a1, int a2, int a3, int a4, int a5) {
        printf("%d %d %d %d %d\n", a1, a2, a3, a4, a5);
}

int main(void) {
        int x, y;

        x=g+c;
        y=d*e+i;

        func(1, a, b+c, 7, j);
        printf("blarfl\n");
        func(e, j*c, 3, x, y);
}

编译后(带 -O0 和不带符号)并将其加载到 IDA 中,主要功能如下所示:

push    rbp
mov     rbp, rsp
sub     rsp, 10h
mov     edx, cs:g
mov     eax, cs:c
add     eax, edx
mov     [rbp+var_8], eax
mov     edx, cs:d
mov     eax, cs:e
imul    edx, eax
mov     eax, cs:i
add     eax, edx
mov     [rbp+var_4], eax
mov     ecx, cs:j
mov     edx, cs:b
mov     eax, cs:c
add     edx, eax
mov     eax, cs:a
mov     r8d, ecx
mov     ecx, 7
mov     esi, eax
mov     edi, 1
call    func
mov     edi, offset s   ; "blarfl"
call    _puts
mov     edx, cs:j
mov     eax, cs:c
mov     esi, edx
imul    esi, eax
mov     eax, cs:e
mov     ecx, [rbp+var_4]
mov     edx, [rbp+var_8]
mov     r8d, ecx
mov     ecx, edx
mov     edx, 3
mov     edi, eax
call    func
leave

一旦你定义了你的函数

; __int64 __cdecl func(int XYZ1, int XYZ2, int XYZ3, int XYZ4, int XYZ5)

分解main变成

push    rbp
mov     rbp, rsp
sub     rsp, 10h
mov     edx, cs:g
mov     eax, cs:c
add     eax, edx
mov     [rbp+XYZ4], eax
mov     edx, cs:d
mov     eax, cs:e
imul    edx, eax
mov     eax, cs:i
add     eax, edx
mov     [rbp+XYZ5], eax
mov     ecx, cs:j
mov     edx, cs:b
mov     eax, cs:c
add     edx, eax        ; XYZ3
mov     eax, cs:a
mov     r8d, ecx        ; XYZ5
mov     ecx, 7          ; XYZ4
mov     esi, eax        ; XYZ2
mov     edi, 1          ; XYZ1
call    func
mov     edi, offset s   ; "blarfl"
call    _puts
mov     edx, cs:j
mov     eax, cs:c
mov     esi, edx
imul    esi, eax        ; XYZ2
mov     eax, cs:e
mov     ecx, [rbp+XYZ5]
mov     edx, [rbp+XYZ4]
mov     r8d, ecx        ; XYZ5
mov     ecx, edx        ; XYZ4
mov     edx, 3          ; XYZ3
mov     edi, eax        ; XYZ1
call    func
leave
retn

所以你会看到 ida 在分配参数的地方自动生成注释。您可以使用PrevNotTail从每个外部参照向后扫描 10 或 20 条指令,并检查参数字符串的注释。如果您使参数名称足够独特,这应该可以很好地识别指令(这就是我使用 XYZ1 而不是 a1 的原因)。

当然,

imul    esi, eax        ; XYZ2

不会真正帮助你那么多。但是如果您的大多数参数func都是常量,您的结果可能会更好