问题是这些参数可能并且在大多数情况下会被计算,而不是常量,因此您实际上并没有一条指令可以为您提供参数。考虑这个测试程序:
#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
都是常量,您的结果可能会更好。