逆向一个最简单的函数

逆向一个最简单的函数,返回预定常亮应该够简单了。

C/C++代码:

int f()
{
	return 123;
};

0x01 x86

开启优化功能后,GCC编译器的汇编代码如下:

f:
		mov  eax,123
		ret

这个函数只是两条指令构成:第一条指令把数值123存放到eax寄存器中;再根据函数调用约定,后面一条指令会把eax的值当做返回值传递给调用者主函数,调用者(Caller)函数会从eax寄存器中取值把它当做返回结果。

0x02 ARM

ARM模式的情况:

f PROC
				MOV    r0,#0x7b;123
				BX     lr
				ENDP

ARM程序使用r0寄存器传递函数的返回值,所以指令把数值123赋值给r0。
ARM程序使用LR寄存器存储函数结束后的返回地址(Return Address);x86程序使用栈结构存放返回地址。可见,BX LR指令的作用是跳转到返回地址,返回到调用者函数,然后继续执行调用体caller的后续指令。

x86和ARM指令集中的mov是复制的意思,而不是移动。
在这里插入图片描述

0x03 MIPS

在mips指令中,寄存器有两种命名方式,一种是以数字命名($0- 31 ) , 另 一 种 是 以 伪 名 称 命 名 ( 31),另一种是以伪名称命名( 31,V0-$A0),在GCC生成的汇编指令中,寄存器都采用数字方式命名。

j	$31
li  $2,123

IDA会显示寄存器的伪名称

jr	$ra
li	$v0,0x7B

根据伪名称和寄存器数字编号可以知道,存储函数返回值的寄存器都是$ 2 ( 2( 2(V0),此处LI指令的意思是Load Immediate。

J和JR指令都是跳转指令,他们把执行流程递交给调用者函数,转到¥31寄存器中的地址上,这个寄存器相当于ARM平台上的LR寄存器。

为什么赋值指令LI和跳转指令J/JR的位置会反过来,这属于精简指令集的特性之一,转移指令延迟槽现象。简单来说就是,不管跳转发生与否,位于跳转指令后面的一条指令总是被先于跳转指令执行。

总之,转移指令后面的这条赋值指令是先于转移指令执行的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值