前言:原文再续书接上一回(很高兴拿到邀请码了,顺便掘坟),上回说到注册机--
================================================================
菜鸟学破解:1.Feiq等级设置(续): 找出Feiq授权码生成的算法
我的方法比较原始:跟踪函数,通过搜索内存找出授权码字符串是在哪个call之后才出现的;转向跟踪那个call的子函数,重复之前的方法不断层层进入,找到生成授权码的最深层子函数。
在feiq中,由于等级设置窗口有计算机标识码字符串,我猜想授权码是通过它来生成的,理想情况下,那个最深层子函数就是对计算机标识码字符串直接作一些例如加减乘除与或异或移位等运算,然后生成授权码。可惜,事实没有那么简单,授权码的计算并非“一步”完成。
因此,我的主要思路是:回溯,授权码可能由中间量A生成,通过分析算法找出A,而A可能由中间量B和C生成,B可能由中间量D、E等和一些已知量(例如计算机标识码,程序里的常量等)生成,这样一步一步追根溯源,逆流而上,最终找出所有已知量,综合当中由已知量生成未知量的算法就得到生成授权码的算法。
用OD载入Feiq,进入之前爆破所在的函数00463480,找到之前分析确认是传入计算机标识码生成授权码的函数004938D0,通过边搜索内存边步进,在call 00568C0E之后出现了授权码,如果忽略大小写,在call 00493B60之后会出现大小写混杂的“授权码”。用IDA分析,00568C0E正是CStrng::MackUpper。
//函数004938D0(GenLv1_MacID_RegCode)
004938D0 /$ 6A FF push -1
004938D2 |. 68 299E5800 push 00589E29 ; SE 处理程序安装
004938D7 |. 64:A1 0000000>mov eax, dword ptr fs:[0]
;;;;;;;;;;;;;;;;;;;;;;;;省略部分;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
0049391E |. 8D4424 24 lea eax, dword ptr [esp+24]
00493922 |. 50 push eax
00493923 |. E8 38020000 call 00493B60 ; JASS: 生成字串JOLG...
;;;;;;;;;;;;;;;;;;;;;;;;省略部分;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
00493954 |. 55 push ebp
00493955 |. 8BD1 mov edx, ecx
00493957 |. 8BF7 mov esi, edi
00493959 |. 8BFB mov edi, ebx
0049395B |. 53 push ebx
0049395C |. C1E9 02 shr ecx, 2
0049395F |. F3:A5 rep movs dword ptr es:[edi], dword p>
00493961 |. 8BCA mov ecx, edx
00493963 |. 83E1 03 and ecx, 3
00493966 |. F3:A4 rep movs byte ptr es:[edi], byte ptr>
00493968 |. 8D4C24 30 lea ecx, dword ptr [esp+30]
0049396C |. E8 1F11F7FF call 00404A90 ; JASS: 生成4055c0用到的参考数组S
00493971 |. 8B8424 440800>mov eax, dword ptr [esp+844]
00493978 |. C68424 380800>mov byte ptr [esp+838], 3
00493980 |. 8B68 F8 mov ebp, dword ptr [eax-8]
;;;;;;;;;;;;;;;;;;;;;;;;省略部分;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
00493A01 |. 6A 22 push 22
00493A03 |. 8D8424 3C0400>lea eax, dword ptr [esp+43C]
00493A0A |. 55 push ebp
00493A0B |. 8D4C24 40 lea ecx, dword ptr [esp+40]
00493A0F |. 50 push eax
00493A10 |. 51 push ecx
00493A11 |. 8D4C24 40 lea ecx, dword ptr [esp+40]
00493A15 |. E8 A61BF7FF call 004055C0 ; JASS: 传入机器标识码,生成产生数字串"xxx"的二进制串的函数
00493A1A |. 8B15 889F5F00 mov edx, dword ptr [5F9F88] ; 飞秋FeiQ.005F9F9C
00493A20 |. 8BF8 mov edi, eax
00493A22 |. 895424 18 mov dword ptr [esp+18], edx
00493A26 |. 33F6 xor esi, esi
00493A28 |. C68424 380800>mov byte ptr [esp+838], 4
00493A30 |. 85FF test edi, edi
00493A32 |. 7E 51 jle short 00493A85
00493A34 |> A1 889F5F00 /mov eax, dword ptr [5F9F88]
00493A39 |. 894424 10 |mov dword ptr [esp+10], eax
00493A3D |. 33C9 |xor ecx, ecx
00493A3F |. 8D5424 10 |lea edx, dword ptr [esp+10]
00493A43 |. 8A8C34 300400>|mov cl, byte ptr [esp+esi+430]
00493A4A |. C68424 380800>|mov byte ptr [esp+838], 5
00493A52 |. 51 |push ecx
00493A53 |. 68 88FD5E00 |push 005EFD88 ; ASCII "%u"
00493A58 |. 52 |push edx
00493A59 |. E8 56040D00 |call 00563EB4 ; JASS: 类似sprintf函数
00493A5E |. 83C4 0C |add esp, 0C
00493A61 |. 8D4424 10 |lea eax, dword ptr [esp+10]
00493A65 |. 8D4C24 18 |lea ecx, dword ptr [esp+18]
00493A69 |. 50 |push eax
00493A6A |. E8 B5500D00 |call 00568B24 ; JASS: 类似CString::operator+=
00493A6F |. 8D4C24 10 |lea ecx, dword ptr [esp+10]
00493A73 |. C68424 380800>|mov byte ptr [esp+838], 4
00493A7B |. E8 8C4C0D00 |call 0056870C
00493A80 |. 46 |inc esi
00493A81 |. 3BF7 |cmp esi, edi
00493A83 |.^ 7C AF \jl short 00493A34
00493A85 |> 8B8C24 480800>mov ecx, dword ptr [esp+848] ; JASS:数字串"xxx"已生成
00493A8C |. 8D5424 18 lea edx, dword ptr [esp+18]
00493A90 |. 51 push ecx
00493A91 |. 51 push ecx
00493A92 |. 8BCC mov ecx, esp
00493A94 |. 896424 18 mov dword ptr [esp+18], esp
00493A98 |. 52 push edx
00493A99 |. E8 E3490D00 call 00568481
00493A9E |. 8D4424 1C lea eax, dword ptr [esp+1C]
00493AA2 |. 50 push eax
00493AA3 |. E8 B8000000 call 00493B60 ; JASS:生成lmto.....
00493AA8 |. 53 push ebx
00493AA9 |. C68424 480800>mov byte ptr [esp+848], 6
00493AB1 |. E8 76400D00 call 00567B2C
00493AB6 |. 8B4C24 30 mov ecx, dword ptr [esp+30]
00493ABA |. 51 push ecx
00493ABB |. E8 6C400D00 call 00567B2C
00493AC0 |. 83C4 14 add esp, 14
00493AC3 |. 8D4C24 14 lea ecx, dword ptr [esp+14]
00493AC7 |. E8 42510D00 call 00568C0E ; JASS:CString::MakeUpper 生成LMTO.....
00493ACC |. 8BB424 400800>mov esi, dword ptr [esp+840]
00493AD3 |. 8D5424 14 lea edx, dword ptr [esp+14]
00493AD7 |. 52 push edx
00493AD8 |. 8BCE mov ecx, esi
00493ADA |. E8 A2490D00 call 00568481
;;;;;;;;;;;;;;;;;;;;;;;;省略部分;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
00493B59 \. C3 retn 进入函数00493B60,会看到有5个循环。第一个循环里充满令人发昏的浮点运算;第二、三、四个循环很相似,而且分别循环5次;第五个循环里有和数字、大小写字母比较的判断。跟踪分析得,一串很长的数字ASCII码串经过第一循环得到了三个32位数,第二、三、四循环分别用这三个数生成了一个15byte的数组,这个数组经过第五循环的变换得到了15个字符的大小写混杂的“授权码”。
//函数00493B60(GenLv2_NumStr_RegCodeCI)
00493B60 /$ 6A FF push -1
00493B62 |. 68 679E5800 push 00589E67 ; SE 处理程序安装
00493B67 |. 64:A1 0000000>mov eax, dword ptr fs:[0]
;;;;;;;;;;;;;;;;;;;;;;;;省略部分;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
00493BDF |. 8B7C24 58 mov edi, dword ptr [esp+58]
00493BE3 |> 8B4424 54 /mov eax, dword ptr [esp+54] ; JASS: 由字串"xxxx"生成一整数
00493BE7 |. 0FAFD5 |imul edx, ebp
00493BEA |. DB4424 18 |fild dword ptr [esp+18]
00493BEE |. DD5C24 18 |fstp qword ptr [esp+18]
00493BF2 |. 8A5C30 FF |mov bl, byte ptr [eax+esi-1]
00493BF6 |. 0FAF5424 10 |imul edx, dword ptr [esp+10]
00493BFB |. 0FBECB |movsx ecx, bl
00493BFE |. 0FAFD7 |imul edx, edi
00493C01 |. 894C24 58 |mov dword ptr [esp+58], ecx
00493C05 |. DB4424 58 |fild dword ptr [esp+58]
00493C09 |. 0FBEC3 |movsx eax, bl
00493C0C |. D9FA |fsqrt
00493C0E |. 0FAFC6 |imul eax, esi
00493C11 |. DC4C24 18 |fmul qword ptr [esp+18]
00493C15 |. DC05 B89A5900 |fadd qword ptr [599AB8]
00493C1B |. 0FAFC6 |imul eax, esi
00493C1E |. 894424 58 |mov dword ptr [esp+58], eax
00493C22 |. DB4424 58 |fild dword ptr [esp+58]
00493C26 |. 895424 58 |mov dword ptr [esp+58], edx
00493C2A |. DEC9 |fmulp st(1), st
00493C2C |. DB4424 58 |fild dword ptr [esp+58]
00493C30 |. DEC1 |faddp st(1), st
00493C32 |. E8 75CD0B00 |call 005509AC ; JASS: _ftol浮点转长整数:arg ST0--return eax
00493C37 |. 99 |cdq
00493C38 |. B9 A0860100 |mov ecx, 186A0
00493C3D |. F7F9 |idiv ecx
00493C3F |. 895424 10 |mov dword ptr [esp+10], edx ; JASS-DEBUG: edx - IterValA
00493C43 |. DB4424 10 |fild dword ptr [esp+10]
00493C47 |. 0FBED3 |movsx edx, bl
00493C4A |. DD5C24 28 |fstp qword ptr [esp+28]
00493C4E |. 895424 58 |mov dword ptr [esp+58], edx
00493C52 |. DB4424 58 |fild dword ptr [esp+58]
00493C56 |. DD05 F8BA5900 |fld qword ptr [59BAF8]
00493C5C |. E8 3FE20B00 |call 00551EA0 ; JASS: _CIpow
00493C61 |. DC4C24 18 |fmul qword ptr [esp+18]
00493C65 |. E8 42CD0B00 |call 005509AC
00493C6A |. DD4424 28 |fld qword ptr [esp+28]
00493C6E |. D9FE |fsin
00493C70 |. 8BD8 |mov ebx, eax
00493C72 |. E8 35CD0B00 |call 005509AC
00493C77 |. DD4424 28 |fld qword ptr [esp+28]
00493C7B |. 03D8 |add ebx, eax
00493C7D |. 8BC6 |mov eax, esi
00493C7F |. 0FAFC5 |imul eax, ebp
00493C82 |. D9FA |fsqrt
00493C84 |. B9 A0860100 |mov ecx, 186A0
00493C89 |. 0FAFC7 |imul eax, edi
00493C8C |. 03C3 |add eax, ebx
00493C8E |. 99 |cdq
00493C8F |. F7F9 |idiv ecx
00493C91 |. 8BEA |mov ebp, edx ; JASS-DEBUG: ebp - IterValB
00493C93 |. E8 14CD0B00 |call 005509AC
00493C98 |. 8BD5 |mov edx, ebp
00493C9A |. 8B4C24 10 |mov ecx, dword ptr [esp+10]
00493C9E |. 0FAFD5 |imul edx, ebp
00493CA1 |. 03D1 |add edx, ecx
00493CA3 |. B9 A0860100 |mov ecx, 186A0
00493CA8 |. 0FAFD6 |imul edx, esi
00493CAB |. 0FAFD6 |imul edx, esi
00493CAE |. 0FAFD7 |imul edx, edi
00493CB1 |. 03C2 |add eax, edx
00493CB3 |. 99 |cdq
00493CB4 |. F7F9 |idiv ecx ; JASS-DEBUG: edx - IterValC (除法之后)
00493CB6 |. 8B4424 20 |mov eax, dword ptr [esp+20]
00493CBA |. 46 |inc esi
00493CBB |. 3BF0 |cmp esi, eax
00493CBD |. 897424 18 |mov dword ptr [esp+18], esi
00493CC1 |.^ 0F8E 1CFFFFFF \jle 00493BE3
00493CC7 |. 8B5C24 10 mov ebx, dword ptr [esp+10] ; JASS: 生成的整数:dword ptr [esp+10],ebp,edx
00493CCB |> 33C0 xor eax, eax
00493CCD |> 8BC8 /mov ecx, eax
00493CCF |. 0FAFC8 |imul ecx, eax
00493CD2 |. 0FAFC8 |imul ecx, eax
00493CD5 |. 8D4C19 1F |lea ecx, dword ptr [ecx+ebx+1F]
00493CD9 |. 81E1 7F000080 |and ecx, 8000007F
00493CDF |. 79 05 |jns short 00493CE6
00493CE1 |. 49 |dec ecx
00493CE2 |. 83C9 80 |or ecx, FFFFFF80
00493CE5 |. 41 |inc ecx
00493CE6 |> 884C04 30 |mov byte ptr [esp+eax+30], cl
00493CEA |. 40 |inc eax
00493CEB |. 83F8 05 |cmp eax, 5
00493CEE |.^ 7C DD \jl short 00493CCD
00493CF0 |. B8 05000000 mov eax, 5
00493CF5 |> 8BC8 /mov ecx, eax
00493CF7 |. 0FAFC8 |imul ecx, eax
00493CFA |. 0FAFC8 |imul ecx, eax
00493CFD |. 8D4C29 1F |lea ecx, dword ptr [ecx+ebp+1F]
00493D01 |. 81E1 7F000080 |and ecx, 8000007F
00493D07 |. 79 05 |jns short 00493D0E
00493D09 |. 49 |dec ecx
00493D0A |. 83C9 80 |or ecx, FFFFFF80
00493D0D |. 41 |inc ecx
00493D0E |> 884C04 30 |mov byte ptr [esp+eax+30], cl
00493D12 |. 40 |inc eax
00493D13 |. 83F8 0A |cmp eax, 0A
00493D16 |.^ 7C DD \jl short 00493CF5
00493D18 |. B8 0A000000 mov eax, 0A
00493D1D |> 8BC8 /mov ecx, eax
00493D1F |. 0FAFC8 |imul ecx, eax
00493D22 |. 0FAFC8 |imul ecx, eax
00493D25 |. 8D4C11 1F |lea ecx, dword ptr [ecx+edx+1F]
00493D29 |. 81E1 7F000080 |and ecx, 8000007F
00493D2F |. 79 05 |jns short 00493D36
00493D31 |. 49 |dec ecx
00493D32 |. 83C9 80 |or ecx, FFFFFF80
00493D35 |. 41 |inc ecx
00493D36 |> 884C04 30 |mov byte ptr [esp+eax+30], cl
00493D3A |. 40 |inc eax
00493D3B |. 83F8 0F |cmp eax, 0F
00493D3E |.^ 7C DD \jl short 00493D1D
00493D40 |. 33D2 xor edx, edx
00493D42 |. C64424 3F 00 mov byte ptr [esp+3F], 0
00493D47 |. 33C9 xor ecx, ecx
00493D49 |> 8A4414 30 /mov al, byte ptr [esp+edx+30]
00493D4D |. 3C 30 |cmp al, 30
00493D4F |. 7C 04 |jl short 00493D55
00493D51 |. 3C 39 |cmp al, 39
00493D53 |. 7E 29 |jle short 00493D7E
00493D55 |> 3C 41 |cmp al, 41
00493D57 |. 7C 04 |jl short 00493D5D
00493D59 |. 3C 5A |cmp al, 5A
00493D5B |. 7E 21 |jle short 00493D7E
00493D5D |> 3C 61 |cmp al, 61
00493D5F |. 7C 04 |jl short 00493D65
00493D61 |. 3C 7A |cmp al, 7A
00493D63 |. 7E 19 |jle short 00493D7E
00493D65 |> 0FBEC0 |movsx eax, al
00493D68 |. 8D4408 1F |lea eax, dword ptr [eax+ecx+1F]
00493D6C |. 25 7F000080 |and eax, 8000007F
00493D71 |. 79 05 |jns short 00493D78
00493D73 |. 48 |dec eax
00493D74 |. 83C8 80 |or eax, FFFFFF80
00493D77 |. 40 |inc eax
00493D78 |> 884414 30 |mov byte ptr [esp+edx+30], al
00493D7C |.^ EB CB |jmp short 00493D49
00493D7E |> 83C1 07 |add ecx, 7
00493D81 |. 42 |inc edx
00493D82 |. 83F9 69 |cmp ecx, 69
00493D85 |.^ 7C C2 \jl short 00493D49
00493D87 |. 8D4C24 30 lea ecx, dword ptr [esp+30]
00493D8B |. 8D5424 14 lea edx, dword ptr [esp+14]
;;;;;;;;;;;;;;;;;;;;;;;;省略部分;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
00493DE6 \. C3 retn 返回跟踪函数004938D0(GenLv1_MacID_RegCode),同样通过搜索内存,找到很长的数字串是在中间一个循环之后(00493A85)生成的,这个循环里有sprintf和CString::+=的调用;跟踪发现此循环的作用是把一个24byte的数组的每个byte的十进制表示连接在一起,生成长数字串。
搜索那个24byte的数组,是在call 004055C0后生成的。进入分析这个函数004055C0,此函数调用前push的其中一个参数正是已知的计算机标识码。函数里有个大循环,循环里有一处函数调用。经过跟踪,在执行循环之前,15byte的计算机标识码加结束符\0共16byte被扩展成24byte的数组。循环每次对8个byte进行处理,结果覆盖该24byte数组并对下8byte处理有所影响。
//函数004055C0(GenLv2_MacID_24ByteArray)
004055C0 /$ 51 push ecx
004055C1 |. 53 push ebx
004055C2 |. 8B5C24 14 mov ebx, dword ptr [esp+14]
004055C6 |. 55 push ebp
004055C7 |. 56 push esi
004055C8 |. 8B7424 14 mov esi, dword ptr [esp+14]
004055CC |. 57 push edi
004055CD |. 8B7C24 1C mov edi, dword ptr [esp+1C]
004055D1 |. 8BC1 mov eax, ecx
004055D3 |. 3BF7 cmp esi, edi
004055D5 |. 894424 10 mov dword ptr [esp+10], eax
004055D9 |. 74 10 je short 004055EB
004055DB |. 8BCB mov ecx, ebx
004055DD |. 8BD1 mov edx, ecx
004055DF |. C1E9 02 shr ecx, 2
004055E2 |. F3:A5 rep movs dword ptr es:[edi], dword p>
004055E4 |. 8BCA mov ecx, edx
004055E6 |. 83E1 03 and ecx, 3
004055E9 |. F3:A4 rep movs byte ptr es:[edi], byte ptr>
004055EB |> 8B4C24 24 mov ecx, dword ptr [esp+24]
004055EF |. 51 push ecx
004055F0 |. 53 push ebx
004055F1 |. 8BC8 mov ecx, eax
004055F3 |. E8 A8FFFFFF call 004055A0
004055F8 |. 8BE8 mov ebp, eax
004055FA |. 8A4424 24 mov al, byte ptr [esp+24]
004055FE |. A8 20 test al, 20
00405600 |. 74 06 je short 00405608
00405602 |. 8BC5 mov eax, ebp
00405604 |. 2BC3 sub eax, ebx
00405606 |. EB 02 jmp short 0040560A
00405608 |> 33C0 xor eax, eax
0040560A |> 8B7424 1C mov esi, dword ptr [esp+1C]
0040560E |. 8BCD mov ecx, ebp
00405610 |. 2BCB sub ecx, ebx
00405612 |. 8D3C1E lea edi, dword ptr [esi+ebx]
00405615 |. 8AD8 mov bl, al
00405617 |. 8AFB mov bh, bl
00405619 |. 8BD1 mov edx, ecx
0040561B |. 8BC3 mov eax, ebx
0040561D |. C1E0 10 shl eax, 10
00405620 |. 66:8BC3 mov ax, bx
00405623 |. C1E9 02 shr ecx, 2
00405626 |. F3:AB rep stos dword ptr es:[edi]
00405628 |. 8BCA mov ecx, edx
0040562A |. 83E1 03 and ecx, 3
0040562D |. F3:AA rep stos byte ptr es:[edi]
0040562F |. 33C0 xor eax, eax
00405631 |. 85ED test ebp, ebp
00405633 |. 0F86 D8000000 jbe 00405711
00405639 |. 8B4424 24 mov eax, dword ptr [esp+24]
0040563D |. 83C5 07 add ebp, 7
00405640 |. 83E0 02 and eax, 2
00405643 |. 83C6 06 add esi, 6
00405646 |. C1ED 03 shr ebp, 3
00405649 |. 894424 1C mov dword ptr [esp+1C], eax
0040564D |. 8D0CED 000000>lea ecx, dword ptr [ebp*8]
00405654 |. 894C24 18 mov dword ptr [esp+18], ecx
00405658 |. EB 04 jmp short 0040565E
0040565A |> 8B4424 1C /mov eax, dword ptr [esp+1C]
0040565E |> 85C0 test eax, eax
00405660 |. 74 18 |je short 0040567A
00405662 |. 8B5424 28 |mov edx, dword ptr [esp+28]
00405666 |. 8B7E FA |mov edi, dword ptr [esi-6]
00405669 |. 8B4424 2C |mov eax, dword ptr [esp+2C]
0040566D |. 33FA |xor edi, edx
0040566F |. 897E FA |mov dword ptr [esi-6], edi
00405672 |. 8B4E FE |mov ecx, dword ptr [esi-2]
00405675 |. 33C8 |xor ecx, eax
00405677 |. 894E FE |mov dword ptr [esi-2], ecx
0040567A |> 8B46 FA |mov eax, dword ptr [esi-6]
0040567D |. 8D7E FA |lea edi, dword ptr [esi-6]
00405680 |. 894424 24 |mov dword ptr [esp+24], eax ; JASS: 32bit交换高低位
00405684 |. 8D5E FE |lea ebx, dword ptr [esi-2]
00405687 |. 8A4C24 26 |mov cl, byte ptr [esp+26]
0040568B |. 8A5424 27 |mov dl, byte ptr [esp+27]
0040568F |. 8846 FD |mov byte ptr [esi-3], al
00405692 |. 8866 FC |mov byte ptr [esi-4], ah
00405695 |. 884E FB |mov byte ptr [esi-5], cl
00405698 |. 8817 |mov byte ptr [edi], dl
0040569A |. 8B03 |mov eax, dword ptr [ebx]
0040569C |. 53 |push ebx
0040569D |. 894424 28 |mov dword ptr [esp+28], eax
004056A1 |. 8846 01 |mov byte ptr [esi+1], al
004056A4 |. 8A4C24 2B |mov cl, byte ptr [esp+2B]
004056A8 |. 8A4424 2A |mov al, byte ptr [esp+2A]
004056AC |. 880B |mov byte ptr [ebx], cl
004056AE |. 8B4C24 14 |mov ecx, dword ptr [esp+14]
004056B2 |. 57 |push edi
004056B3 |. 8826 |mov byte ptr [esi], ah
004056B5 |. 8846 FF |mov byte ptr [esi-1], al
004056B8 |. E8 33F4FFFF |call 00404AF0 ; JASS:把8字节“字符串”转换成二进制串
004056BD |. 8B07 |mov eax, dword ptr [edi]
004056BF |. 894424 24 |mov dword ptr [esp+24], eax
004056C3 |. 8846 FD |mov byte ptr [esi-3], al
004056C6 |. 8A5424 26 |mov dl, byte ptr [esp+26]
004056CA |. 8A4424 27 |mov al, byte ptr [esp+27]
004056CE |. 8866 FC |mov byte ptr [esi-4], ah
004056D1 |. 8856 FB |mov byte ptr [esi-5], dl
004056D4 |. 8807 |mov byte ptr [edi], al
004056D6 |. 8B03 |mov eax, dword ptr [ebx]
004056D8 |. 894424 24 |mov dword ptr [esp+24], eax
004056DC |. 8846 01 |mov byte ptr [esi+1], al
004056DF |. 8A4C24 26 |mov cl, byte ptr [esp+26]
004056E3 |. 8A5424 27 |mov dl, byte ptr [esp+27]
004056E7 |. 8826 |mov byte ptr [esi], ah
004056E9 |. 8B4424 1C |mov eax, dword ptr [esp+1C]
004056ED |. 85C0 |test eax, eax
004056EF |. 884E FF |mov byte ptr [esi-1], cl
004056F2 |. 8813 |mov byte ptr [ebx], dl
004056F4 |. 74 0D |je short 00405703
004056F6 |. 8B07 |mov eax, dword ptr [edi]
004056F8 |. 8B4F 04 |mov ecx, dword ptr [edi+4]
004056FB |. 894424 28 |mov dword ptr [esp+28], eax
004056FF |. 894C24 2C |mov dword ptr [esp+2C], ecx
00405703 |> 83C6 08 |add esi, 8
00405706 |. 4D |dec ebp
00405707 |.^ 0F85 4DFFFFFF \jnz 0040565A
0040570D |. 8B4424 18 mov eax, dword ptr [esp+18]
00405711 |> 5F pop edi
00405712 |. 5E pop esi
00405713 |. 5D pop ebp
00405714 |. 5B pop ebx
00405715 |. 59 pop ecx
00405716 \. C2 1800 retn 18 循环中间的函数00404A4F很长但很有规律,里面没有更深层的函数调用,有很多异或运算。主要的运算就是分别对那8个byte的前4byte和后4byte进行异或迭代,其中还用到了一些“常量”数组加入异或运算。
//函数00404A4F(GenLv3_8ByteTrans)
00404AF0 /$ 83EC 10 sub esp, 10
00404AF3 |. 53 push ebx
00404AF4 |. 55 push ebp
00404AF5 |. 56 push esi
00404AF6 |. 8B31 mov esi, dword ptr [ecx]
00404AF8 |. 57 push edi
00404AF9 |. 8B7C24 24 mov edi, dword ptr [esp+24] ; JASS-DEBUG:ESP[24]0012CA7C
00404AFD |. 8B2E mov ebp, dword ptr [esi] ; JASS-DEBUG:S[0]2A9BB267
00404AFF |. 8B41 04 mov eax, dword ptr [ecx+4] ; JASS-DEBUG:a
00404B02 |. 8B17 mov edx, dword ptr [edi] ; JASS-DEBUG:[]32483758--首4字母
00404B04 |. 33D5 xor edx, ebp ; JASS-DEBUG:edx=(首4字母)^S[0]
00404B06 |. 895424 10 mov dword ptr [esp+10], edx ; JASS-DEBUG:T[0]_1--下面用到的4个“行”指标
00404B0A |. 8B5C24 13 mov ebx, dword ptr [esp+13] ; JASS-DEBUG:b=T[0]_1:32
00404B0E |. 8B4C24 12 mov ecx, dword ptr [esp+12] ; JASS-DEBUG:c=T[0]_1:24
00404B12 |. 81E3 FF000000 and ebx, 0FF
00404B18 |. 81E1 FF000000 and ecx, 0FF
00404B1E |. 8B2C98 mov ebp, dword ptr [eax+ebx*4] ; JASS-DEBUG:A[a+b*4]
00404B21 |. 8B5C24 11 mov ebx, dword ptr [esp+11] ; JASS-DEBUG:f=T[0]_1:16
00404B25 |. 8B8C88 000400>mov ecx, dword ptr [eax+ecx*4+400] ; JASS-DEBUG:B[a+c*4]
00404B2C |. 81E3 FF000000 and ebx, 0FF
00404B32 |. 03CD add ecx, ebp
00404B34 |. 8BAC98 000800>mov ebp, dword ptr [eax+ebx*4+800] ; JASS-DEBUG:C[a+f*4]
00404B3B |. 8BDA mov ebx, edx
00404B3D |. 81E3 FF000000 and ebx, 0FF ; JASS-DEBUG:i=T[0]_1:8
00404B43 |. 33CD xor ecx, ebp
00404B45 |. 8BAC98 000C00>mov ebp, dword ptr [eax+ebx*4+C00] ; JASS-DEBUG:D[a+i*4]
00404B4C |. 8B5E 04 mov ebx, dword ptr [esi+4] ; JASS-DEBUG:S[1]A5125437
00404B4F |. 03CD add ecx, ebp
00404B51 |. 33CB xor ecx, ebx ; JASS-DEBUG: ecx = ((A+B)^C+D)^S
00404B53 |. 8B5C24 28 mov ebx, dword ptr [esp+28] ; JASS-DEBUG:ESP[28]
00404B57 |. 330B xor ecx, dword ptr [ebx] ; JASS-DEBUG:[]4652564C--次4字母
00404B59 |. 894C24 18 mov dword ptr [esp+18], ecx ; JASS-DEBUG:T[1]_1=(次4字母)^ecx(ABCDS_1)
00404B5D |. 8B5C24 1A mov ebx, dword ptr [esp+1A]
00404B61 |. 8B6C24 1B mov ebp, dword ptr [esp+1B]
00404B65 |. 81E3 FF000000 and ebx, 0FF
00404B6B |. 81E5 FF000000 and ebp, 0FF
00404B71 |. 8B9C98 000400>mov ebx, dword ptr [eax+ebx*4+400] ; JASS-DEBUG:B[]
00404B78 |. 031CA8 add ebx, dword ptr [eax+ebp*4] ; JASS-DEBUG:A[]
00404B7B |. 8B6C24 19 mov ebp, dword ptr [esp+19]
00404B7F |. 81E5 FF000000 and ebp, 0FF
00404B85 |. 339CA8 000800>xor ebx, dword ptr [eax+ebp*4+800] ; JASS-DEBUG:C[]
00404B8C |. 8BE9 mov ebp, ecx
00404B8E |. 81E5 FF000000 and ebp, 0FF
00404B94 |. 039CA8 000C00>add ebx, dword ptr [eax+ebp*4+C00] ; JASS-DEBUG:D[]
00404B9B |. 8B6E 08 mov ebp, dword ptr [esi+8] ; JASS-DEBUG:S[2]41772F25
00404B9E |. 33DD xor ebx, ebp ; JASS-DEBUG: ebx = ((A+B)^C+D)^S
00404BA0 |. 33D3 xor edx, ebx ; JASS-DEBUG: edx = (首4字母)^S[0]^ebx
00404BA2 |. 895424 10 mov dword ptr [esp+10], edx ; JASS-DEBUG:T[0]_2=T[0]_1^ABCDS_2
00404BA6 |. 8B5C24 12 mov ebx, dword ptr [esp+12]
00404BAA |. 8B6C24 13 mov ebp, dword ptr [esp+13]
00404BAE |. 81E3 FF000000 and ebx, 0FF
00404BB4 |. 81E5 FF000000 and ebp, 0FF
00404BBA |. 8B9C98 000400>mov ebx, dword ptr [eax+ebx*4+400]
00404BC1 |. 031CA8 add ebx, dword ptr [eax+ebp*4]
00404BC4 |. 8B6C24 11 mov ebp, dword ptr [esp+11]
00404BC8 |. 81E5 FF000000 and ebp, 0FF
00404BCE |. 339CA8 000800>xor ebx, dword ptr [eax+ebp*4+800]
00404BD5 |. 8BEA mov ebp, edx
00404BD7 |. 81E5 FF000000 and ebp, 0FF
00404BDD |. 039CA8 000C00>add ebx, dword ptr [eax+ebp*4+C00]
00404BE4 |. 8B6E 0C mov ebp, dword ptr [esi+C]
00404BE7 |. 33DD xor ebx, ebp
00404BE9 |. 33CB xor ecx, ebx
00404BEB |. 894C24 18 mov dword ptr [esp+18], ecx ; JASS-DEBUG:T[1]_2=T[1]_1^ABCDS_3
;;;;;;;;;;;;;;;;;;;;;;;;省略部分;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
00404F57 |. 894C24 18 mov dword ptr [esp+18], ecx ; JASS-DEBUG: 15
00404F5B |. 8B5C24 1A mov ebx, dword ptr [esp+1A]
00404F5F |. 8B6C24 1B mov ebp, dword ptr [esp+1B]
00404F63 |. 81E3 FF000000 and ebx, 0FF
00404F69 |. 81E5 FF000000 and ebp, 0FF
00404F6F |. 8B9C98 000400>mov ebx, dword ptr [eax+ebx*4+400]
00404F76 |. 031CA8 add ebx, dword ptr [eax+ebp*4]
00404F79 |. 8B6C24 19 mov ebp, dword ptr [esp+19]
00404F7D |. 81E5 FF000000 and ebp, 0FF
00404F83 |. 339CA8 000800>xor ebx, dword ptr [eax+ebp*4+800]
00404F8A |. 8BE9 mov ebp, ecx
00404F8C |. 81E5 FF000000 and ebp, 0FF
00404F92 |. 039CA8 000C00>add ebx, dword ptr [eax+ebp*4+C00]
00404F99 |. 8B46 40 mov eax, dword ptr [esi+40] ; JASS-DEBUG:S[16]
00404F9C |. 33D8 xor ebx, eax ; JASS-DEBUG:ABCDS_16
00404F9E |. 8B46 44 mov eax, dword ptr [esi+44] ; JASS-DEBUG:S[17]
00404FA1 |. 33D3 xor edx, ebx ; JASS-DEBUG:edx = T[0]_8^ABCDS_16
00404FA3 |. 33C8 xor ecx, eax ; JASS-DEBUG:ecx = T[1]_8^S[17]
00404FA5 |. 8B4424 28 mov eax, dword ptr [esp+28]
00404FA9 |. 8910 mov dword ptr [eax], edx
00404FAB |. 890F mov dword ptr [edi], ecx
00404FAD |. 5F pop edi
00404FAE |. 5E pop esi
00404FAF |. 5D pop ebp
00404FB0 |. 5B pop ebx
00404FB1 |. 83C4 10 add esp, 10
00404FB4 \. C2 0800 retn 8 到这里,我可以总结出授权码大概的生成过程:
计算机标识码
=>
24byte扩展的计算机标识码 => 24byte数组
=>
数字ASCII码串 => 3个32位整数 => 15byte数组 => 大小写混杂的授权码
=>
授权码
似乎大功告成,只需把相应函数的算法整理出来,组合一下就可得授权码生成器。但如果换了另一台机子去尝试,会发现授权码是错的。原因是函数00404A4F用到的“常量”数组并非常量,是动态生成的。继续往前探索,终于发现这些数组是在call 00404A90之后生成的。函数00404A90首先动态分配了两块内存,然后调用00405490。
在函数00405490中,那两块内存的初始值分别来源于两个固定地址的内存(程序的数据段);之后有3个循环,从循环次数可以判断前两个是生成0x48byte的数组(简记为S),后一个生成0x1000byte的数组(简记为A)。第一个循环由一个15byte的中间字符串和S的初始值生成新的S值,第二第三个循环都调用了之前提到的00404A4F(GenLv3_8ByteTrans),相当于对自身数组作迭代更新。
//函数00405490(GenLv2_15MedStr_SA)
00405490 /$ 83EC 08 sub esp, 8
00405493 |. 33C0 xor eax, eax
00405495 |. 53 push ebx
00405496 |. 55 push ebp
00405497 |. 56 push esi
00405498 |. 57 push edi
00405499 |. 8BF1 mov esi, ecx
0040549B |> 8B0E /mov ecx, dword ptr [esi]
0040549D |. 8B90 20655E00 |mov edx, dword ptr [eax+5E6520]
004054A3 |. 891408 |mov dword ptr [eax+ecx], edx ; JASS-DEBUG: 复制内存
004054A6 |. 83C0 04 |add eax, 4
004054A9 |. 83F8 48 |cmp eax, 48
004054AC |.^ 7C ED \jl short 0040549B
004054AE |. 33C0 xor eax, eax
004054B0 |> B9 00010000 /mov ecx, 100
004054B5 |> 8B56 04 |/mov edx, dword ptr [esi+4]
004054B8 |. 8BB8 68655E00 ||mov edi, dword ptr [eax+5E6568]
004054BE |. 893C10 ||mov dword ptr [eax+edx], edi ; JASS-DEBUG: 复制内存
004054C1 |. 83C0 04 ||add eax, 4
004054C4 |. 49 ||dec ecx
004054C5 |.^ 75 EE |\jnz short 004054B5
004054C7 |. 3D 00100000 |cmp eax, 1000
004054CC |.^ 7C E2 \jl short 004054B0
004054CE |. 8B7C24 20 mov edi, dword ptr [esp+20]
004054D2 |. 8B5C24 1C mov ebx, dword ptr [esp+1C]
004054D6 |. 33C9 xor ecx, ecx
004054D8 |. 33ED xor ebp, ebp
004054DA |> 8BC1 /mov eax, ecx
004054DC |. 99 |cdq
004054DD |. F7FF |idiv edi
004054DF |. 41 |inc ecx
004054E0 |. 8A041A |mov al, byte ptr [edx+ebx]
004054E3 |. 884424 23 |mov byte ptr [esp+23], al
004054E7 |. 8BC1 |mov eax, ecx
004054E9 |. 99 |cdq
004054EA |. F7FF |idiv edi
004054EC |. 41 |inc ecx
004054ED |. 8BC1 |mov eax, ecx
004054EF |. 8A141A |mov dl, byte ptr [edx+ebx]
004054F2 |. 885424 22 |mov byte ptr [esp+22], dl
004054F6 |. 99 |cdq
004054F7 |. F7FF |idiv edi
004054F9 |. 41 |inc ecx
004054FA |. 8A041A |mov al, byte ptr [edx+ebx]
004054FD |. 884424 21 |mov byte ptr [esp+21], al
00405501 |. 8BC1 |mov eax, ecx
00405503 |. 99 |cdq
00405504 |. F7FF |idiv edi
00405506 |. 8B06 |mov eax, dword ptr [esi]
00405508 |. 41 |inc ecx
00405509 |. 03C5 |add eax, ebp
0040550B |. 83C5 04 |add ebp, 4
0040550E |. 8A141A |mov dl, byte ptr [edx+ebx]
00405511 |. 885424 20 |mov byte ptr [esp+20], dl
00405515 |. 8B5424 20 |mov edx, dword ptr [esp+20]
00405519 |. 3110 |xor dword ptr [eax], edx
0040551B |. 83FD 48 |cmp ebp, 48
0040551E |.^ 7C BA \jl short 004054DA
00405520 |. 33FF xor edi, edi
00405522 |. 897C24 14 mov dword ptr [esp+14], edi
00405526 |. 897C24 10 mov dword ptr [esp+10], edi
0040552A |> 8D4424 14 /lea eax, dword ptr [esp+14]
0040552E |. 8D4C24 10 |lea ecx, dword ptr [esp+10]
00405532 |. 50 |push eax
00405533 |. 51 |push ecx
00405534 |. 8BCE |mov ecx, esi
00405536 |. E8 B5F5FFFF |call 00404AF0
0040553B |. 8B16 |mov edx, dword ptr [esi]
0040553D |. 8B4424 10 |mov eax, dword ptr [esp+10]
00405541 |. 890417 |mov dword ptr [edi+edx], eax
00405544 |. 8B0E |mov ecx, dword ptr [esi]
00405546 |. 8B5424 14 |mov edx, dword ptr [esp+14]
0040554A |. 89540F 04 |mov dword ptr [edi+ecx+4], edx
0040554E |. 83C7 08 |add edi, 8
00405551 |. 83FF 48 |cmp edi, 48
00405554 |.^ 7C D4 \jl short 0040552A
00405556 |. BF 04000000 mov edi, 4
0040555B |> BB 80000000 /mov ebx, 80
00405560 |> 8D4424 14 |/lea eax, dword ptr [esp+14]
00405564 |. 8D4C24 10 ||lea ecx, dword ptr [esp+10]
00405568 |. 50 ||push eax
00405569 |. 51 ||push ecx
0040556A |. 8BCE ||mov ecx, esi
0040556C |. E8 7FF5FFFF ||call 00404AF0
00405571 |. 8B56 04 ||mov edx, dword ptr [esi+4]
00405574 |. 8B4424 10 ||mov eax, dword ptr [esp+10]
00405578 |. 894417 FC ||mov dword ptr [edi+edx-4], eax
0040557C |. 8B4E 04 ||mov ecx, dword ptr [esi+4]
0040557F |. 8B5424 14 ||mov edx, dword ptr [esp+14]
00405583 |. 89140F ||mov dword ptr [edi+ecx], edx
00405586 |. 83C7 08 ||add edi, 8
00405589 |. 4B ||dec ebx
0040558A |.^ 75 D4 |\jnz short 00405560
0040558C |. 81FF 04100000 |cmp edi, 1004
00405592 |.^ 7C C7 \jl short 0040555B
00405594 |. 5F pop edi
00405595 |. 5E pop esi
00405596 |. 5D pop ebp
00405597 |. 5B pop ebx
00405598 |. 83C4 08 add esp, 8
0040559B \. C2 0800 retn 8 继续往前找那个15byte的中间字符串的来源。在call 00493B60之后这个字符串出现了。函数00493B60(GenLv2_NumStr_RegCodeCI)正是之前分析过的由数字ASCII码串生成大小写混杂的授权码的函数,这回的输入字符串正是计算机标识符,输出是
15byte的中间字符串。
因此,函数00404A4F(GenLv3_8ByteTrans)(*)所用到的“常量”数组是由计算机标识符和真正的常量数组生成。为了验证这是否常量数组,可以在不同的机器上观察该地址的内存是否一致。
下一步可以整理算法。我选择把算法用c/c++重写,下面是一些重要的计算过程:
//由计算机标识码生成24byte数组,其中用到数组A、S
int Algo_004055C0(unsigned char * _src, int _src_len, int _res_len);
//由24byte数组生成数字ASCII码串
string Algo_00493A3F(const unsigned char * _src, int _size);
//由数字ASCII码串生成大小写混杂的授权码
//由计算机标识码生成15byte中间字符串
int Algo_00493B60(string & _str);
//由15byte中间字符串和内存中的常量数组生成数组A、S
int Algo_00405490(const unsigned char * _src, unsigned int * _dst, int _dst_len);
//由扩展的计算机标识码生成24byte数组的中间步骤
//数组A、S迭代更新的中间步骤
int Algo_00404AF0(unsigned int & _higher, unsigned int & _lower);
程序在6台机器及2台虚拟机上测试,其中有1台机器授权码不对,可能有些细节我还分析得不对-_-b
后记:
注册机做出来后,我上网搜索了一下别人对Feiq授权码的破解,只找到有人做过内存注册机,没找到有人分析它的生成算法,有点失望,不过我不懂内存注册机,正好可以学习研究下,有空也做个锻炼下。
心得体会:
1.跟踪分析时注释很重要,就像是在迷宫中作记号。希望大牛们可以分享下注释的技巧等等。
2.通过不断搜索内存来找到生成目标的函数。当然,我觉得应该还有更好方法,又或者是写个脚本之类,好减少重复劳动,还请大家指点了。
3.分析函数时可以先忽略计算的细节,先找出输入和输出。
4.用C等重写算法时,最好不要“一气呵成”,按照汇编的函数组织层次和逻辑结构分成几个层次几个函数,这样可以方便调试测试。此外,听说可以直接把汇编代码拷出来用,不用花力气分析算法,不知道具体咋操作,是在OD弄还是在IDA弄比较方便?
5.初学者分析下算法还是有好处的,我觉得我对汇编的恐惧感又减少了。
6.现在的工具很好很强大,要好好熟悉,充分利用。
附源码
上传的附件: