小日本的一款16进制编辑器 AXE v3.41 的注册算法简单分析
Homepage:http://www.axe-editor.com/
Download:
Installer AXE 3.4.1http://www.axe-editor.com/downloads/installAXE.exe
一款感觉还不错的hex编辑器,分析了下,简单写出来。
下断点: BP GetWindowTextA后,打开注册窗口,输入注册名:aCaFeeL,输入注册码:12345678,点击OK按钮,被中断下来,ALT+F9建后,回到AXE的领空:
>>>>>>
004B56E2 /$ 56 push esi
004B56E3 |. 8BF1 mov esi, ecx
004B56E5 |. 8B4E 38 mov ecx, dword ptr [esi+38]
004B56E8 |. 85C9 test ecx, ecx
004B56EA |. 75 2E jnz short AXE.004B571A
004B56EC |. FF76 1C push dword ptr [esi+1C] ; /hWnd
004B56EF |. FF15 C0664E00 call dword ptr [<&USER32.GetWindowTex>; \GetWindowTextLengthA
004B56F5 |. 8D48 01 lea ecx, dword ptr [eax+1]
004B56F8 |. 51 push ecx
004B56F9 |. 8B4C24 0C mov ecx, dword ptr [esp+C]
004B56FD |. 50 push eax
004B56FE |. E8 05E6FFFF call AXE.004B3D08
004B5703 |. 50 push eax ; |Buffer
004B5704 |. FF76 1C push dword ptr [esi+1C] ; |hWnd
004B5707 |. FF15 A0654E00 call dword ptr [<&USER32.GetWindowTex>; \GetWindowTextA
004B570D |. 8B4C24 08 mov ecx, dword ptr [esp+8] ; 回到了这里!!!!!!
004B5711 |. 6A FF push -1
004B5713 |. E8 C8E5FFFF call AXE.004B3CE0
004B5718 |. EB 0C jmp short AXE.004B5726
004B571A |> 8B01 mov eax, dword ptr [ecx]
004B571C |. FF7424 08 push dword ptr [esp+8]
004B5720 |. FF90 88000000 call dword ptr [eax+88]
004B5726 |> 5E pop esi
004B5727 \. C2 0400 retn 4 ; 走完这个子Call
>>>>>> 走完上面的子程序后,来到了这里:
>>>>>>
0043F547 . E8 96610700 call AXE.004B56E2 ; 这就是上面的子call
0043F54C . 8D4C24 14 lea ecx, dword ptr [esp+14] ; 走完后,来到了这里:
0043F550 . 51 push ecx
0043F551 . 68 29040000 push 429
0043F556 . 8BCE mov ecx, esi
0043F558 . E8 75860700 call AXE.004B7BD2
0043F55D . 8BC8 mov ecx, eax
0043F55F . E8 7E610700 call AXE.004B56E2
0043F564 . 8B5424 14 mov edx, dword ptr [esp+14] ; 注册名 -> edx
0043F568 . 68 044D5100 push AXE.00514D04 ; notfound
0043F56D . 52 push edx ; 压
0043F56E . E8 1DF00400 call AXE.0048E590
0043F573 . 83C4 08 add esp, 8
0043F576 . 3BC3 cmp eax, ebx
0043F578 75 0C jnz short AXE.0043F586
0043F57A . 53 push ebx ; /Arg3
0043F57B . 53 push ebx ; |Arg2
0043F57C . 68 F04C5100 push AXE.00514CF0 ; |no matches found.
0043F581 . E8 0D020800 call AXE.004BF793 ; \AXE.004BF793
0043F586 > 8B4424 18 mov eax, dword ptr [esp+18] ; 注册码 -> eax
0043F58A . 8D7E 5C lea edi, dword ptr [esi+5C]
0043F58D . 57 push edi
0043F58E . 68 58245100 push AXE.00512458 ; %lu
0043F593 . 50 push eax
0043F594 . E8 26CB0400 call AXE.0048C0BF
0043F599 . 83C4 0C add esp, 0C
0043F59C . 8D4C24 14 lea ecx, dword ptr [esp+14]
0043F5A0 . 8D6E 60 lea ebp, dword ptr [esi+60]
0043F5A3 . 51 push ecx
0043F5A4 . 8BCD mov ecx, ebp
0043F5A6 . E8 EF430700 call AXE.004B399A
0043F5AB . 51 push ecx
0043F5AC . 8BCC mov ecx, esp
0043F5AE . 896424 14 mov dword ptr [esp+14], esp
0043F5B2 . 55 push ebp
0043F5B3 . E8 1E400700 call AXE.004B35D6
0043F5B8 . 8B17 mov edx, dword ptr [edi]
0043F5BA . C64424 6C 01 mov byte ptr [esp+6C], 1
0043F5BF . 52 push edx
0043F5C0 . 53 push ebx
0043F5C1 . E8 BA24FEFF call AXE.00421A80
0043F5C6 . 8BC8 mov ecx, eax
0043F5C8 . E8 5300FFFF call AXE.0042F620 ; 算法::F7进入,注册正确的话,eax<>0
0043F5CD . 3BC3 cmp eax, ebx ; eax = $00(ebx) ?
0043F5CF 0F84 26030000 je AXE.0043F8FB ; //不跳
0043F5D5 . A0 644B5100 mov al, byte ptr [514B64]
0043F5DA . 8A0D 684B5100 mov cl, byte ptr [514B68]
0043F5E0 . 8A15 6C4B5100 mov dl, byte ptr [514B6C]
0043F5E6 . 34 AA xor al, 0AA
0043F5E8 . 80F1 55 xor cl, 55
0043F5EB . 884424 24 mov byte ptr [esp+24], al
0043F5EF . A0 704B5100 mov al, byte ptr [514B70]
0043F5F4 . 884C24 25 mov byte ptr [esp+25], cl
0043F5F8 . 8A0D 744B5100 mov cl, byte ptr [514B74]
0043F5FE . 80F2 66 xor dl, 66
0043F601 . 34 CC xor al, 0CC
0043F603 . 80F1 77 xor cl, 77
0043F606 . 885424 26 mov byte ptr [esp+26], dl
>>>>>> 毫无疑问,注册成功与否,便是看 0043F5CD 这里的eax是否为0了,不为0才注册成功,要分析算法,自然要进入0043F5C8地址的
0043F5C8 . E8 5300FFFF call AXE.0042F620
这里了,走到这里时,按F7建进入后:
>>>>>>
0042F620 /$ 64:A1 0000000>mov eax, dword ptr fs:[0] ; 来到这里
0042F626 |. 6A FF push -1
0042F628 |. 68 48AE4D00 push AXE.004DAE48
0042F62D |. 50 push eax
0042F62E |. 64:8925 00000>mov dword ptr fs:[0], esp
0042F635 |. 53 push ebx
0042F636 |. 56 push esi ; esi := $0012FB28;
0042F637 |. 57 push edi
0042F638 |. 8B4424 24 mov eax, dword ptr [esp+24] ; 注册名 -> eax
0042F63C |. C74424 14 000>mov dword ptr [esp+14], 0
0042F644 |. 8B48 F8 mov ecx, dword ptr [eax-8] ; 注册名长度 -> ecx
0042F647 |. 85C9 test ecx, ecx ; ecx and ecx = 0 ?
0042F649 |. 0F84 BF000000 je AXE.0042F70E ; 注册名长度为0的话,跳
0042F64F |. 8B7424 20 mov esi, dword ptr [esp+20] ; 这里注意: esi := 注册码的16进制;
0042F653 |. 85F6 test esi, esi ; ecx 0 ?
0042F655 |. 0F84 B3000000 je AXE.0042F70E ; <>0
0042F65B |. 81FE 25270000 cmp esi, 2725 ; esi <> $2725 ?
0042F661 |. 75 2A jnz short AXE.0042F68D ; 不等,肯定跳!
0042F663 |. 8D4C24 24 lea ecx, dword ptr [esp+24]
0042F667 |. C74424 14 FFF>mov dword ptr [esp+14], -1
0042F66F |. E8 ED410800 call AXE.004B3861
0042F674 |. B8 01000000 mov eax, 1 ; 这里说明,等于$2725,注册成功
0042F679 |. 8B4C24 0C mov ecx, dword ptr [esp+C]
0042F67D |. 64:890D 00000>mov dword ptr fs:[0], ecx
0042F684 |. 5F pop edi
0042F685 |. 5E pop esi
0042F686 |. 5B pop ebx
0042F687 |. 83C4 0C add esp, 0C
0042F68A |. C2 0C00 retn 0C
0042F68D |> 83F9 04 cmp ecx, 4 ; 注册名长度大于4 ?
0042F690 |. 7D 12 jge short AXE.0042F6A4 ; 大于等于4,跳
0042F692 |. 68 2C415100 push AXE.0051412C ; abcd
0042F697 |. 8D4C24 28 lea ecx, dword ptr [esp+28]
0042F69B |. E8 9D450800 call AXE.004B3C3D
0042F6A0 |. 8B4424 24 mov eax, dword ptr [esp+24] ; 注册名长度小于4,则注册名+'abcd' -> eax
0042F6A4 |> 8B48 F8 mov ecx, dword ptr [eax-8] ; 注册名长度 -> ecx
0042F6A7 |. 8A58 02 mov bl, byte ptr [eax+2] ; 取注册名的第3位字符码 -> bl(ebx低位)
0042F6AA |. 8A10 mov dl, byte ptr [eax] ; 取注册名的第1位字符码 -> dl(edx低位)
0042F6AC |. 0FBE4401 FF movsx eax, byte ptr [ecx+eax-1] ; 取注册名的最后位字符码 -> eax
0042F6B1 |. 0FBEFB movsx edi, bl ; edi = bl;
0042F6B4 |. 0FBED2 movsx edx, dl ; edx = dl;
0042F6B7 |. 03C7 add eax, edi ; eax := eax + edi;
0042F6B9 |. 03C2 add eax, edx ; eax := eax + edx;
0042F6BB |. 0FAFC1 imul eax, ecx ; eax := eax * ecx;
0042F6BE |. 25 FFFFFF8F and eax, 8FFFFFFF ; eax := eax and $8FFFFFFF;
0042F6C3 |. 79 07 jns short AXE.0042F6CC ; 为0? 跳!
0042F6C5 |. 48 dec eax
0042F6C6 |. 0D 000000F0 or eax, F0000000
0042F6CB |. 40 inc eax
0042F6CC |> 81FE 00000010 cmp esi, 10000000 ; esi 比较 $10000000
0042F6D2 |. 76 05 jbe short AXE.0042F6D9 ; 小于或等于,跳
0042F6D4 |. 05 00000010 add eax, 10000000 ; 大于: eax:= eax + $10000000;
0042F6D9 |> 35 D7139A03 xor eax, 39A13D7 ; eax := eax xor $39A13D7
0042F6DE |. 33C9 xor ecx, ecx ; ecx 清零 ecx := 0;
0042F6E0 |. 3BF0 cmp esi, eax ; esi 比较 eax,『『这里相等便OK』』
0042F6E2 |. C74424 14 FFF>mov dword ptr [esp+14], -1
0042F6EA |. 0F94C1 sete cl ; cl 设置1
0042F6ED |. 8BF1 mov esi, ecx ; 注意: esi := ecx;
0042F6EF |. 8D4C24 24 lea ecx, dword ptr [esp+24]
0042F6F3 |. E8 69410800 call AXE.004B3861
0042F6F8 |. 8BC6 mov eax, esi ; eax := esi; //最终结果
0042F6FA |. 8B4C24 0C mov ecx, dword ptr [esp+C]
0042F6FE |. 64:890D 00000>mov dword ptr fs:[0], ecx
0042F705 |. 5F pop edi
0042F706 |. 5E pop esi
0042F707 |. 5B pop ebx
0042F708 |. 83C4 0C add esp, 0C
0042F70B |. C2 0C00 retn 0C
0042F70E |> 8D4C24 24 lea ecx, dword ptr [esp+24]
0042F712 |. C74424 14 FFF>mov dword ptr [esp+14], -1
0042F71A |. E8 42410800 call AXE.004B3861
0042F71F |. 8B4C24 0C mov ecx, dword ptr [esp+C]
0042F723 |. 5F pop edi
0042F724 |. 5E pop esi
0042F725 |. 33C0 xor eax, eax
0042F727 |. 64:890D 00000>mov dword ptr fs:[0], ecx
0042F72E |. 5B pop ebx
0042F72F |. 83C4 0C add esp, 0C
0042F732 \. C2 0C00 retn 0C
>>>>>> 通过上面的分析,我们知道了其注册算法为:读入注册名和注册码,先将注册码转换为16进制数,放入esi中;然后读入注册名,取注册名的第3位字符,放入edi中,第1位字符放入edx中,注册名的最后位字符放入eax中,然后将这三个字符码相加,结果再与$8FFFFFFF做and运算,得到的结果再异或
$39A13D7后得到最终结果,放入eax中。用这个结果比较esi中的注册码,相等,就注册成功了! 放上一组可用的Key:
注册名: aCaFeeL
注册码: 60429493 注册机的算法在多台机器上使用不同注册名通过验证,但没有时间再优化它了,应该不存在bug的问题,附件中为我打包后的注册机源代码。
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
上传的附件: