我一直试图通过堆栈粉碎更改返回地址来跳过指令.以下代码跳过main中的++并输出"1 3"的输出.我已经在32位英特尔机器上执行了这段代码.
#include<stdio.h>
void fun(int a,int b) {
// buffer
char buf[8];
char *p;
p = (char *)buf+24;
*p=*p+5;
return;
}
int main() {
int a=1,b=2;
fun(a,b);
a++;
b++;
printf("%d %d",a,b);
}
Run Code Online (Sandbox Code Playgroud)
我无法理解为什么返回地址存储在距buf起始地址24字节的位移处.我尝试在不同的32位英特尔机器上执行相同的代码,我不得不使用20字节而不是24字节的位移.我已将我的理解放在下图中.我不确定是什么填补了"?"所代表的差距.在图中.gcc是否存在任何金丝雀价值或者我错过了什么?
链接到图:http://www.cse.iitb.ac.in/~shashankr/stack.png
粉碎堆栈example3.c混乱问了同样的问题,但无法解释一般的置换原因.
下图给出了通过在函数中放置断点获得的堆栈的视图.
堆栈内容http://www.cse.iitb.ac.in/~shashankr/stack4.png
以下是main和fun的汇编代码:
Dump of assembler (fun):
0x08048434 <+0>: push %ebp
0x08048435 <+1>: mov %esp,%ebp
0x08048437 <+3>: sub $0x18,%esp
0x0804843a <+6>: mov %gs:0x14,%eax
0x08048440 <+12>: mov %eax,-0xc(%ebp)
0x08048443 <+15>: xor %eax,%eax
0x08048445 <+17>: lea -0x14(%ebp),%eax
0x08048448 <+20>: add $0x18,%eax
0x0804844b <+23>: …Run Code Online (Sandbox Code Playgroud) 我一直在阅读"Shellcoders手册",并指的是这个链接,用于实现堆栈溢出.但似乎Linux内核开发人员已经使内核非常安全.这是我的问题.
1)这段代码
void function(int a, int b, int c) {
char buffer1[8];
char buffer2[10];
int* ret;
ret = buffer1 + 6;
*ret+=8;
}
void main() {
int x;
x = 0;
function(1,2,3);
x = 1;
printf("%d\n",x);
}
Run Code Online (Sandbox Code Playgroud)
给出输出
$ cc smash.c
smash.c: In function ‘function’:
smash.c:7:8: warning: assignment from incompatible pointer type
$ ./a.out
1
Run Code Online (Sandbox Code Playgroud)
用的线*ret+=8与*ret=8给出以下输出
*** stack smashing detected ***: ./a.out terminated
======= Backtrace: =========
/lib/i386-linux-gnu/libc.so.6(__fortify_fail+0x50)[0xa86df0]
/lib/i386-linux-gnu/libc.so.6(+0xe5d9a)[0xa86d9a]
./a.out[0x8048448]
./a.out[0x8048477]
/lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xe7)[0x9b7e37]
./a.out[0x8048381]
======= Memory …Run Code Online (Sandbox Code Playgroud)