在程序二进制文件中,如何确定与变量参数函数“printf”的参数传递相关的指令?例如:
#include <stdio.h>
#include <string.h>
int fun(int a, int b){
return a+b;
}
void main (int argc, char* argv[]){
int a = 0;
int b = 1;
int c = 2;
int d = 3;
printf("a:fun(b,c):d: %d:%d:%d\n", a, fun(b,c), d);
}
组装如下:
(gdb) disas main
Dump of assembler code for function main:
0x080483f1 <+0>: push %ebp
0x080483f2 <+1>: mov %esp,%ebp
0x080483f4 <+3>: and $0xfffffff0,%esp
0x080483f7 <+6>: sub $0x20,%esp
0x080483fa <+9>: movl $0x0,0x10(%esp)
0x08048402 <+17>: movl $0x1,0x14(%esp)
0x0804840a <+25>: movl $0x2,0x18(%esp)
0x08048412 <+33>: movl $0x3,0x1c(%esp)
0x0804841a <+41>: mov 0x18(%esp),%eax
0x0804841e <+45>: mov %eax,0x4(%esp)
0x08048422 <+49>: mov 0x14(%esp),%eax
0x08048426 <+53>: mov %eax,(%esp)
0x08048429 <+56>: call 0x80483e4 <fun>
=> 0x0804842e <+61>: mov $0x8048530,%edx
0x08048433 <+66>: mov 0x1c(%esp),%ecx
0x08048437 <+70>: mov %ecx,0xc(%esp)
0x0804843b <+74>: mov %eax,0x8(%esp)
0x0804843f <+78>: mov 0x10(%esp),%eax
0x08048443 <+82>: mov %eax,0x4(%esp)
=> 0x08048447 <+86>: mov %edx,(%esp)
0x0804844a <+89>: call 0x8048300 <printf@plt>
0x0804844f <+94>: leave
0x08048450 <+95>: ret
与变量参数函数“print”的参数传递相关的指令是否是两条指令“0x0804842e&lt; + 61&gt;:mov $ 0x8048530,%edx”和“0x08048447&lt; + 86&gt;:mov%edx”之间的指令, (%ESP)”。
我测试了很多功能“printf”。在我所有测试的案例中,与参数传递相关的指令都在这两个指令之间。
答案 0 :(得分:-1)
您可以通过了解C调用约定来找到它。那就是参数以相反的顺序被压入堆栈。
`0x0804842e&lt; + 61&gt;:mov $ 0x8048530,%edx //可能是字符串文字
0x08048433&lt; + 66&gt;:mov 0x1c(%esp),%ecx //将3个字面移动到%ecx
0x08048437&lt; + 70&gt;:mov%ecx,0xc(%esp)//将3移到堆栈上的参数顶部(%esp是堆栈指针)
0x0804843b&lt; + 74&gt;:mov%eax,0x8(%esp)//将fun中的返回值移到堆栈的下一个插槽中,%eax存储函数的返回值。
0x0804843f&lt; + 78&gt;:mov 0x10(%esp),%eax //将0字面移动到%eax
0x08048443&lt; + 82&gt;:mov%eax,0x4(%esp)//将%eax移入堆栈的下一个插槽
0x08048447&lt; + 86&gt;:mov%edx,(%esp)//将字符串文字移动到堆栈
0x0804844a&lt; + 89&gt;:调用0x8048300` //调用printf