逆向工程-printf()函数与参数传递
Posted 小蚂蚁_CrkRes
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了逆向工程-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
以上是关于逆向工程-printf()函数与参数传递的主要内容,如果未能解决你的问题,请参考以下文章