C语言逆向——常量字符串的赋值copy分析
注意区别,hello 和 world两个字符串都是放在常量存储区的!
int main(int argc, char* argv[]) { // Fun(101); char* s = "hello"; char arr[] = "world"; printf("%s\n %s\n", s, arr); return 0; }
但是,在给arr赋值的时候,从其汇编实现看,是copy 常量world的内容了过去。
98: char* s = "hello"; 0040D8A8 mov dword ptr [ebp-4],offset string "hello" (00422fc8) 99: char arr[] = "world"; 0040D8AF mov eax,[string "world" (00422fc0)] 0040D8B4 mov dword ptr [ebp-0Ch],eax 0040D8B7 mov cx,word ptr [string "world"+4 (00422fc4)] 0040D8BE mov word ptr [ebp-8],cx 100: printf("%s\n %s\n", s, arr); 0040D8C2 lea edx,[ebp-0Ch] 0040D8C5 push edx 0040D8C6 mov eax,dword ptr [ebp-4] 0040D8C9 push eax 0040D8CA push offset string "%s\n %s\n" (00422fb8) 0040D8CF call printf (0040d710)
因为world占用2个字节,所以mov了两次,也就是先copy worl部分,再copy 最后d字符。
0040D8AF mov eax,[string "world" (00422fc0)] 0040D8B4 mov dword ptr [ebp-0Ch],eax 0040D8B7 mov cx,word ptr [string "world"+4 (00422fc4)] 0040D8BE mov word ptr [ebp-8],cx
我们验证下,将字符串继续增加:
int main(int argc, char* argv[]) { // Fun(101); char* s = "hello"; char arr[] = "world12345678"; printf("%s\n %s\n", s, arr); return 0; }
反汇编看看,
98: char* s = "hello"; 0040D8A8 mov dword ptr [ebp-4],offset string "hello" (00422fc8) 99: char arr[] = "world12345678"; 0040D8AF mov eax,[string "world12345678" (00422fd0)] 0040D8B4 mov dword ptr [ebp-14h],eax 0040D8B7 mov ecx,dword ptr [string "world12345678"+4 (00422fd4)] 0040D8BD mov dword ptr [ebp-10h],ecx 0040D8C0 mov edx,dword ptr [string "world12345678"+8 (00422fd8)] 0040D8C6 mov dword ptr [ebp-0Ch],edx 0040D8C9 mov ax,[string "world12345678"+0Ch (00422fdc)] 0040D8CF mov word ptr [ebp-8],ax 100: printf("%s\n %s\n", s, arr); 0040D8D3 lea ecx,[ebp-14h] 0040D8D6 push ecx 0040D8D7 mov edx,dword ptr [ebp-4] 0040D8DA push edx 0040D8DB push offset string "%s\n %s\n" (00422fb8) 0040D8E0 call printf (0040d710)
果然,又多了几个字节,还是按照既定的策略进行常量区域字符串的copy。