前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >ARM中的进程内存和内存破坏

ARM中的进程内存和内存破坏

作者头像
用户1423082
发布2024-12-31 18:32:55
发布2024-12-31 18:32:55
9000
代码可运行
举报
文章被收录于专栏:giantbranch's bloggiantbranch's blog
运行总次数:0
代码可运行

注:本位为简译文章,原文见最后的reference

进程的内存布局

程序载入内存会分成多个段,我们关心下面三个

  1. 程序空间

一般情况下布局如下

我们可以通过gef看到内存布局及权限

代码语言:javascript
代码运行次数:0
复制
azeria@labs:~/exp $ gdb program
...
gef> gef config context.layout "code"
gef> break main
Breakpoint 1 at 0x104c4: file program.c, line 6.
gef> run
...
gef> nexti 2
-----------------------------------------------------------------------------------------[ code:arm ]----
...
      0x104c4 <main+20>        mov    r0,  #8
      0x104c8 <main+24>        bl     0x1034c <malloc@plt>
->    0x104cc <main+28>        mov    r3,  r0
      0x104d0 <main+32>        str    r3,  [r11,  #-8]
...
gef> vmmap
Start      End        Offset     Perm Path
0x00010000 0x00011000 0x00000000 r-x /home/azeria/exp/program <---- Program Image
0x00020000 0x00021000 0x00000000 rw- /home/azeria/exp/program <---- Program Image continues...
0x00021000 0x00042000 0x00000000 rw- [heap] <---- HEAP
0xb6e74000 0xb6f9f000 0x00000000 r-x /lib/arm-linux-gnueabihf/libc-2.19.so <---- Shared library (libc)
0xb6f9f000 0xb6faf000 0x0012b000 --- /lib/arm-linux-gnueabihf/libc-2.19.so <---- libc continues...
0xb6faf000 0xb6fb1000 0x0012b000 r-- /lib/arm-linux-gnueabihf/libc-2.19.so <---- libc continues...
0xb6fb1000 0xb6fb2000 0x0012d000 rw- /lib/arm-linux-gnueabihf/libc-2.19.so <---- libc continues...
0xb6fb2000 0xb6fb5000 0x00000000 rw-
0xb6fcc000 0xb6fec000 0x00000000 r-x /lib/arm-linux-gnueabihf/ld-2.19.so <---- Shared library (ld)
0xb6ffa000 0xb6ffb000 0x00000000 rw-
0xb6ffb000 0xb6ffc000 0x0001f000 r-- /lib/arm-linux-gnueabihf/ld-2.19.so <---- ld continues...
0xb6ffc000 0xb6ffd000 0x00020000 rw- /lib/arm-linux-gnueabihf/ld-2.19.so <---- ld continues...
0xb6ffd000 0xb6fff000 0x00000000 rw-
0xb6fff000 0xb7000000 0x00000000 r-x [sigpage]
0xbefdf000 0xbf000000 0x00000000 rw- [stack] <---- STACK
0xffff0000 0xffff1000 0x00000000 r-x [vectors]

栈溢出

如图,就是程序对用户输入的长度做限制,导致可以覆盖LR寄存器的味道,通过精心地控制,即可达到任意代码执行的目的

我们用如下程序测试

代码语言:javascript
代码运行次数:0
复制
/*azeria@labs:~/exp $ gcc stack.c -o stack*/
#include "stdio.h"

int main(int argc, char **argv)
{
char buffer[8];
gets(buffer);
}

汇编代码如下:

我们输入7个A,可以看到 R11(即FP)和LR储存的位置还没被覆盖

假如我们输入16个A,可以看到都覆盖了,之后的pop {r11, pc}就会让攻击者劫持控制流了

继续运行,确实被控制了,程序也蹦了

堆溢出

堆相对复杂,我们malloc一次,就会得到一个chunk,这个chunk有header和user data,堆溢出有下面图中的两种:一个是chunk内部,一个是溢出到另一个chunk了

chunk内部溢出

示例代码

代码语言:javascript
代码运行次数:0
复制

/*azeria@labs:~/exp $ gcc intra_chunk.c -o intra_chunk -O*/
#include "stdlib.h"
#include "stdio.h"

struct u_data                                          //object model: 8 bytes for name, 4 bytes for number
{
 char name[8];
 int number;
};

int main ( int argc, char* argv[] )
{
 struct u_data* objA = malloc(sizeof(struct u_data)); //create object in Heap

 objA->number = 1234;                                 //set the number of our object to a static value
 gets(objA->name);                                    //set name of our object according to user's input

 if(objA->number == 1234)                             //check if static value is intact
 {
  puts("Memory valid");
 }
 else                                                 //proceed here in case the static value gets corrupted
 {
  puts("Memory corrupted");
 }
}

可以看到,假如我们分配一个结构体的内存,假如对name的输入没有限制,那么number也是我们可以控制的

汇编如下:

输入7个A

堆从0x00021000开始,结构如下,number还没被覆盖

但是我们输入8个A,那么number的最低位就被00覆盖了

那就可以改变程序的执行流程

chunk外部溢出

示例代码如下:

代码语言:javascript
代码运行次数:0
复制
/*azeria@labs:~/exp $ gcc inter_chunk.c -o inter_chunk*/
#include "stdlib.h"
#include "stdio.h"

int main ( int argc, char* argv[] )
{
 char *some_string = malloc(8);  //create some_string "object" in Heap
 int *some_number = malloc(4);   //create some_number "object" in Heap

 *some_number = 1234;            //assign some_number a static value
 gets(some_string);              //ask user for input for some_string

 if(*some_number == 1234)        //check if static value (of some_number) is in tact
 {
 puts("Memory valid");
 }
 else                            //proceed here in case the static some_number gets corrupted
 {
 puts("Memory corrupted");
 }
}

差不多,我们也先输入7个A,可以看到堆的结构如下

16个A,header和some_number都被覆盖了

也同样可以改变执行流程

Reference

https://azeria-labs.com/process-memory-and-memory-corruption/

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018-07-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 进程的内存布局
  • 栈溢出
  • 堆溢出
  • Reference
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档