Closed. This question needs to be more
focused。它当前不接受答案。
想改善这个问题吗?更新问题,使其仅关注
editing this post的一个问题。
去年关闭。
Improve this question
我试图找出如何在C / C++中调用函数时传递该函数的参数以及如何在汇编级别上返回该函数的返回值。我找到了这些答案:
Assembly x86 - Calling C functions How does argument passing work?表示堆栈用于在C / C++中的函数之间传递参数。但是,当我编写一个简单的C++测试程序并在radare2中反汇编它时,它似乎并未使用堆栈将参数传递给该函数。而是将参数放在函数调用之前的
esi
和
edi
中。
尽管此站点上的答案将立即对您有所帮助,但非常感谢您可以链接到我可以了解更多信息的文档,即使正确的文档可能太技术性了,我也无法理解。
测试C++程序:
void foo(int a, int b) {
return;
}
int main() {
int a=5;
foo(5,a);
return 0;
}
从radare2拆卸下来的组件:
┌ (fcn) main 37
│ int main (int argc, char **argv, char **envp);
│ ; var int32_t var_4h @ rbp-0x4
│ ; DATA XREF from entry0 @ 0x50d
│ 0x00000607 55 push rbp
│ 0x00000608 4889e5 mov rbp, rsp
│ 0x0000060b 4883ec10 sub rsp, 0x10
│ 0x0000060f c745fc050000. mov dword [var_4h], 5
│ 0x00000616 8b45fc mov eax, dword [var_4h]
│ 0x00000619 89c6 mov esi, eax
│ 0x0000061b bf05000000 mov edi, 5
│ 0x00000620 e8d5ffffff call sym foo(int, int) ; sym.foo_int__int
│ 0x00000625 b800000000 mov eax, 0
│ 0x0000062a c9 leave
└ 0x0000062b c3 ret
引起此问题的原因是以下我尝试解决的初学者破解代码。
我并不是在寻求帮助来解决这一难题,而只是希望帮助您理解以下示例中如何传递函数自变量以及将来可以在哪里进行查找。
以下来自crame的示例显示了被调用的sym.imp.puts(以下两个示例是手动键入的,因此它们可能包含错误,尽管我确实尝试过校对):
; CODE XREF from main @ 0x11f8
; 0x36915
; "Wrong key!"
lea rdi, str.Wrong_key
; int puts(const char *s)
call sym.imp.puts;[oo]
puts
似乎具有从
str.Wrong_key
传递给
rdi
的地址。
另一方面,此代码段:
lea rax, [var_6ch]
mov rsi, rax
; const char *format
; "%d"
lea rdi, [0x000368ff]
mov eax, 0
; int scanf(const char *format)
call sym.imp.__isoc99_scanf;[ob]
mov eax, dword [var_6ch]
cmp eax, 1
je 0x1228
我无法理解此代码段中的情况。在此之前不使用
var_6ch
。大概是这样调用
scanf
的:
scanf("%d", var_6ch);
但是我看不到如何将
var_6ch
或
%d
字符串传递给scanf。
以前的所有代码示例似乎都没有使用堆栈来传递参数,因此,感谢您的帮助。
在x86-64(这是您所使用的体系结构)上,System V ABI调用约定是最常用的,它定义了以下用于函数参数的寄存器(按声明顺序):RDI,RSI,RDX ,RCX,R8,R9,XMM0至XMM07。返回寄存器是RAX。
另一方面,在x86 32位上,由于寄存器较少,因此通常在堆栈上传递参数。
当然,调用约定不仅定义了如何传递参数,要了解更多信息,还可以看看the wikipedia page。
您在该代码段中看到的正是这样的:
lea rax, [var_6ch] ; get the address of some variable
mov rsi, rax ; rsi = second parameter
; loads the variable's address into rsi
lea rdi, [0x000368ff] ; rdi = first parameter
; loads the address of the format string into rdi
mov eax, 0 ; clear eax
call sym.imp.__isoc99_scanf;[ob] ; call scanf(rdi, rsi)
mov eax, dword [var_6ch]
cmp eax, 1
je 0x1228