直接修改栈的实例

xiaoxiao2021-03-01  36

1 [bobo]$catgotover.c 2 #include<stdio.h> 3 #include<string.h> 4 5 intevil_code(char*s) 6 {7 printf("hi,Iamhere!\n"); 8 return0; 9 }10 11 intmain(intargc,char*argv[]) 12 {13 longaddr=*(long*)((long)strlen+2); 14 15 *(long*)addr=(long)evil_code; 16 17 intlen=strlen(argv[0]); 18 19 printf("len=[%d]\n",len); 20 21 return0; 22 }23 24 [bobo]$gccgotover.c-ogotover 25 [bobo]$./gotover 26 hi,Iamhere! 27 len=[0]

看了这篇帖子,理解了上面这段程序,直接修改栈内容。

详细内容可以参考 , 还有一篇alert7写的动态库符号解析过程 大概是这样的: 对于32位的x86,调用动态库中的函数,比如 printf(); 调用的其实是plt中的一小段代码,这一小段代码如: address + 0: jmp *0xXXXXXXXX address + 6 : push 一个常数 jmp 0xYYYYYYYY 第一次调用printf时地址0xXXXXXXXX中的值就是address + 6, 也就是第一次jmp会跳到 address + 6的地方,然后下一个jmp进行如号解析,然后在0xXXXXXXXX中写入真实的printf函数的地址,之后再调用printf时就会直接跳到printf函数去了。 我前面那个代码就是在0xXXXXXXXX中放入evil_code()函数的地址,address + 0: jmp *0xXXXXXXXX 这条指令占用6个字节,前面两个是操作码,后面就是地址,所以有代码中" + 2"

跑了帖子中更能清晰理解栈结构的例子,结果如下:

[S@fedora-1 test]$ cat test1.c #include

int gi = 1;

f(char *fmt, int *p, int v) { int i;

for(i = 0; i < 8; i++) { printf("%d %p %p\n", i, &i + i, *(&i+i)); } printf("p = %p v = %d\n", p, v); return;

for(i = 0; i < 256; i++) { printf("addr = %p value = %d\n", &gi, gi); } }

main() { f("fmt", &gi, gi); } [S@fedora-1 test]$ ./a.out 0 0xbf8daf24 (nil) 1 0xbf8daf28 0xbf8daf48 2 0xbf8daf2c 0x8048469 3 0xbf8daf30 0x804855d 4 0xbf8daf34 0x80496d4 5 0xbf8daf38 0x1 6 0xbf8daf3c 0x80484a9 7 0xbf8daf40 0xa7add0 p = 0x80496d4 v = 1

程序中的局部数组溢出使用,就能改变栈,结果不可预料。打印出荒唐的信息。

摘自:http://bbs.chinaunix.net/viewthread.php?tid=1652842&extra=page=1&filter=digest&page=6

转载请注明原文地址: https://www.6miu.com/read-3450340.html

最新回复(0)