C语言探究 第一课 字符串数组篇
先上C语言 再上反汇编
程序代码:
int _tmain(int argc, _TCHAR* argv[])
{
char str[]="user32";
//char *str="user32"
return 0;
}
程序代码:
text:004117C0
.text:004117C0 push ebp
.text:004117C1 mov ebp, esp
.text:004117C3 sub esp, 0D4h
.text:004117C9 push ebx
.text:004117CA push esi
.text:004117CB push edi
.text:004117CC lea edi, [ebp+var_D4]
.text:004117D2 mov ecx, 35h
.text:004117D7 mov eax, 0CCCCCCCCh
.text:004117DC rep stosd
.text:004117DE mov eax, __security_cookie ; 0BB40E64Eh
.text:004117E3 xor eax, ebp
.text:004117E5 mov [ebp+var_4], eax
.text:004117E8 mov eax, dword ptr ds:aUser32 ; "user32" 此处可以看到
.text:004117ED mov [ebp+var_10], eax "user"
.text:004117F0 mov cx, word ptr ds:aUser32+4
.text:004117F7 mov [ebp+var_C], cx "32"
.text:004117FB mov dl, byte ptr ds:aUser32+6
.text:00411801 mov [ebp+var_A], dl 0
上面代码为 char str[]="user32" 的反汇编,可以看到 user32是被放到了栈中的
.text:00411804 xor eax, eax
.text:00411806 push edx
.text:00411807 mov ecx, ebp
.text:00411809 push eax
.text:0041180A lea edx, dword_411828
.text:00411810 call j__RTC_CheckStackVars
.text:00411815 pop eax
.text:00411816 pop edx
.text:00411817 pop edi
.text:00411818 pop esi
.text:00411819 pop ebx
.text:0041181A mov ecx, [ebp+var_4]
.text:0041181D xor ecx, ebp
.text:0041181F call j___security_check_cookie
.text:00411824 mov esp, ebp
.text:00411826 pop ebp
.text:00411827 retn
.text:00411827 wmain endp
下面是另外一个版本
程序代码:
int _tmain(int argc, _TCHAR* argv[])
{
//char str[]="user32";
char *str="user32";
return 0;
}
程序代码:push ebp mov ebp, esp sub esp, 0CCh push ebx push esi push edi lea edi, [ebp+var_CC] mov ecx, 33h mov eax, 0CCCCCCCCh rep stosd mov [ebp+var_8], offset aUser32 ; "user32" 此处为char *str="user32" xor eax, eax pop edi pop esi pop ebx mov esp, ebp pop ebp retn wmain endp
总结 char str[]="user32" 和 char *str="user32"两个
1.两个操作的数据来源均来自于数据段
2.前者用mov指令将指定字符串 存放到了栈中 进行访问,后者直接将数据的地址存放到栈中用地址间接进行访问
3.采用前者进行操作容易产生栈溢出的错误 ,后者是不会的 所以用后者进行操作是比较安全和妥当的
4.前者数据初始化慢 后者初始化快
[ 本帖最后由 zhu224039 于 2014-6-7 15:35 编辑 ]









