69,373
社区成员
发帖
与我相关
我的任务
分享
int i,j,a[4][2];
//你事先把a[4][2]赋值或者事先打印出其值
a[4][2] = 100;
for(i=0;i<4;i++)
{
for(j=0;j<2;j++)
a[i][j]=i+j;
}
//再看下值
#include <stdio.h>
#define N 10
int main()
{
int idx;
int a[N];
// 这里的循环出口为什么是N+2,这个是我在VS2010下面调试出来的,其他的编译器不一定是这样
for (idx = 0; idx <= N + 2; ++idx) {
a[idx] = 0;
printf("idx=%d\t", idx);
}
printf("run at end...\n");
getchar();
return 0;
}
int main()
{
00831390 push ebp
00831391 mov ebp,esp
00831393 sub esp,100h ;注意这里,VS一次性的分配了256个栈地址用于临时变量,
;这个数字是怎么算出来的,我不是很清楚,就是很大,多余局部变量用的空间,
;我们的代码是1个int和10个int,共需要44个字节
00831399 push ebx
0083139A push esi
0083139B push edi
0083139C lea edi,[ebp-100h]
008313A2 mov ecx,40h
008313A7 mov eax,0CCCCCCCCh
008313AC rep stos dword ptr es:[edi]
008313AE mov eax,dword ptr [___security_cookie (837000h)]
008313B3 xor eax,ebp
008313B5 mov dword ptr [ebp-4],eax
int idx;
int a[N];
for (idx = 0; idx <= N + 2; ++idx) {
008313B8 mov dword ptr [ebp-0Ch],0 ;注意这里,意味着idx的地址是ebp-0Ch,
;如果在循环中能把这个地址写入0,就会一直循环下去
008313BF jmp main+3Ah (8313CAh)
008313C1 mov eax,dword ptr [ebp-0Ch]
008313C4 add eax,1
008313C7 mov dword ptr [ebp-0Ch],eax
008313CA cmp dword ptr [ebp-0Ch],0Ch
008313CE jg main+68h (8313F8h)
a[idx] = 0;
008313D0 mov eax,dword ptr [ebp-0Ch]
008313D3 mov dword ptr [ebp+eax*4-3Ch],0 ;注意这里,如果eax(也就是idx)等于0,
;其实就是数组a的地址,所以a的地址是 ebp + 0*4 - 3Ch,就是ebp-3Ch,
;这是数组的偏移量为0的元素,如果是偏移量为10的元素,地址就是ebp-3C+4*10,
;可以推出,偏移量是12的元素(其实已经出了数组了,但是栈地址仍然是可以访问的),
;地址是ebp-3C + 4*12,也就是ebp-12,也就是ebp-0Ch,也就是idx,
;所以这个例子证明是可以溢出的,但是编译器不同,溢出地址不同,
;linux下面变量的定义是紧紧挨在一起的,所以数组的最后一个不能
;写的元素正好是另一个局部变量的地址,有条件可以在linux下
;反编译验证这一点
printf("idx=%d\t", idx);
008313DB mov esi,esp
008313DD mov eax,dword ptr [ebp-0Ch]
008313E0 push eax
008313E1 push offset string "idx=%d\t" (835750h)
008313E6 call dword ptr [__imp__printf (8382B4h)]
008313EC add esp,8
008313EF cmp esi,esp
008313F1 call @ILT+295(__RTC_CheckEsp) (83112Ch)
}
008313F6 jmp main+31h (8313C1h)
printf("run at end...\n");
008313F8 mov esi,esp
008313FA push offset string "run at end...\n" (83573Ch)
008313FF call dword ptr [__imp__printf (8382B4h)]
00831405 add esp,4
00831408 cmp esi,esp
0083140A call @ILT+295(__RTC_CheckEsp) (83112Ch)
getchar();
0083140F mov esi,esp
00831411 call dword ptr [__imp__getchar (8382B8h)]
00831417 cmp esi,esp
00831419 call @ILT+295(__RTC_CheckEsp) (83112Ch)
return 0;
0083141E xor eax,eax
}
00831420 push edx
00831421 mov ecx,ebp
00831423 push eax
00831424 lea edx,[ (831450h)]
0083142A call @ILT+120(@_RTC_CheckStackVars@8) (83107Dh)
0083142F pop eax
00831430 pop edx
00831431 pop edi
00831432 pop esi
00831433 pop ebx
00831434 mov ecx,dword ptr [ebp-4]
00831437 xor ecx,ebp
00831439 call @ILT+15(@__security_check_cookie@4) (831014h)
0083143E add esp,100h
00831444 cmp ebp,esp
00831446 call @ILT+295(__RTC_CheckEsp) (83112Ch)
0083144B mov esp,ebp
0083144D pop ebp
0083144E ret