大端序:数据的高位字节存放在地址的低端 低位字节存放在地址高端
小端序:数据的高位字节存放在地址的高端 低位字节存放在地址低端(例如x86)
栈增长方向:由高地址到低地址
缓冲区溢出:当计算机向缓冲区内填充数据位数时超过了缓冲区本身的容量,使得溢出的数据覆盖在合法数据上,通过往程序的缓冲区写超出其长度的内容,造成缓冲区的溢出,从而破坏程序的堆栈,造成程序崩溃或使程序转而执行其它指令。
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <iostream> int k; void fun(const char* input) { char buf[8]; strcpy(buf,input); printf("Address of input=%p\n",input); printf("Address of buf=%p\n",buf); k=(int)&input-(int)buf; printf("%s\n", buf); } void haha() { printf("\nOK!success"); } int main(int argc, char* argv[]) { printf("Address of foo=%p\n",fun); printf("Address of haha=%p\n",haha); void haha(); int addr[4]; char s[]="FindK"; printf("Address of s=%p\n",s); fun(s); printf("%d\n", k); int go=(int)&haha; printf("Address of &haha=%p\n",&haha); //把haha()函数的地址分离成字节 addr[0]=(go << 24)>>24; addr[1]=(go << 16)>>24; addr[2]=(go << 8)>>24; addr[3]=go>>24;char ss[]="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; for(int j=0;j<4;j++){ ss[k-j-1]=addr[3-j]; } fun(ss); return 0; }
fun()函数中buf只分配了8字节的空间,通过写超出其长度的字符串ss,并传入void fun()函数对buf赋值,使调用fun()函数时的堆栈溢出,覆盖了返回地址,令构造的ss输入部分恰巧使覆盖返回地址部分的内容正好指向haha()函数入口,这样程序就不会返回之前的步骤(也就是主函数中调用fun()函数下边的return指令),而是进入了haha()函数,同时执行haha()函数中的printf("\nOK!success")指令,在屏幕上打印出OK!success
内存模型:
00401019 ----haha
00401005 ----fun
..........................
0012FF68 ----s="FindK"
..........................
0012FF30 ----ss="aaaaaaaaaaaaaaaaaaaaaaaa"
..........................
0012FEDC----input (&s,&ss)
...(3byte) 此处4bytes被新的地址值覆盖,将跳转haha
0012FED8---- 函数返回地址//当调用一个函数的时候,首先是参数入栈,然后是返回地址
....(4byte)
0012FED3 ----buf[7]
......(6byte)
0012FECC ---- buf[0]