1.win32实例汇编代码
.386
.model flat,stdcall
option casemap:none
include windows.inc
include user32.inc
includelib user32.lib
include kernel32.inc
includelib kernel32.lib
;数据段
.data
szText db 'HelloWorldPE',0
szText2 db 'OverFlow me!',0
szShellCode dd 0ffffffffh,0ddddddddh,0040103ah,0
;代码段
.code
;---------------------------
; 未检查长度的字符串拷贝函数
;---------------------------
_memCopy proc _lpSrc
local @buf[4]:byte
pushad
mov al,1
mov esi,_lpSrc
lea edi,@buf
.while al!=0
mov al,byte ptr [esi]
mov byte ptr [edi],al
inc esi
inc edi
.endw
popad
ret
_memCopy endp
start:
invoke _memCopy,addr szShellCode
invoke MessageBox,NULL,offset szText,NULL,MB_OK
invoke MessageBox,NULL,offset szText2,NULL,MB_OK
invoke ExitProcess,NULL
end start
2.情景分析
_memCopy函数的中,首先开辟了 local @buf[4]:byte 四个字节的缓冲区,函数是要把地址lpSrc处的字符串拷贝到这四个字节的缓冲区,但其判断字符串结尾是采用识别'\0'来判断的,并没有采用长度限制,因此存在缓冲区溢出漏洞。
将汇编源码编译成可执行文件(具体编译方法可参MASM的相关博客或者技术文章),用OD打开运行可执行文件:
在地址0x00401025处调用了0x00401000处的函数,也就是有栈溢出漏洞的_memCopy函数,转到0x00401000处:
地址0x00401003处即是在栈EBP-4处开辟bu的f四字节缓冲区,_memCopy函数要将szShellCode dd 0ffffffffh,0ddddddddh,0040103ah,0拷贝到此处。此时的栈数据如下图所示,EBP-4处即为四字节的buf缓冲区,拷贝szShellCode后EBP-4 EBP EBP+4处的值为0x0fffffff 0x0ddddddd 0x0040103a,另外一点就是EBP+4处存放的是函数返回后下一个要执行代码的地址(EIP),原来值为0x0040102a,被覆盖后的值变为0x0040103a,由最上面的OD图可以知道,本来显示HelloWorldPE字符串的MessageBox此时变为OverFlow me!,说明代码执行流程发生了改变。