strcpy中汇编的过程
00401191 mov edi,dword ptr ss:[esp+0x8] ; buffer数组地址
00401195 jmp short test.00401201
...
00401201 mov ecx,dword ptr ss:[esp+0xC] ; cpy的数的地址
00401205 test ecx,0x3 ; 判断cpy数的地址是否正确
0040120B je short test.00401226
...
00401226 mov edx,0x7EFEFEFF
0040122B mov eax,dword ptr ds:[ecx] ; eax保存buffer中四个字节
0040122D add edx,eax ; eax+7EFEFEFF
0040122F xor eax,-0x1 ; 对eax取反
00401232 xor eax,edx ; eax取反 xor (7EFEFEFF+eax)
00401234 mov edx,dword ptr ds:[ecx] ; 保存buffer四个字节
00401236 add ecx,0x4 ; ecx-->buffer+4
00401239 test eax,0x81010100 ; **见注解**
0040123E je short test.00401221
00401240 test dl,dl
00401242 je short test.00401278 ; 第一个字节为00
00401244 test dh,dh
00401246 je short test.0040126F ; 第二个字节为00
00401248 test edx,0xFF0000
0040124E je short test.00401262 ; 第三个字节为00
00401250 test edx,0xFF000000
00401256 je short test.0040125A ; 第四个字节为00
00401258 jmp short test.00401221
0040125A mov dword ptr ds:[edi],edx
0040125C mov eax,dword ptr ss:[esp+0x8]
00401260 pop edi ; 0012FB20
00401261 retn
00401262 mov word ptr ds:[edi],dx
00401265 mov eax,dword ptr ss:[esp+0x8]
00401269 mov byte ptr ds:[edi+0x2],0x0
0040126D pop edi ; 0012FB20
0040126E retn
0040126F mov word ptr ds:[edi],dx
00401272 mov eax,dword ptr ss:[esp+0x8]
00401276 pop edi ; 0012FB20
00401277 retn
00401278 mov byte ptr ds:[edi],dl
0040127A mov eax,dword ptr ss:[esp+0x8]
0040127E pop edi ; 0012FB20
0040127F retn
注解:同于0x81010100做或运算来判断改数组中存在00,分别有四个情况
- 第一个字节为00:则0040122D add edx,eax处,edx的最后一个字节必为FF,同时不会产生进位,那么第二个字节数处为(xx-2)xor(!xx),第八位必然为1,如果不为0,那么该处(xx-1)xor(!xx)第八位必然为0。同理第二个,第三个。
- 第四个字节为00,同理在add edx,eax处 edx的第一个字节必定为7F(7E+00+第三位的进位),那么7F xor (!00)=0x1000 0000
所以只有当四个字节中存在00时 test 0x81010100才可能不为1,跳出循环,接下来判断为00的字节位数。