缓冲区溢出实验1原理篇
//---C源程序--------
#include<stdio.h>
#include<string.h>
unsigned char name[]="12345678aaaa";
int main(int argc, char* argv[])
{
unsigned char buf[8];
strcpy((char*)buf,(char *)name);
printf("hello world!");
return 0;
}
//-------------------------------------
下面是进入main()后的汇编代码:
00401000 /$ 83EC 08 sub esp, 8
00401003 |. 83C9 FF or ecx, FFFFFFFF
00401006 |. 33C0 xor eax, eax
00401008 |. 8D5424 00 lea edx, [esp]
0040100C |. 56 push esi
0040100D |. 57 push edi
0040100E |. BF 30704000 mov edi, 00407030 ; ASCII "12345678aaaa"
00401013 |. 68 48704000 push 00407048 ; ASCII "hello world!"
00401018 |. F2:AE repne scas byte ptr es:[edi]
0040101A |. F7D1 not ecx
0040101C |. 2BF9 sub edi, ecx
0040101E |. 8BC1 mov eax, ecx
00401020 |. 8BF7 mov esi, edi
00401022 |. 8BFA mov edi, edx
00401024 |. C1E9 02 shr ecx, 2
00401027 |. F3:A5 rep movs dword ptr es:[edi], dword p>
00401029 |. 8BC8 mov ecx, eax
0040102B |. 83E1 03 and ecx, 3
0040102E |. F3:A4 rep movs byte ptr es:[edi], byte ptr>
00401030 |. E8 0B000000 call 00401040
00401035 |. 83C4 04 add esp, 4
00401038 |. 33C0 xor eax, eax
0040103A |. 5F pop edi
0040103B |. 5E pop esi
0040103C |. 83C4 08 add esp, 8
0040103F /. C3 retn
在执行strcpy之前的堆栈情况:
0012FF68 0012FFC0
0012FF6C 00401AF1
0012FF70<= 00407048 push [ASCII "hello world!"]
0012FF74 7C930738 push edi
0012FF78 FFFFFFFF push esi;
0012FF7C 00401BAC |_这里就是给buf[8]留的内存空间
0012FF80 00407000 |
0012FF84 00401125 <-- main()的返回地址
0012FF88 00000001
0012FF8C 00370B40
0012FF90 00370B88
0012FF94 7C930738 ntdll.7C930738
执行了 strcpy 以后会从 0012FF7C 一直填充,将main()地返回地址给覆盖,成了61616161
于是当main()返回的时候就会跳到地址61616161去,那个地方不存在,于是就出错咯`