第一次对反汇编代码做深入阅读,学到了很多东西,但还没成系统。
00401BD0 /$ 55 push ebp 00401BD1 |. 8BEC mov ebp, esp 00401BD3 |. 81EC 14040000 sub esp, 414 00401BD9 |. 56 push esi 00401BDA |. 57 push edi 00401BDB |. BF B0534000 mov edi, 004053B0 ; ttttttt 00401BE0 |. 83C9 FF or ecx, FFFFFFFF ; ecx赋值为FFFFFFFF,下面讲解为什么。 00401BE3 |. 33C0 xor eax, eax ; eax清0,此时al也为0,下面会用到。 00401BE5 |. F2:AE repne scas byte ptr es:[edi] ; 在es:[edi]中循环查找,直到es:[di]与al(al=0)相等或者ecx为0为止,每查找一次,ecx就会减1。 00401BE7 |. F7D1 not ecx ; 逻辑非命令,如果ecx为FFFFFFF6,执行not ecx后,ecx就变成了9。此时ecx代表了字符串长度+1。 00401BE9 |. 49 dec ecx ; 获取字符串的实际长度。 00401BEA |. 83F9 04 cmp ecx, 4 ; 用户名长度与4比较 00401BED |. 0F82 BE010000 jb 00401DB1 ; 小于4就会自动跳出,无弹窗 00401BF3 |. BF A0534000 mov edi, 004053A0 ; tttttttt 00401BF8 |. 83C9 FF or ecx, FFFFFFFF ; 同上面的差不多 00401BFB |. F2:AE repne scas byte ptr es:[edi] ; 其实这些代码就是strlen()优化后的代码。 00401BFD |. F7D1 not ecx ; 00401BFF |. 49 dec ecx ; 00401C00 |. 83F9 08 cmp ecx, 8 ; ecx是注册码长度,不得小于8 00401C03 |. 0F82 A8010000 jb 00401DB1 ; 00401C09 |. 8B15 74114000 mov edx, dword ptr [401174] ; 把401174指向的4个字节的数据给edx,执行后edx=401178 00401C0F |. B9 00030000 mov ecx, 300 ; 00401C14 |. BF A0474000 mov edi, 004047A0 ; 目测指向4047A0这块区域的定义比保存密码、用户名的要早,但初始化晚。不知道对不对。 00401C19 |. F3:AB rep stos dword ptr es:[edi] ; STOS是将eax中的值拷贝到ES:EDI指向的地址,向上找eax有关的代码,可以知道是0。rep是指上面代码重复执行ecx次。 00401C1B |> 8BC8 /mov ecx, eax ; 上面一行,我的理解是分配缓冲区,初始化为0。 00401C1D |. 8BFA |mov edi, edx ; edi=401178,eax=0,ecx=0。 00401C1F |. 83E1 0F |and ecx, 0F ; 让ecx高16位清0,干啥用? 00401C22 |. 0FBEB1 A05340>|movsx esi, byte ptr [ecx+4053A0] ; 密码 带符号扩展,是不是把ANSI转换成UNICODE?看后面代码,又感觉不像。可能只是为了计算地址方便吧。 00401C29 |. 0FBE89 B05340>|movsx ecx, byte ptr [ecx+4053B0] ; 用户名 例子:MOV BL,80H MOVSX AX,BL 此时AX=FF80H。 00401C30 |. 03FE |add edi, esi ; edi+=esi(输入的密码,按位提取); 00401C32 |. 40 |inc eax ; eax自增,应该是为了记录循环次数。 00401C33 |. 3D 000C0000 |cmp eax, 0C00 ; 循环0xc00次,好多次啊。 00401C38 |. 8A0C39 |mov cl, byte ptr [ecx+edi] ; edi+ecx(输入的用户名,按位提取), 00401C3B |. 8888 9F474000 |mov byte ptr [eax+40479F], cl ; 最终是把401178+密码的第N位的ASCII+用户名的第N位ASCII的字节拷贝到40479F开头的地址里。(N每次加1) 00401C41 |.^ 72 D8 \jb short 00401C1B ; 40479F 所指向的就是前面 行00401C14 初始化为0的那一片区域。 00401C43 |. B9 FF000000 mov ecx, 0FF ; ecx=0xFF 00401C48 |. 33C0 xor eax, eax ; eax置0,一般不使用mov eax,0 机器指令为5个,而前者只有2个。 00401C4A |. 8DBD F0FBFFFF lea edi, dword ptr [ebp-410] ; 00401C50 |. C785 ECFBFFFF>mov dword ptr [ebp-414], 0 ; 00401C5A |. F3:AB rep stos dword ptr es:[edi] ; 貌似又是分配缓冲区, 00401C5C |. 83CA FF or edx, FFFFFFFF ; edx=FFFFFFFF 00401C5F |. B9 00010000 mov ecx, 100 ; 00401C64 |> 8D41 FF /lea eax, dword ptr [ecx-1] ;------------------------------------------------------------------------------------ 00401C67 |. 51 |push ecx ;这部分是双重循环的东西 00401C68 |. B9 08000000 |mov ecx, 8 ; for(DWORD i=0x100;i=0;--i) 00401C6D |> D1E8 |/shr eax, 1 ; { 00401C6F |. 73 05 ||jnb short 00401C76 ; for(DWORD j=0;j<8;++j) 00401C71 |. 35 2083B8ED ||xor eax, EDB88320 ; { 00401C76 |> 49 ||dec ecx ; i>>1;//这个操作到底是会生成逻辑右移,还是算术右移,就要看编译器的了。 00401C77 |.^ 75 F4 |\jnz short 00401C6D ; i=i^0xEDB88320 ; 00401C79 |. 59 |pop ecx ; } 00401C7A |. 89848D E8FBFF>|mov dword ptr [ebp+ecx*4-418], eax ; i保存到刚才分配的缓冲区中。 00401C81 |. 49 |dec ecx ; } 00401C82 |.^ 75 E0 \jnz short 00401C64 ;------------------------------------------------------------------------------------ 00401C84 |. 33C0 xor eax, eax ;------------------------------------------------------------------------------------ 00401C86 |> 33C9 /xor ecx, ecx ; eax,ecx清0。edx一开始为FFFFFFFF 00401C88 |. 8BF2 |mov esi, edx ; 00401C8A |. 8A88 A0474000 |mov cl, byte ptr [eax+4047A0] ; 这里是取出密码 00401C90 |. 81E6 FF000000 |and esi, 0FF ; 清esi高24位,只保留低8位。 00401C96 |. 33CE |xor ecx, esi ; esi与ecx只有低8位有数据,做异或运算。赋值给ecx。 00401C98 |. C1EA 08 |shr edx, 8 ; edx右移8位。FFFFFFFF--->00FFFFFF 00401C9B |. 8B8C8D ECFBFF>|mov ecx, dword ptr [ebp+ecx*4-414] ; 取出地址ebp+ecx*4-414 地址中的数据,做为一个新的ecx。 00401CA2 |. 33D1 |xor edx, ecx ; 与edx做异或运算,赋值给edx。 00401CA4 |. 40 |inc eax ; eax自增。 00401CA5 |. 3D 000C0000 |cmp eax, 0C00 ; 循环0xC00次。 00401CAA |.^ 7C DA \jl short 00401C86 ;------------------------------------------------------------------------------------ 00401CAC |. 8BC2 mov eax, edx ; 上面循环结束后,把edx传出,其它的值都是辅助。 00401CAE |. 33D2 xor edx, edx ; 清0 00401CB0 |. F7D0 not eax ; 取反 00401CB2 |. 25 FF000000 and eax, 0FF ; 前16位清0 00401CB7 |. B9 6D000000 mov ecx, 6D ; ecx=0x6D 00401CBC |. F7F1 div ecx ; 除数是edx:eax,被除数是ecx,商是eax,余数是edx。 00401CBE |. C645 EC 00 mov byte ptr [ebp-14], 0 ; 00401CC2 |. 8D4D EC lea ecx, dword ptr [ebp-14] ; 为什么要这样来搞?lea可以来计算复杂表达式。是不是把[ebp-14]清0,取[ebp-14]地址给ecx呢? 00401CC5 |. 8DB2 DE104000 lea esi, dword ptr [edx+4010DE] ; 上次除法余数+4010DE 的地址中数据给esi 00401CCB |. 33D2 xor edx, edx ; 00401CCD |. 8955 ED mov dword ptr [ebp-13], edx ; 栈清0,edx,eax清0。 00401CD0 |. 33C0 xor eax, eax ; 00401CD2 |. 8955 F1 mov dword ptr [ebp-F], edx ; 00401CD5 |. 8955 F5 mov dword ptr [ebp-B], edx ; 00401CD8 |. 8955 F9 mov dword ptr [ebp-7], edx ;------------------------------------------------------------------------------------ 00401CDB |> 8A1406 /mov dl, byte ptr [esi+eax] ; 00401CDE |. 83C0 02 |add eax, 2 ;把esi+eax中的一个字节赋值给ecx所在地址,eax变化0--->2--->4--->..... 00401CE1 |. 8811 |mov byte ptr [ecx], dl ;ecx是自增1。 00401CE3 |. 41 |inc ecx ; 00401CE4 |. 83F8 20 |cmp eax, 20 ; 循环10次, 00401CE7 |.^ 72 F2 \jb short 00401CDB ;------------------------------------------------------------------------------------ 00401CE9 |. B9 FF000000 mov ecx, 0FF ;------------------------------------------------------------------------------------ 00401CEE |. 33C0 xor eax, eax ; 这部分代码与上面00401C43到00401C82代码完全一样。 00401CF0 |. 8DBD F0FBFFFF lea edi, dword ptr [ebp-410] ; 00401CF6 |. C785 ECFBFFFF>mov dword ptr [ebp-414], 0 ; 00401D00 |. F3:AB rep stos dword ptr es:[edi] ; 00401D02 |. 83CA FF or edx, FFFFFFFF ; 00401D05 |. B9 00010000 mov ecx, 100 ; 00401D0A |> 8D41 FF /lea eax, dword ptr [ecx-1] ; 00401D0D |. 51 |push ecx ; 00401D0E |. B9 08000000 |mov ecx, 8 ; 00401D13 |> D1E8 |/shr eax, 1 ; 00401D15 |. 73 05 ||jnb short 00401D1C ; 00401D17 |. 35 2083B8ED ||xor eax, EDB88320 ; 00401D1C |> 49 ||dec ecx ; 00401D1D |.^ 75 F4 |\jnz short 00401D13 ; 00401D1F |. 59 |pop ecx ; 00401D20 |. 89848D E8FBFF>|mov dword ptr [ebp+ecx*4-418], eax ; 00401D27 |. 49 |dec ecx ; 00401D28 |.^ 75 E0 \jnz short 00401D0A ;----------------------------------------------------------------------------------- 00401D2A |. 33C0 xor eax, eax ;----------------------------------------------------------------------------------- 00401D2C |> 33C9 /xor ecx, ecx ;又是一个循环,与00401C84 到 00401CA5 代码相同,只是处理的数据地址不同,循环次数不同。 00401D2E |. 8BFA |mov edi, edx ; 00401D30 |. 8A4C05 EC |mov cl, byte ptr [ebp+eax-14] ; 00401D34 |. 81E7 FF000000 |and edi, 0FF ; 00401D3A |. 33CF |xor ecx, edi ; 00401D3C |. C1EA 08 |shr edx, 8 ; 00401D3F |. 8B8C8D ECFBFF>|mov ecx, dword ptr [ebp+ecx*4-414] ; 00401D46 |. 33D1 |xor edx, ecx ; 00401D48 |. 40 |inc eax ; 00401D49 |. 83F8 10 |cmp eax, 10 ; 00401D4C |.^ 7C DE \jl short 00401D2C ;---------------------------------------------------------------------------------- 00401D4E |. 8B46 20 mov eax, dword ptr [esi+20] ; 00401D51 |. F7D2 not edx ; 00401D53 |. 3BD0 cmp edx, eax ; 00401D55 75 44 jnz short 00401D9B ;这地方是关键跳,爆破的话,虽然不会出现错误提示,但是会出现乱码。 00401D57 |. 8B55 08 mov edx, dword ptr [ebp+8] ;--------------------------------------------------------------------- 00401D5A |. 6A 00 push 0 ; /lParam = NULL 下面都是为CreateWindowExA传入的参数。 00401D5C |. 6A 00 push 0 ; |hInst = NULL 00401D5E |. 6A 00 push 0 ; |hMenu = NULL 00401D60 |. 52 push edx ; |hParent 00401D61 |. 6A 5A push 5A ; |Height = 5A (90.) 00401D63 |. 68 B4000000 push 0B4 ; |Width = B4 (180.) 00401D68 |. 6A 00 push 0 ; |Y = 0 00401D6A |. 6A 00 push 0 ; |X = 0 00401D6C |. 68 0100CF10 push 10CF0001 ; |Style = WS_OVERLAPPED|WS_MINIMIZEBOX|WS_MAXIMIZEBOX|WS_VISIBLE|WS_SYSMENU|WS_THICKFRAME|WS_CAPTION|1 00401D71 |. 68 F8134000 push 004013F8 ; |提示 00401D76 |. 68 F0134000 push 004013F0 ; |static 00401D7B |. 68 00000200 push 20000 ; |ExtStyle = WS_EX_STATICEDGE 00401D80 |. FF15 AC104000 call dword ptr [<&USER32.CreateWindow>; \CreateWindowExA 00401D86 |. 85C0 test eax, eax ; 00401D88 |. 74 27 je short 00401DB1 ; 00401D8A |. 8D4D EC lea ecx, dword ptr [ebp-14] ; 00401D8D |. 51 push ecx ; /Text 为SetWindowTextA传入参数。 00401D8E |. 50 push eax ; |hWnd 00401D8F |. FF15 B0104000 call dword ptr [<&USER32.SetWindowTex>; \SetWindowTextA 00401D95 |. 5F pop edi ; 00401D96 |. 5E pop esi ; 00401D97 |. 8BE5 mov esp, ebp ; 00401D99 |. 5D pop ebp ; 00401D9A |. C3 retn ;--------------------------------------------返回。。 00401D9B |> 8B55 08 mov edx, dword ptr [ebp+8] ; 00401D9E |. 6A 10 push 10 ; /Style = MB_OK|MB_ICONHAND|MB_APPLMODAL 00401DA0 |. 68 E8134000 push 004013E8 ; |错误 00401DA5 |. 68 DC134000 push 004013DC ; |注册失败 00401DAA |. 52 push edx ; |hOwner 00401DAB |. FF15 B4104000 call dword ptr [<&USER32.MessageBoxA>>; \MessageBoxA 00401DB1 |> 5F pop edi ; 00401DB2 |. 5E pop esi ; 00401DB3 |. 8BE5 mov esp, ebp ; 00401DB5 |. 5D pop ebp ; 00401DB6 \. C3 retn ;