0x00寄存器
ARM处理器中一共有37个32寄存器,其中31个为通用寄存器、6个位状态寄存器。任何时候,通用寄存器(R0-R14)、PC、一个状态寄存器都是可以访问的。但是在不同的工作状态和工作模式,寄存器是否可以访问是不一样的。
状态寄存器就是保存了符号标志、零标志、溢出标志、进位标志等,和X86汇编寄存器中的一些寄存器的相似的
R0-R12供程序数据使用,R13是栈指针(SP),R14为子程序链接寄存器(LR),通常存储函数的返回地址
0x01指令
ARM处理器的指令集可以分为六种指令:跳转指令、数据处理指令、程序状态寄存器处理指令、加载存储指令、协处理器指令、异常产生指令。总的来说和X86指令集还是有些不一样的
跳转指令
跳转指令可以分为两种:
专门的跳转指令,可以实现向前向后32MB的地址跳转
直接修改PC寄存器,通过向PC寄存器写入目的地址,可以实现4GB的地址空间的跳转,结合使用MOV LR, PC,保存函数的返回地址
1.B:执行一个简单的跳转,目标地址是相对于当前PC值的偏移地址
2.BL:跳转之前会把PC值存到R14寄存器中,通常用于函数调用
3.BLX:和上一个指令相比,多的功能是将处理器的工作状态由ARM变成Thumb
4.BX:可以跳转到ARM指令或者Thumb指令
数据处理指令
可分为数据传送指令、算术逻辑运算运算、比较指令
1.MOV:和X86是差不多的
2.MVN:在转移之前先按位取反
3.CMP:两个寄存器中的值进行比较,不改变寄存器的值,但是更新CPSR标志寄存器
4.ADD:把后两个寄存器相加,结果存在第一个寄存器中
5.SUB:把后两个寄存器相减,结果存在第一个寄存器中
6.AND:逻辑与
7.ORR:逻辑或
8.EOR:异或
9.MUL:把后两个寄存器相乘,结果存在第一个寄存器中
程序状态寄存器处理指令
1.MRS:用于将程序状态寄存器的内容送到通用寄存器
2.MSR:将操作数的内容送到程序状态寄存器的特定域
加载存储指令
适用于在寄存器和存储器之间数据的传输
和X86不一样的是mov指令只能够在寄存器之间传送数据
LDR:将一个32位的数据送到寄存器中
LDRB:将一个8位的数据送到寄存器中,并且把高24位清零
LDRH:将一个16位的数据送到寄存器中,并且把高16位清零
STR:从源寄存器32位存入到存储器中,和前几个指令相比是不清零
协处理器指令
CDP:用于ARM处理器通知ARM协处理器来处理特定的操作,若协处理器不能完成,则抛出异常
LDC:让协处理器来将源寄存器的内容送到存储器中,若协处理器不能完成操作,则抛出异常
异常产生指令
SWI:产生软件中断
BKPT:产生软件断点中断
以上总结的是常见的,如果做题遇到不认识的指令,及时添补即可
0x03实战
typo
题目信息:
题目是静态链接,但是已经去了符号表,我们可以把libc的符号表导出来,再导进去这个文件,即可恢复一些符号
用ida来分析程序:(通过字符串来找到关键函数)
sub_8F00 首先用户必须先读入一个回车,然后才程序继续,不然程序就直接退出了,测试的时候发现f5出的不是太全,看汇编 可以看到E.r.r.o.r.,这个是每次循环读入字符串之后的输出,那么输入的函数肯定在这个之前 可以清晰的看到存在栈溢出
用pwndbg中的cyclic测出来偏移是112,第一次做arm的pwn,搞不懂返回地址在哪里存,把stack的数据打印出来就好了:
可以发现返回地址存在r11,距离R11的偏移也刚刚好是112
然后用ROPgadget找到合适的指令
可以看到有一个pop {r0, r4, pc},刚好覆盖了第一个参数和pc,修改成system("/bin/shx00")即可
exp:
baby_arm
这个题是64位的
通过捣鼓环境发现在ubuntu:18.04上gdb没有报错,所以又在ubuntu:18.04配置了一下环境
这道题是动态链接的
在IDA里面分析程序 首先读入bss段上一个长度512的字符串,然后在sub_4007F0里面存在栈溢出 但是发现,第二次输入的字符串在ret地址的下面,所以覆盖sub_400818函数的返回地址 计算出来偏移是72,这里ROP用到的是ret2csu
然后函数里面存在mprotect,我们利用ROP把bss段修改成可读可写可执行的权限,然后把shellcode写入里面,最后跳转到bss段即可获取到shell
exp:
|