逆向工程-printf()函数与参数传递

#include<stdio.h>

int main()

{

printf("a=%d; b=%d;c=%d",1,2,3);

return 0;

}

 

 

x86传递3个参数

$SG3830 DB 'a=%d;b=%d;c=%d',00h

...

push 3

push 2

push 1

push OFFSET $SG3830

call _printf

add esp,16

 

函数的参数以逆序存入栈里,第一个参数在最后入栈。

32位地址指针和int类型数据都占据32位/4字节空间。4个参数总共占16字节的存储空间

在调用函数之后,“ADD ESP,X”指令修正ESP寄存器中的栈指针。

 

如果某个程序连续地调用多个函数,且调用函数的指令之间不夹杂其他指令 ,那么编译器可能把释放参数存储空间的“ADD ESP,X”指令进行合并,一次性释放所有空间。

push a1

push a2

call ...

...

push a1

call ...

push a1

push a2

push a3

call ...

add esp,24

如下例:

push 3

call sub_100018B0

call sub_100019D0

call sub_10006A90

push 1

call sub_10006A90

add esp,8

 

cdecl调用约定的特征:被调用方函数不负责恢复ESP的状态;调用方函数负责还原参数所用的空间。

ADD ESP,10

ESP寄存器的值有变化,但是栈中的数据还在那里。因为程序没有把原有的栈的数据进行清零,所以保留在栈指针SP之上的参数值就成为了噪音或者脏数据。

 

GCC编译

main proc near

 

var_10 =dword ptr-10h

var_C =dword ptr-0Ch

var_8 =dword ptr-8

var_4 =dword ptr-4

push ebp

mov ebp,esp

and esp,0FFFFFFF0h

sub esp,10h

mov eax,offset aADBDCD;"a=%d;b=%d;c=%d"

mov [esp+10h+var_4],3

mov [esp+10h+var_8],2

mov [esp+10h+var_C],1

mov [esp+10h+var_10],eax

call _printf

mov eax,0

leave

retn

main endp

与MSVC生成 程序相比,GCC生成的程序仅在参数入栈的方式上有所区别。GCC没有使用PUSH/POP指令,而是直接对栈进行了操作。

 

ARM模式下传递3个参数

ARM系统在传递参数时,通常会进行拆分:把前4个参数传递给R0~R3寄存器,然后利用栈传递其余的参数。

 

32位ARM系统

非经优化的Keil+ARM模式

main

STMFD SP!,{R4,LR}

MOV R3,#3

MOV R2,#2

MOV R1,#1

ADR R0,aADBDCD; "a=%d;b=%d;c=%d"

BL __2printf

MOV R0,#0

LDMFD SP!,{R4,PC}

 

R0~R3寄存器依次负责传递参数。R0 寄存器置0,对应着return 0

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小蚂蚁_CrkRes

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值