VMware Workstation 7.1.3 注册码算法分析+注册机
本帖最后由 风吹屁屁凉 于 2011-3-14 17:06 编辑标 题: 【原创】某虚拟机7.1.3 注册码算法分析+注册机
作 者: hewittlee
时 间: 2011-03-06,12:37:47
链 接: http://bbs.pediy.com/showthread.php?t=130419
【文章标题】: 某虚拟机7.1.3 注册码算法分析+注册机
【文章作者】: Daniel
【作者邮箱】: vvcracker@gmail.com
【操作系统】: Windows 7
【生产日期】: 2010
【软件名称】: 某虚拟机7.1.3
【软件介绍】: 一个虚拟机系统平台
【加壳方式】: 无
【保护方式】: 注册码
【编写语言】: Microsoft Visual C++ 10.0
【使用工具】: OD + PEID + IDA Pro
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请各位大牛小牛原谅!
--------------------------------------------------------------------------------
【讨论说明】
本文只讨论核心验证算法,至于如何跟踪到核心算法,不作说明。
【软件加密详细过程】
验证过程:由于此验证过程比较多,我会一层一层地说明
112341E0为主注册算法入口,还要处理返回的日期限制数组
112341E0/[ DISCUZ_CODE_57 ]nbsp; 55 push ebp
112341E1|.8BEC mov ebp, esp
112341E3|.83EC 4C sub esp, 4C
112341E6|.53 push ebx
112341E7|.33C0 xor eax, eax
112341E9|.57 push edi
112341EA|.50 push eax ; /Arg4 => 00000000
112341EB|.8945 F0 mov dword ptr ss:, eax ; |
112341EE|.8945 E4 mov dword ptr ss:, eax ; |
112341F1|.8B86 E8010000 mov eax, dword ptr ds: ; |
112341F7|.68 38B13D11 push 113DB138 ; |Arg3 = 113DB138 ASCII "Hash"
112341FC|.50 push eax ; |Arg2
112341FD|.8D5E 08 lea ebx, dword ptr ds: ; |
11234200|.53 push ebx ; |Arg1
11234201|.E8 2A290000 call 11236B30 ; \vmwareba.11236B30
11234206|.8BF8 mov edi, eax ;获取这次循环中,sha散列固定的字符数组
11234208|.83C4 10 add esp, 10
1123420B|.85FF test edi, edi
1123420D|.0F84 C1000000 je 112342D4
11234213|.68 84003C11 push 113C0084 ; /Arg2 = 113C0084 ASCII "Option"
11234218|.56 push esi ; |Arg1
11234219|.E8 12FAFFFF call 11233C30 ; \vmwareba.11233C30
1123421E|.83C4 08 add esp, 8
11234221|.A8 02 test al, 2
11234223|.8945 EC mov dword ptr ss:, eax
11234226|.74 1F je short 11234247
11234228|.8B45 08 mov eax, dword ptr ss:
1123422B|.8D50 01 lea edx, dword ptr ds:
1123422E|.8BFF mov edi, edi
11234230|>8A08 /mov cl, byte ptr ds:
11234232|.83C0 01 |add eax, 1
11234235|.84C9 |test cl, cl
11234237|.^ 75 F7 \jnz short 11234230
11234239|.2BC2 sub eax, edx
1123423B|.83F8 1D cmp eax, 1D
1123423E|.0F85 90000000 jnz 112342D4
11234244|.8B45 EC mov eax, dword ptr ss:
11234247|>A8 08 test al, 8
11234249|.74 1A je short 11234265
1123424B|.8B8E E8010000 mov ecx, dword ptr ds:
11234251|.6A 01 push 1 ; /Arg4 = 00000001
11234253|.68 F0BB3D11 push 113DBBF0 ; |Arg3 = 113DBBF0 ASCII "Hash2"
11234258|.51 push ecx ; |Arg2
11234259|.53 push ebx ; |Arg1
1123425A|.E8 D1280000 call 11236B30 ; \vmwareba.11236B30
1123425F|.83C4 10 add esp, 10
11234262|.8945 F0 mov dword ptr ss:, eax
11234265|>8D55 F8 lea edx, dword ptr ss:
11234268|.52 push edx ; /Arg7
11234269|.8D9E EC010000 lea ebx, dword ptr ds: ; |
1123426F|.53 push ebx ; |Arg6
11234270|.8D45 E8 lea eax, dword ptr ss: ; |
11234273|.50 push eax ; |edx为日期数组,1123a320处理后写入数据
11234274|.8B45 08 mov eax, dword ptr ss: ; |
11234277|.8D4D F4 lea ecx, dword ptr ss: ; |
1123427A|.51 push ecx ; |Arg4
1123427B|.8D55 FC lea edx, dword ptr ss: ; |
1123427E|.52 push edx ; |Arg3
1123427F|.57 push edi ; |Arg2
11234280|.50 push eax ; |Arg1
11234281|.E8 9A600000 call 1123A320 ; \1123a320注册算法入口
11234286|.83C4 1C add esp, 1C
11234289|.85C0 test eax, eax
1123428B|.74 13 je short 112342A0
1123428D|>6A 00 push 0 ; /Arg1 = 00000000
1123428F|.E8 ECA70900 call #510 ; \#510
11234294|.83C4 04 add esp, 4
11234297|.5F pop edi
11234298|.83C8 FF or eax, FFFFFFFF
1123429B|.5B pop ebx
1123429C|.8BE5 mov esp, ebp
1123429E|.5D pop ebp
1123429F|.C3 retn
112342A0|>837D F8 00 cmp dword ptr ss:, 0
112342A4|.75 36 jnz short 112342DC
112342A6|.8B45 F0 mov eax, dword ptr ss:
112342A9|.85C0 test eax, eax
112342AB|.74 27 je short 112342D4
112342AD|.8D4D F8 lea ecx, dword ptr ss:
112342B0|.51 push ecx ; /Arg7
112342B1|.53 push ebx ; |Arg6
112342B2|.8D55 E8 lea edx, dword ptr ss: ; |
112342B5|.52 push edx ; |
112342B6|.8D4D F4 lea ecx, dword ptr ss: ; |
112342B9|.51 push ecx ; |Arg4
112342BA|.8D55 FC lea edx, dword ptr ss: ; |
112342BD|.52 push edx ; |Arg3
112342BE|.50 push eax ; |Arg2
112342BF|.8B45 08 mov eax, dword ptr ss: ; |
112342C2|.50 push eax ; |Arg1
112342C3|.E8 58600000 call 1123A320 ; \1123a320一系列注册算法
112342C8|.83C4 1C add esp, 1C
112342CB|.85C0 test eax, eax
112342CD|.^ 75 BE jnz short 1123428D
112342CF|.3945 F8 cmp dword ptr ss:, eax
112342D2|.75 08 jnz short 112342DC
112342D4|>5F pop edi
112342D5|.33C0 xor eax, eax
112342D7|.5B pop ebx
112342D8|.8BE5 mov esp, ebp
112342DA|.5D pop ebp
112342DB|.C3 retn
112342DC|>8B45 F4 mov eax, dword ptr ss:
112342DF|.84C0 test al, al
112342E1|.^ 74 F1 je short 112342D4
112342E3|.8B4D 10 mov ecx, dword ptr ss:
112342E6|.8B55 0C mov edx, dword ptr ss:
112342E9|.51 push ecx ; /Arg7
112342EA|.52 push edx ; |Arg6
112342EB|.8B55 EC mov edx, dword ptr ss: ; |
112342EE|.8D4D E4 lea ecx, dword ptr ss: ; |
112342F1|.51 push ecx ; |Arg5
112342F2|.52 push edx ; |Arg4
112342F3|.50 push eax ; |Arg3
112342F4|.57 push edi ; |Arg2
112342F5|.56 push esi ; |Arg1
112342F6|.8D45 B4 lea eax, dword ptr ss: ; |
112342F9|.8D4D CC lea ecx, dword ptr ss: ; |
112342FC|.E8 7FFAFFFF call 11233D80 ; \判断日期数组,处理日期限制数组
11234301|.83C4 1C add esp, 1C
11234304|.83F8 01 cmp eax, 1
11234307|.0F85 AC000000 jnz 112343B9
1123430D|.8B55 14 mov edx, dword ptr ss:
11234310|.85D2 test edx, edx
11234312|.0F84 9C000000 je 112343B4
11234318|.66:8B4D FC mov cx, word ptr ss:
1123431C|.66:898A A2000>mov word ptr ds:, cx ;以下写入日期信息
11234323|.8B4D E8 mov ecx, dword ptr ss:
11234326|.898A A4000000 mov dword ptr ds:, ecx
1123432C|.8B4D CC mov ecx, dword ptr ss:
1123432F|.894A 24 mov dword ptr ds:, ecx
11234332|.8B4D D0 mov ecx, dword ptr ss:
11234335|.894A 28 mov dword ptr ds:, ecx
11234338|.8B4D D4 mov ecx, dword ptr ss:
1123433B|.894A 2C mov dword ptr ds:, ecx
1123433E|.8B4D D8 mov ecx, dword ptr ss:
11234341|.8A45 F4 mov al, byte ptr ss:
11234344|.3C 07 cmp al, 7
11234346|.894A 30 mov dword ptr ds:, ecx
11234349|.8B4D DC mov ecx, dword ptr ss:
1123434C|.894A 34 mov dword ptr ds:, ecx
1123434F|.8B4D E0 mov ecx, dword ptr ss:
11234352|.894A 38 mov dword ptr ds:, ecx
11234355|.8B4D B4 mov ecx, dword ptr ss:
11234358|.894A 40 mov dword ptr ds:, ecx
1123435B|.8B4D B8 mov ecx, dword ptr ss:
1123435E|.894A 44 mov dword ptr ds:, ecx
11234361|.8B4D BC mov ecx, dword ptr ss:
11234364|.894A 48 mov dword ptr ds:, ecx
11234367|.8B4D C0 mov ecx, dword ptr ss:
1123436A|.894A 4C mov dword ptr ds:, ecx
1123436D|.8B4D C4 mov ecx, dword ptr ss:
11234370|.894A 50 mov dword ptr ds:, ecx
11234373|.8B4D C8 mov ecx, dword ptr ss:
11234376|.8882 A0000000 mov byte ptr ds:, al
1123437C|.894A 54 mov dword ptr ds:, ecx
1123437F|.76 2D jbe short 112343AE
11234381|.33C0 xor eax, eax
11234383|.8D8E 28020000 lea ecx, dword ptr ds:
11234389|.8DA424 000000>lea esp, dword ptr ss:
11234390|>8079 FC 00 /cmp byte ptr ds:, 0
11234394|.74 0D |je short 112343A3
11234396|.8339 00 |cmp dword ptr ds:, 0
11234399|.74 08 |je short 112343A3
1123439B|.C68410 AE0000>|mov byte ptr ds:, 1
112343A3|>83C0 01 |add eax, 1
112343A6|.83C1 08 |add ecx, 8
112343A9|.83F8 05 |cmp eax, 5
112343AC|.^ 7C E2 \jl short 11234390
112343AE|>8B45 E4 mov eax, dword ptr ss:
112343B1|.8942 7C mov dword ptr ds:, eax
112343B4|>B8 01000000 mov eax, 1
112343B9|>5F pop edi
112343BA|.5B pop ebx
112343BB|.8BE5 mov esp, ebp
112343BD|.5D pop ebp
112343BE\.C3 retn
按F7进入1123a320算法处理函数,如下,在这个函数中,有两个关键处理,112396A0为注册码转换为16位数组A,1123A190对数组A
进行第二次转换处理,以及对数组位作检测,作判断。
1123A320/[ DISCUZ_CODE_58 ]nbsp; 55 push ebp
1123A321|.8BEC mov ebp, esp
1123A323|.56 push esi
1123A324|.57 push edi
1123A325|.8B7D 08 mov edi, dword ptr ss:
1123A328|.8BC7 mov eax, edi
1123A32A|.E8 41F2FFFF call 11239570
1123A32F|.8BF0 mov esi, eax
1123A331|.85F6 test esi, esi
1123A333|.74 2F je short 1123A364
1123A335|.8B4D 20 mov ecx, dword ptr ss:
1123A338|.8B55 0C mov edx, dword ptr ss:
1123A33B|.8B45 14 mov eax, dword ptr ss:
1123A33E|.51 push ecx ; /Arg3
1123A33F|.8B4D 10 mov ecx, dword ptr ss: ; |
1123A342|.52 push edx ; |Arg2
1123A343|.C600 00 mov byte ptr ds:, 0 ; |
1123A346|.8B45 18 mov eax, dword ptr ss: ; |
1123A349|.56 push esi ; |Arg1
1123A34A|.E8 01F4FFFF call 11239750 ; \vmwareba.11239750
1123A34F|.83C4 0C add esp, 0C
1123A352|.56 push esi ; /block
1123A353|.8BF8 mov edi, eax ; |
1123A355|.FF15 BC253911 call dword ptr ds:[<&MSVCR80.free>] ; \free
1123A35B|.83C4 04 add esp, 4
1123A35E|.8BC7 mov eax, edi
1123A360|.5F pop edi
1123A361|.5E pop esi
1123A362|.5D pop ebp
1123A363|.C3 retn
1123A364|>6A 00 push 0 ; /Arg1 = 00000000
1123A366|.E8 15470900 call #510 ; \#510
1123A36B|.83C4 04 add esp, 4
1123A36E|.8BC7 mov eax, edi
1123A370|.E8 8BF2FFFF call 11239600
1123A375|.8BF0 mov esi, eax ; |
1123A377|.85F6 test esi, esi ; |
1123A379|.74 3E je short 1123A3B9 ; |
1123A37B|.8B7D 1C mov edi, dword ptr ss: ; |
1123A37E|.6A 60 push 60 ; |/n = 60 (96.)
1123A380|.6A 00 push 0 ; ||c = 00
1123A382|.57 push edi ; ||s
1123A383|.E8 F8A00F00 call <jmp.&MSVCR80.memset> ; |\memset
1123A388|.8B45 20 mov eax, dword ptr ss: ; |
1123A38B|.8B4D 18 mov ecx, dword ptr ss: ; |
1123A38E|.8B55 14 mov edx, dword ptr ss: ; |
1123A391|.50 push eax ; |Arg6
1123A392|.8B45 10 mov eax, dword ptr ss: ; |
1123A395|.51 push ecx ; |Arg5
1123A396|.8B4D 0C mov ecx, dword ptr ss: ; |
1123A399|.52 push edx ; |Arg4
1123A39A|.50 push eax ; |Arg3
1123A39B|.51 push ecx ; |Arg2
1123A39C|.56 push esi ; |Arg1
1123A39D|.8BC7 mov eax, edi ; |
1123A39F|.E8 6CF6FFFF call 11239A10 ; \vmwareba.11239A10
1123A3A4|.83C4 24 add esp, 24
1123A3A7|.56 push esi ; /block
1123A3A8|.8BF8 mov edi, eax ; |
1123A3AA|.FF15 BC253911 call dword ptr ds:[<&MSVCR80.free>] ; \free
1123A3B0|.83C4 04 add esp, 4
1123A3B3|.8BC7 mov eax, edi
1123A3B5|.5F pop edi
1123A3B6|.5E pop esi
1123A3B7|.5D pop ebp
1123A3B8|.C3 retn
1123A3B9|>6A 00 push 0 ; /Arg1 = 00000000
1123A3BB|.E8 C0460900 call #510 ; \#510
1123A3C0|.83C4 04 add esp, 4
1123A3C3|.8BC7 mov eax, edi ;eax为我们输入的注册码
1123A3C5|.E8 D6F2FFFF call 112396A0
1123A3CA|.8BF0 mov esi, eax ;eax由注册值转换的16位数组值
1123A3CC|.85F6 test esi, esi ; |
1123A3CE|.74 3C je short 1123A40C ; |
1123A3D0|.8B7D 1C mov edi, dword ptr ss: ; |
1123A3D3|.6A 60 push 60 ; |/n = 60 (96.)
1123A3D5|.6A 00 push 0 ; ||c = 00
1123A3D7|.57 push edi ; ||s
1123A3D8|.E8 A3A00F00 call <jmp.&MSVCR80.memset> ; |\memset
1123A3DD|.8B55 20 mov edx, dword ptr ss: ; |
1123A3E0|.8B45 18 mov eax, dword ptr ss: ; |
1123A3E3|.8B4D 10 mov ecx, dword ptr ss: ; |
1123A3E6|.52 push edx ; |Arg6
1123A3E7|.8B55 0C mov edx, dword ptr ss: ; |
1123A3EA|.57 push edi ; |Arg5
1123A3EB|.50 push eax ; |Arg4
1123A3EC|.8B45 14 mov eax, dword ptr ss: ; |
1123A3EF|.51 push ecx ; |Arg3
1123A3F0|.52 push edx ; |edx为每次循环提供的hash值
1123A3F1|.56 push esi ; |Arg1
1123A3F2|.E8 99FDFFFF call 1123A190 ; \vmwareba.1123A190
1123A3F7|.83C4 24 add esp, 24 ;
1123A3FA|.56 push esi ; /block
1123A3FB|.8BF8 mov edi, eax ; |
1123A3FD|.FF15 BC253911 call dword ptr ds:[<&MSVCR80.free>] ; \free
1123A403|.83C4 04 add esp, 4
1123A406|.8BC7 mov eax, edi
1123A408|.5F pop edi
1123A409|.5E pop esi
1123A40A|.5D pop ebp
1123A40B|.C3 retn
1123A40C|>56 push esi ; /block
1123A40D|.BF 01000000 mov edi, 1 ; |
1123A412|.FF15 BC253911 call dword ptr ds:[<&MSVCR80.free>] ; \free
1123A418|.83C4 04 add esp, 4
1123A41B|.8BC7 mov eax, edi
1123A41D|.5F pop edi
1123A41E|.5E pop esi
1123A41F|.5D pop ebp
1123A420\.C3 retn
先进入112396A0,看到真正的注册码处理转换在11239400中
1123973C|> \68 68C73D11 push 113DC768 ; /Arg2 = 113DC768
11239741|.50 push eax ; |Arg1
11239742|.B8 19000000 mov eax, 19 ; |注册码长度
11239747|.E8 B4FCFFFF call 11239400 ; \
1123974C|.83C4 08 add esp, 8
1123974F\.C3 retn
进入11239400,注册码转换为16位数组,算法描述如下:
11239400/[ DISCUZ_CODE_60 ]nbsp; 55 push ebp
11239401|.8BEC mov ebp, esp
11239403|.51 push ecx ;
11239404|.56 push esi
11239405|.8BF0 mov esi, eax
11239407|.8D04B6 lea eax, dword ptr ds:
1123940A|.57 push edi
1123940B|.50 push eax ; /Arg1
1123940C|.E8 3F36EDFF call #201 ; \#201
11239411|.8BF8 mov edi, eax
11239413|.83C4 04 add esp, 4
11239416|.85FF test edi, edi
11239418|.75 06 jnz short 11239420
1123941A|.5F pop edi
1123941B|.5E pop esi
1123941C|.8BE5 mov esp, ebp
1123941E|.5D pop ebp
1123941F|.C3 retn
11239420|>53 push ebx
11239421|.8D5E FF lea ebx, dword ptr ds: ;循环19次,从最后一位位开始
11239424|.85DB test ebx, ebx
11239426|.895D FC mov dword ptr ss:, ebx
11239429|.0F8C 0C010000 jl 1123953B
1123942F|.8D749B 02 lea esi, dword ptr ds:;赋值esi,位置计算从7a开始
11239433|>8B4D 0C /mov ecx, dword ptr ss: ecx为索引数组
11239436|.8B1499 |mov edx, dword ptr ds: ;edx获取索引值
11239439|.8B45 08 |mov eax, dword ptr ss:
1123943C|.0FBE0C02 |movsx ecx, byte ptr ds: ;获取索引的注册码值
11239440|.51 |push ecx ; /c
11239441|.68 30C63D11 |push 113DC630 ; |s = "0123456789ACDEFGHJKLMNPQRTUVWXYZ"
11239446|.FF15 38263911 |call dword ptr ds:[<&MSVCR80.strchr>>; \strchr
1123944C|.83C4 08 |add esp, 8 ;eax计算注册码在113DC630数组的位置
1123944F|.85C0 |test eax, eax
11239451|.0F84 ED000000 |je 11239544
11239457|.BA 30C63D11 |mov edx, 113DC630 ;ASCII "0123456789ACDEFGHJKLMNPQRTUVWXYZ"
1123945C|.2AC2 |sub al, dl ;al为索引值
1123945E|.8D4E FE |lea ecx, dword ptr ds: ;处理esi-2的位置值
11239461|.8BD1 |mov edx, ecx
11239463|.83E1 1F |and ecx, 1F ;ecx为32位中相对的位置
11239466|.BB 01000000 |mov ebx, 1 ;ebx赋值为1
1123946B|.C1FA 05 |sar edx, 5 ;edx为转换16位数组中的索引
1123946E|.D3E3 |shl ebx, cl ;ebx为对32位中的cl的位置置1
11239470|.A8 01 |test al, 1 ;测试al是否为1
11239472|.8D5497 08 |lea edx, dword ptr ds: ;计算转换数组的位置
11239476|.74 04 |je short 1123947C
11239478|.091A |or dword ptr ds:, ebx ;对转换数组中的位置赋值1
1123947A|.EB 04 |jmp short 11239480
1123947C|>F7D3 |not ebx
1123947E|.211A |and dword ptr ds:, ebx ;对转换数组中的位置赋值0
11239480|>8D4E FF |lea ecx, dword ptr ds: ;处理esi-1的位置值
11239483|.8BD1 |mov edx, ecx
11239485|.83E1 1F |and ecx, 1F ;ecx为32位中相对的位置
11239488|.BB 01000000 |mov ebx, 1 ;ebx赋值为1
1123948D|.D0E8 |shr al, 1 ;al为索引值,右移一位
1123948F|.C1FA 05 |sar edx, 5 ;edx为转换16位数组中的索引
11239492|.D3E3 |shl ebx, cl ;ebx为对32位中的cl的位置置1
11239494|.A8 01 |test al, 1 ;测试al是否为1
11239496|.8D5497 08 |lea edx, dword ptr ds: ;计算转换数组的位置
1123949A|.74 04 |je short 112394A0
1123949C|.091A |or dword ptr ds:, ebx ;对转换数组中的位置赋值1
1123949E|.EB 04 |jmp short 112394A4
112394A0|>F7D3 |not ebx
112394A2|.211A |and dword ptr ds:, ebx ;对转换数组中的位置赋值0
112394A4|>D0E8 |shr al, 1 ;以下也有3步类似处理,同上
112394A6|.BB 01000000 |mov ebx, 1
112394AB|.84C3 |test bl, al
112394AD|.8BCE |mov ecx, esi
112394AF|.74 12 |je short 112394C3
112394B1|.C1F9 05 |sar ecx, 5
112394B4|.8D548F 08 |lea edx, dword ptr ds:
112394B8|.8BCE |mov ecx, esi
112394BA|.83E1 1F |and ecx, 1F
112394BD|.D3E3 |shl ebx, cl
112394BF|.091A |or dword ptr ds:, ebx
112394C1|.EB 12 |jmp short 112394D5
112394C3|>83E1 1F |and ecx, 1F
112394C6|.D3E3 |shl ebx, cl
112394C8|.8BD6 |mov edx, esi
112394CA|.C1FA 05 |sar edx, 5
112394CD|.8D5497 08 |lea edx, dword ptr ds:
112394D1|.F7D3 |not ebx
112394D3|.211A |and dword ptr ds:, ebx
112394D5|>8D4E 01 |lea ecx, dword ptr ds:
112394D8|.8BD1 |mov edx, ecx
112394DA|.83E1 1F |and ecx, 1F
112394DD|.BB 01000000 |mov ebx, 1
112394E2|.D0E8 |shr al, 1
112394E4|.C1FA 05 |sar edx, 5
112394E7|.D3E3 |shl ebx, cl
112394E9|.A8 01 |test al, 1
112394EB|.8D5497 08 |lea edx, dword ptr ds:
112394EF|.74 04 |je short 112394F5
112394F1|.091A |or dword ptr ds:, ebx
112394F3|.EB 04 |jmp short 112394F9
112394F5|>F7D3 |not ebx
112394F7|.211A |and dword ptr ds:, ebx
112394F9|>8D4E 02 |lea ecx, dword ptr ds:
112394FC|.A8 02 |test al, 2
112394FE|.BA 01000000 |mov edx, 1
11239503|.8BC1 |mov eax, ecx
11239505|.74 10 |je short 11239517
11239507|.83E1 1F |and ecx, 1F
1123950A|.C1F8 05 |sar eax, 5
1123950D|.D3E2 |shl edx, cl
1123950F|.8D4487 08 |lea eax, dword ptr ds:
11239513|.0910 |or dword ptr ds:, edx
11239515|.EB 10 |jmp short 11239527
11239517|>83E1 1F |and ecx, 1F
1123951A|.D3E2 |shl edx, cl
1123951C|.C1F8 05 |sar eax, 5
1123951F|.8D4487 08 |lea eax, dword ptr ds:
11239523|.F7D2 |not edx
11239525|.2110 |and dword ptr ds:, edx
11239527|>8B5D FC |mov ebx, dword ptr ss:
1123952A|.83EB 01 |sub ebx, 1 ;循环值减一
1123952D|.83EE 05 |sub esi, 5 ;esi减5位
11239530|.85DB |test ebx, ebx
11239532|.895D FC |mov dword ptr ss:, ebx
11239535|.^ 0F8D F8FEFFFF \jge 11239433
1123953B|>5B pop ebx
1123953C|.8BC7 mov eax, edi
1123953E|.5F pop edi
1123953F|.5E pop esi
11239540|.8BE5 mov esp, ebp
11239542|.5D pop ebp
11239543|.C3 retn
11239544|>8B45 0C mov eax, dword ptr ss:
11239547|.8B0C98 mov ecx, dword ptr ds:
1123954A|.83C1 01 add ecx, 1
1123954D|.51 push ecx
1123954E|.68 38C83D11 push 113DC838 ;
11239553|.E8 08550900 call 112CEA60
11239558|.57 push edi ; /block
11239559|.FF15 BC253911 call dword ptr ds:[<&MSVCR80.free>] ; \free
1123955F|.83C4 0C add esp, 0C
11239562|.5B pop ebx
11239563|.5F pop edi
11239564|.33C0 xor eax, eax
11239566|.5E pop esi
11239567|.8BE5 mov esp, ebp
11239569|.5D pop ebp
1123956A\.C3 retn观看索引数组,循环获取索引值,索引从0x18开始到0结束113DC76819 00 00 00 15 00 00 00 01 00 00 00 10 00 00 00............
113DC77813 00 00 00 00 00 00 00 14 00 00 00 08 00 00 00.............
113DC78816 00 00 00 18 00 00 00 1B 00 00 00 02 00 00 00............
113DC79809 00 00 00 0A 00 00 00 06 00 00 00 0E 00 00 00..............
113DC7A81A 00 00 00 1C 00 00 00 03 00 00 00 04 00 00 00............
113DC7B80C 00 00 00 0D 00 00 00 07 00 00 00 0F 00 00 00..............
113DC7C812 00 00 00 02 00 00 00 01 00 00 00 00 00 00 00.............
IDA分析11239400算法,转换为C,算法说明文章结尾看软件加密思路1,算法如下
v6 = v5 - 1;
v23 = v5 - 1;
if ( v5 - 1 < 0 )
{
LABEL_22:
result = v4;
}
else
{
v7 = 5 * v6 + 2;
while ( 1 )
{
v8 = strchr("0123456789ACDEFGHJKLMNPQRTUVWXYZ", *(_BYTE *)(*(_DWORD *)(a3 + 4 * v6) + a2));
if ( !v8 )
break;
v9 = (_BYTE)v8 - (unsigned int)"0123456789ACDEFGHJKLMNPQRTUVWXYZ";
v11 = 1 << ((v7 - 2) & 0x1F);
v10 = (int)(v4 + 4 * ((v7 - 2) >> 5) + 8);
if ( v9 & 1 )
*(_DWORD *)v10 |= v11;
else
*(_DWORD *)v10 &= ~v11;
v12 = v9 >> 1;
v14 = 1 << ((v7 - 1) & 0x1F);
v13 = (int)(v4 + 4 * ((v7 - 1) >> 5) + 8);
if ( v12 & 1 )
*(_DWORD *)v13 |= v14;
else
*(_DWORD *)v13 &= ~v14;
v15 = v12 >> 1;
if ( v15 & 1 )
*((_DWORD *)v4 + (v7 >> 5) + 2) |= 1 << (v7 & 0x1F);
else
*((_DWORD *)v4 + (v7 >> 5) + 2) &= ~(1 << (v7 & 0x1F));
v16 = v15 >> 1;
v18 = 1 << ((v7 + 1) & 0x1F);
v17 = (int)(v4 + 4 * ((v7 + 1) >> 5) + 8);
if ( v16 & 1 )
*(_DWORD *)v17 |= v18;
else
*(_DWORD *)v17 &= ~v18;
v20 = v7 + 2;
v21 = (v16 & 2) == 0;
v19 = v7 + 2;
if ( v21 )
*((_DWORD *)v4 + (v19 >> 5) + 2) &= ~(1 << (v20 & 0x1F));
else
*((_DWORD *)v4 + (v19 >> 5) + 2) |= 1 << (v20 & 0x1F);
v6 = v23 - 1;
v7 -= 5;
v22 = v23-- - 1 < 0;
if ( v22 )
goto LABEL_22;
}
sub_112CEA60(
"@&!*@*@(msg.serial.full.alphabet)The character number %u of the serial number is invalid.\n",
*(_DWORD *)(a3 + 4 * v6) + 1);
free(v4);
result = 0;
}
至此,第一次转换注册码完成。
进入1123A190,看第二个注册验证过程,又是一个漫长的验证过程,注意,注释的地方都属于处理过程
1123A190/[ DISCUZ_CODE_62 ]nbsp; 55 push ebp
1123A191|.8BEC mov ebp, esp
1123A193|.83EC 08 sub esp, 8
1123A196|.53 push ebx
1123A197|.56 push esi
1123A198|.6A 7D push 7D ; /Arg1 = 0000007D
1123A19A|.8BD8 mov ebx, eax ; |
1123A19C|.E8 AF28EDFF call #201 ; \#201
1123A1A1|.8BF0 mov esi, eax
1123A1A3|.83C4 04 add esp, 4
1123A1A6|.85F6 test esi, esi
1123A1A8|.75 09 jnz short 1123A1B3
1123A1AA|.8D46 01 lea eax, dword ptr ds:
1123A1AD|.5E pop esi
1123A1AE|.5B pop ebx
1123A1AF|.8BE5 mov esp, ebp
1123A1B1|.5D pop ebp
1123A1B2|.C3 retn
1123A1B3|>8B45 08 mov eax, dword ptr ss:
1123A1B6|.57 push edi
1123A1B7|.6A 01 push 1
1123A1B9|.50 push eax ;eax为第一次转换的16位数组
1123A1BA|.8BFE mov edi, esi ;edi为经过11239100处理的第二次转换16位数组
1123A1BC|.E8 3FEFFFFF call 11239100
1123A1C1|.8B45 14 mov eax, dword ptr ss: ;
1123A1C4|.8B55 10 mov edx, dword ptr ss: ;
1123A1C7|.53 push ebx ;
1123A1C8|.E8 03FBFFFF call 11239CD0 ; 根据第二次转换16位数组的值,获取第14位的值,判断是否在合理值范围内,并赋值到ebx的地址
1123A1CD|.83C4 0C add esp, 0C
1123A1D0|.803B 06 cmp byte ptr ds:, 6 ; 判断ebx是否在合理值范围内
1123A1D3|.72 0A jb short 1123A1DF
1123A1D5|.8B45 18 mov eax, dword ptr ss: ; eax为时间数组
1123A1D8|.8BD6 mov edx, esi ; edx为第二次转换16位数组地址
1123A1DA|.E8 11FDFFFF call 11239EF0 ; 11239EF0根据edx数组赋值到eax
1123A1DF|>803B 08 cmp byte ptr ds:, 8 ; 判断ebx是否在合理值范围内
1123A1E2|.72 0C jb short 1123A1F0
1123A1E4|.8B55 18 mov edx, dword ptr ss:
1123A1E7|.56 push esi ;
1123A1E8|.E8 53FFFFFF call 1123A140 ;
1123A1ED|.83C4 04 add esp, 4
1123A1F0|>33DB xor ebx, ebx
1123A1F2|.33FF xor edi, edi
1123A1F4|.B8 25000000 mov eax, 25
1123A1F9|.8DA424 000000>lea esp, dword ptr ss: ;以下处理是分离出16位数组前5位
1123A200|>0FA4DF 01 /shld edi, ebx, 1 ;前4位,后1位分别赋给ebx,edi
1123A204|.8D50 02 |lea edx, dword ptr ds: ;此过程有点迷惑人的成分,过程很复杂
1123A207|.897D FC |mov dword ptr ss:, edi ;开头跟踪一番后,才发觉自己被骗了
1123A20A|.8BCA |mov ecx, edx ;
1123A20C|.83E1 1F |and ecx, 1F
1123A20F|.BF 01000000 |mov edi, 1
1123A214|.D3E7 |shl edi, cl
1123A216|.8B4D FC |mov ecx, dword ptr ss:
1123A219|.C1FA 05 |sar edx, 5
1123A21C|.03DB |add ebx, ebx
1123A21E|.857C96 08 |test dword ptr ds:, edi
1123A222|.74 06 |je short 1123A22A
1123A224|.83C3 01 |add ebx, 1
1123A227|.83D1 00 |adc ecx, 0
1123A22A|>0FA4D9 01 |shld ecx, ebx, 1
1123A22E|.894D FC |mov dword ptr ss:, ecx
1123A231|.8D50 01 |lea edx, dword ptr ds:
1123A234|.8BCA |mov ecx, edx
1123A236|.83E1 1F |and ecx, 1F
1123A239|.BF 01000000 |mov edi, 1
1123A23E|.D3E7 |shl edi, cl
1123A240|.C1FA 05 |sar edx, 5
1123A243|.03DB |add ebx, ebx
1123A245|.857C96 08 |test dword ptr ds:, edi
1123A249|.8B55 FC |mov edx, dword ptr ss:
1123A24C|.74 06 |je short 1123A254
1123A24E|.83C3 01 |add ebx, 1
1123A251|.83D2 00 |adc edx, 0
1123A254|>8BC8 |mov ecx, eax
1123A256|.83E1 1F |and ecx, 1F
1123A259|.BF 01000000 |mov edi, 1
1123A25E|.D3E7 |shl edi, cl
1123A260|.8BC8 |mov ecx, eax
1123A262|.0FA4DA 01 |shld edx, ebx, 1
1123A266|.C1F9 05 |sar ecx, 5
1123A269|.03DB |add ebx, ebx
1123A26B|.857C8E 08 |test dword ptr ds:, edi
1123A26F|.74 06 |je short 1123A277
1123A271|.83C3 01 |add ebx, 1
1123A274|.83D2 00 |adc edx, 0
1123A277|>0FA4DA 01 |shld edx, ebx, 1
1123A27B|.8955 FC |mov dword ptr ss:, edx
1123A27E|.8D50 FF |lea edx, dword ptr ds:
1123A281|.8BCA |mov ecx, edx
1123A283|.83E1 1F |and ecx, 1F
1123A286|.BF 01000000 |mov edi, 1
1123A28B|.D3E7 |shl edi, cl
1123A28D|.8B4D FC |mov ecx, dword ptr ss:
1123A290|.C1FA 05 |sar edx, 5
1123A293|.03DB |add ebx, ebx
1123A295|.857C96 08 |test dword ptr ds:, edi
1123A299|.74 06 |je short 1123A2A1
1123A29B|.83C3 01 |add ebx, 1
1123A29E|.83D1 00 |adc ecx, 0
1123A2A1|>0FA4D9 01 |shld ecx, ebx, 1
1123A2A5|.894D FC |mov dword ptr ss:, ecx
1123A2A8|.8D50 FE |lea edx, dword ptr ds:
1123A2AB|.8BCA |mov ecx, edx
1123A2AD|.83E1 1F |and ecx, 1F
1123A2B0|.BF 01000000 |mov edi, 1
1123A2B5|.D3E7 |shl edi, cl
1123A2B7|.C1FA 05 |sar edx, 5
1123A2BA|.03DB |add ebx, ebx
1123A2BC|.857C96 08 |test dword ptr ds:, edi
1123A2C0|.8B7D FC |mov edi, dword ptr ss:
1123A2C3|.74 06 |je short 1123A2CB
1123A2C5|.83C3 01 |add ebx, 1
1123A2C8|.83D7 00 |adc edi, 0
1123A2CB|>83E8 05 |sub eax, 5
1123A2CE|.8D50 02 |lea edx, dword ptr ds:
1123A2D1|.85D2 |test edx, edx
1123A2D3|.^ 0F8D 27FFFFFF \jge 1123A200
1123A2D9|.8B4D 0C mov ecx, dword ptr ss:
1123A2DC|.8D45 F8 lea eax, dword ptr ss:
1123A2DF|.50 push eax ; 处理结果保存到eax中
1123A2E0|.51 push ecx ; ecx上层提供的固定字符串数组
1123A2E1|.56 push esi ; esi第二次转换16位数组
1123A2E2|.E8 49E8FFFF call 11238B30 ; 对第二次还原16位后11位,进行处理
1123A2E7|.83C4 0C add esp, 0C ;
1123A2EA|.3B5D F8 cmp ebx, dword ptr ss: ;对比ebx,edi的值是否相同
1123A2ED|.75 0C jnz short 1123A2FB
1123A2EF|.3B7D FC cmp edi, dword ptr ss:
1123A2F2|.75 07 jnz short 1123A2FB
1123A2F4|.B8 01000000 mov eax, 1
1123A2F9|.EB 02 jmp short 1123A2FD
1123A2FB|>33C0 xor eax, eax
1123A2FD|>8B55 1C mov edx, dword ptr ss: ;1zhi
1123A300|.56 push esi ; /block
1123A301|.8902 mov dword ptr ds:, eax ; |
1123A303|.FF15 BC253911 call dword ptr ds:[<&MSVCR80.free>] ; \free
1123A309|.83C4 04 add esp, 4
1123A30C|.5F pop edi
1123A30D|.5E pop esi
1123A30E|.33C0 xor eax, eax
1123A310|.5B pop ebx
1123A311|.8BE5 mov esp, ebp
1123A313|.5D pop ebp
1123A314\.C3 retn
先看11239100处理过程,算法描述如下:
11239100/[ DISCUZ_CODE_63 ]nbsp; 55 push ebp
11239101|.8BEC mov ebp, esp
11239103|.83EC 10 sub esp, 10
11239106|.53 push ebx
11239107|.56 push esi
11239108|.33F6 xor esi, esi
1123910A|.33C0 xor eax, eax ;以下为要保存计算的3个开始的位数值
1123910C C745 FC 50000>mov dword ptr ss:, 50 ;保存80
11239113 C745 F8 28000>mov dword ptr ss:, 28 ;保存40
1123911A|.8975 F4 mov dword ptr ss:, esi ;保存0
1123911D|.33DB xor ebx, ebx ;ebx作为内循环求余处理的索引值
1123911F|.8945 F0 mov dword ptr ss:, eax ;eax是从0开始的索引值
11239122|.EB 0F jmp short 11239133 ;以下为两个循环作为处理
11239124|>8B75 F4 /mov esi, dword ptr ss: ;内循环的索引值主要用来求余
11239127|.33DB |xor ebx, ebx ;外循环的索引值从0到105位之间进行处理
11239129|.8945 F0 |mov dword ptr ss:, eax ;ebx内循环索引置0
1123912C|.EB 05 |jmp short 11239133
1123912E| 8BFF |mov edi, edi
11239130|>8B75 F4 |mov esi, dword ptr ss:
11239133|>837D 0C 00 cmp dword ptr ss:, 0
11239137|.0F84 EE000000 |je 1123922B
1123913D|.8BC8 |mov ecx, eax
1123913F|.83E1 1F |and ecx, 1F ;这里主要根据索引获取数组的值,并判断是否为1
11239142|.BE 01000000 |mov esi, 1 ;同时队内循环索引求余
11239147|.D3E6 |shl esi, cl
11239149|.8B4D 08 |mov ecx, dword ptr ss:
1123914C|.C1F8 05 |sar eax, 5
1123914F|.237481 08 |and esi, dword ptr ds:
11239153|.B8 ABAAAAAA |mov eax, AAAAAAAB
11239158|.F7DE |neg esi
1123915A|.1BF6 |sbb esi, esi
1123915C|.F7E3 |mul ebx
1123915E|.D1EA |shr edx, 1
11239160|.8D1452 |lea edx, dword ptr ds:
11239163|.8BC3 |mov eax, ebx
11239165|.F7DE |neg esi
11239167|.2BC2 |sub eax, edx ;eax为内循环索引值求余的结果
11239169|.0F84 8A000000 |je 112391F9 ;以下分别对求余结果0,1,2进行处理
1123916F|.83FB 14 |cmp ebx, 14
11239172|.0F84 81000000 |je 112391F9
11239178|.F6C3 01 |test bl, 1
1123917B|.75 4A |jnz short 112391C7
1123917D|.83FB 10 |cmp ebx, 10
11239180|.74 45 |je short 112391C7
11239182|.85F6 |test esi, esi ;处理余数为1的情况
11239184|.8B4D FC |mov ecx, dword ptr ss: ;获取要处理的位数
11239187|.74 1E |je short 112391A7
11239189|.8BD1 |mov edx, ecx
1123918B|.C1FA 05 |sar edx, 5 ;edx为目标16位数组中的索引
1123918E|.8D4497 08 |lea eax, dword ptr ds: ;计算目标数组的位置
11239192|.83E1 1F |and ecx, 1F ;ecx为32位中相对的位置
11239195|.BA 01000000 |mov edx, 1
1123919A|.D3E2 |shl edx, cl ;edx为对32位中的cl的位置置1
1123919C|.0910 |or dword ptr ds:, edx ;目标数组的位置置1
1123919E|.8345 FC 01 |add dword ptr ss:, 1 ;对位数加1
112391A2|.E9 4B010000 |jmp 112392F2
112391A7|>8BC1 |mov eax, ecx
112391A9|.83E1 1F |and ecx, 1F ;ecx为32位中相对的位置
112391AC|.BA 01000000 |mov edx, 1
112391B1|.D3E2 |shl edx, cl ;edx为对32位中的cl的位置置1
112391B3|.C1F8 05 |sar eax, 5 ;edx为目标16位数组中的索引
112391B6|.8D4487 08 |lea eax, dword ptr ds: ;计算目标数组的位置
112391BA|.F7D2 |not edx
112391BC|.2110 |and dword ptr ds:, edx ;目标数组的位置置0
112391BE|.8345 FC 01 |add dword ptr ss:, 1 ;对位数加1
112391C2|.E9 2B010000 |jmp 112392F2
112391C7|>8B4D F8 |mov ecx, dword ptr ss:
112391CA|.8BC1 |mov eax, ecx ;以下求余为0,2的处理跟求余为1相似
112391CC|.83E1 1F |and ecx, 1F
112391CF|.BA 01000000 |mov edx, 1
112391D4|.C1F8 05 |sar eax, 5
112391D7|.D3E2 |shl edx, cl
112391D9|.85F6 |test esi, esi
112391DB|.8D4487 08 |lea eax, dword ptr ds:
112391DF|.74 0B |je short 112391EC
112391E1|.0910 |or dword ptr ds:, edx
112391E3|.8345 F8 01 |add dword ptr ss:, 1
112391E7|.E9 06010000 |jmp 112392F2
112391EC|>F7D2 |not edx
112391EE|.2110 |and dword ptr ds:, edx
112391F0|.8345 F8 01 |add dword ptr ss:, 1
112391F4|.E9 F9000000 |jmp 112392F2
112391F9|>8B4D F4 |mov ecx, dword ptr ss:
112391FC|.8BC1 |mov eax, ecx
112391FE|.83E1 1F |and ecx, 1F
11239201|.BA 01000000 |mov edx, 1
11239206|.C1F8 05 |sar eax, 5
11239209|.D3E2 |shl edx, cl
1123920B|.85F6 |test esi, esi
1123920D|.8D4487 08 |lea eax, dword ptr ds:
11239211|.74 0B |je short 1123921E
11239213|.0910 |or dword ptr ds:, edx
11239215|.8345 F4 01 |add dword ptr ss:, 1
11239219|.E9 D4000000 |jmp 112392F2
1123921E|>F7D2 |not edx
11239220|.2110 |and dword ptr ds:, edx
11239222|.8345 F4 01 |add dword ptr ss:, 1
11239226|.E9 C7000000 |jmp 112392F2
1123922B|>B8 ABAAAAAA |mov eax, AAAAAAAB
11239230|.F7E3 |mul ebx
11239232|.D1EA |shr edx, 1
11239234|.8D0452 |lea eax, dword ptr ds:
11239237|.8BCB |mov ecx, ebx
11239239|.2BC8 |sub ecx, eax
1123923B|.74 63 |je short 112392A0
1123923D|.83FB 14 |cmp ebx, 14
11239240|.74 5E |je short 112392A0
11239242|.F6C3 01 |test bl, 1
11239245|.75 2F |jnz short 11239276
11239247|.83FB 10 |cmp ebx, 10
1123924A|.74 2A |je short 11239276
1123924C|.8B4D FC |mov ecx, dword ptr ss:
1123924F|.8B75 08 |mov esi, dword ptr ss:
11239252|.83E1 1F |and ecx, 1F
11239255|.B8 01000000 |mov eax, 1
1123925A|.D3E0 |shl eax, cl
1123925C|.8B4D FC |mov ecx, dword ptr ss:
1123925F|.8BD1 |mov edx, ecx
11239261|.C1FA 05 |sar edx, 5
11239264|.234496 08 |and eax, dword ptr ds:
11239268|.F7D8 |neg eax
1123926A|.1BC0 |sbb eax, eax
1123926C|.F7D8 |neg eax
1123926E|.83C1 01 |add ecx, 1
11239271|.894D FC |mov dword ptr ss:, ecx
11239274|.EB 4E |jmp short 112392C4
11239276|>8B4D F8 |mov ecx, dword ptr ss:
11239279|.8B75 08 |mov esi, dword ptr ss:
1123927C|.83E1 1F |and ecx, 1F
1123927F|.B8 01000000 |mov eax, 1
11239284|.D3E0 |shl eax, cl
11239286|.8B4D F8 |mov ecx, dword ptr ss:
11239289|.8BD1 |mov edx, ecx
1123928B|.C1FA 05 |sar edx, 5
1123928E|.234496 08 |and eax, dword ptr ds:
11239292|.F7D8 |neg eax
11239294|.1BC0 |sbb eax, eax
11239296|.F7D8 |neg eax
11239298|.83C1 01 |add ecx, 1
1123929B|.894D F8 |mov dword ptr ss:, ecx
1123929E|.EB 24 |jmp short 112392C4
112392A0|>8B55 08 |mov edx, dword ptr ss:
112392A3|.8BCE |mov ecx, esi
112392A5|.83E1 1F |and ecx, 1F
112392A8|.B8 01000000 |mov eax, 1
112392AD|.D3E0 |shl eax, cl
112392AF|.8BCE |mov ecx, esi
112392B1|.C1F9 05 |sar ecx, 5
112392B4|.23448A 08 |and eax, dword ptr ds:
112392B8|.F7D8 |neg eax
112392BA|.1BC0 |sbb eax, eax
112392BC|.F7D8 |neg eax
112392BE|.83C6 01 |add esi, 1
112392C1|.8975 F4 |mov dword ptr ss:, esi
112392C4|>8B4D F0 |mov ecx, dword ptr ss:
112392C7|.85C0 |test eax, eax
112392C9|.BA 01000000 |mov edx, 1
112392CE|.8BC1 |mov eax, ecx
112392D0|.74 10 |je short 112392E2
112392D2|.83E1 1F |and ecx, 1F
112392D5|.C1F8 05 |sar eax, 5
112392D8|.D3E2 |shl edx, cl
112392DA|.8D4487 08 |lea eax, dword ptr ds:
112392DE|.0910 |or dword ptr ds:, edx
112392E0|.EB 10 |jmp short 112392F2
112392E2|>83E1 1F |and ecx, 1F
112392E5|.D3E2 |shl edx, cl
112392E7|.C1F8 05 |sar eax, 5
112392EA|.8D4487 08 |lea eax, dword ptr ds:
112392EE|.F7D2 |not edx
112392F0|.2110 |and dword ptr ds:, edx
112392F2|>8345 F0 01 |add dword ptr ss:, 1
112392F6|.8B45 F0 |mov eax, dword ptr ss: ;增加外循环索引
112392F9|.83C3 01 |add ebx, 1 ;基于上一个key,从1到69位,求余,分别基于0,1,2
112392FC|.83FB 15 |cmp ebx, 15
112392FF|.^ 0F8C 2BFEFFFF |jl 11239130
11239305|.83F8 69 |cmp eax, 69
11239308|.^ 0F8C 16FEFFFF \jl 11239124
1123930E|.BE 6B000000 mov esi, 6B ;从107位开始到128位直接复制
11239313|>8B5D 08 /mov ebx, dword ptr ss:
11239316|.8D46 FE |lea eax, dword ptr ds:
11239319|.8BC8 |mov ecx, eax
1123931B|.83E1 1F |and ecx, 1F
1123931E|.BA 01000000 |mov edx, 1
11239323|.D3E2 |shl edx, cl
11239325|.C1F8 05 |sar eax, 5
11239328|.8D0485 080000>|lea eax, dword ptr ds:
1123932F|.851418 |test dword ptr ds:, edx
11239332|.74 05 |je short 11239339
11239334|.091438 |or dword ptr ds:, edx
11239337|.EB 05 |jmp short 1123933E
11239339|>F7D2 |not edx
1123933B|.211438 |and dword ptr ds:, edx
1123933E|>8D46 FF |lea eax, dword ptr ds:
11239341|.8BC8 |mov ecx, eax
11239343|.83E1 1F |and ecx, 1F
11239346|.BA 01000000 |mov edx, 1
1123934B|.D3E2 |shl edx, cl
1123934D|.C1F8 05 |sar eax, 5
11239350|.8D0485 080000>|lea eax, dword ptr ds:
11239357|.851418 |test dword ptr ds:, edx
1123935A|.74 05 |je short 11239361
1123935C|.091438 |or dword ptr ds:, edx
1123935F|.EB 05 |jmp short 11239366
11239361|>F7D2 |not edx
11239363|.211438 |and dword ptr ds:, edx
11239366|>8BCE |mov ecx, esi
11239368|.83E1 1F |and ecx, 1F
1123936B|.B8 01000000 |mov eax, 1
11239370|.D3E0 |shl eax, cl
11239372|.8BCE |mov ecx, esi
11239374|.C1F9 05 |sar ecx, 5
11239377|.8D0C8D 080000>|lea ecx, dword ptr ds:
1123937E|.850419 |test dword ptr ds:, eax
11239381|.74 05 |je short 11239388
11239383|.090439 |or dword ptr ds:, eax
11239386|.EB 05 |jmp short 1123938D
11239388|>F7D0 |not eax
1123938A|.210439 |and dword ptr ds:, eax
1123938D|>8D46 01 |lea eax, dword ptr ds:
11239390|.8BC8 |mov ecx, eax
11239392|.83E1 1F |and ecx, 1F
11239395|.BA 01000000 |mov edx, 1
1123939A|.D3E2 |shl edx, cl
1123939C|.C1F8 05 |sar eax, 5
1123939F|.8D0485 080000>|lea eax, dword ptr ds:
112393A6|.851418 |test dword ptr ds:, edx
112393A9|.74 05 |je short 112393B0
112393AB|.091438 |or dword ptr ds:, edx
112393AE|.EB 05 |jmp short 112393B5
112393B0|>F7D2 |not edx
112393B2|.211438 |and dword ptr ds:, edx
112393B5|>8D46 02 |lea eax, dword ptr ds:
112393B8|.8BC8 |mov ecx, eax
112393BA|.83E1 1F |and ecx, 1F
112393BD|.BA 01000000 |mov edx, 1
112393C2|.D3E2 |shl edx, cl
112393C4|.C1F8 05 |sar eax, 5
112393C7|.8D0485 080000>|lea eax, dword ptr ds:
112393CE|.851418 |test dword ptr ds:, edx
112393D1|.74 05 |je short 112393D8
112393D3|.091438 |or dword ptr ds:, edx
112393D6|.EB 05 |jmp short 112393DD
112393D8|>F7D2 |not edx
112393DA|.211438 |and dword ptr ds:, edx
112393DD|>83C6 05 |add esi, 5
112393E0|.8D56 FE |lea edx, dword ptr ds:
112393E3|.83FA 7D |cmp edx, 7D
112393E6|.^ 0F8C 27FFFFFF \jl 11239313
112393EC|.5E pop esi
112393ED|.5B pop ebx
112393EE|.8BE5 mov esp, ebp
112393F0|.5D pop ebp
112393F1\.C3 retn
IDA分析11239100算法,转换为C,算法说明文章结尾看软件加密思路2,算法如下
while ( 1 )
{
while ( 1 )
{
if ( a3 )
{
v6 = (*(_DWORD *)(a2 + 4 * (v3 >> 5) + 8) & (1 << (v3 & 0x1F))) != 0;
if ( v4 % 3 && v4 != 20 )
{
if ( v4 & 1 || v4 == 16 )
{
v8 = 1 << (v25 & 0x1F);
v7 = a1 + 4 * (v25 >> 5) + 8;
if ( v6 )
{
*(_DWORD *)v7 |= v8;
++v25;
}
else
{
*(_DWORD *)v7 &= ~v8;
++v25;
}
}
else
{
if ( (*(_DWORD *)(a2 + 4 * (v3 >> 5) + 8) & (1 << (v3 & 0x1F))) != 0 )
{
*(_DWORD *)(a1 + 4 * (v26 >> 5) + 8) |= 1 << (v26 & 0x1F);
++v26;
}
else
{
*(_DWORD *)(a1 + 4 * (v26 >> 5) + 8) &= ~(1 << (v26 & 0x1F));
++v26;
}
}
}
else
{
v10 = 1 << (v24 & 0x1F);
v9 = a1 + 4 * (v24 >> 5) + 8;
if ( v6 )
{
*(_DWORD *)v9 |= v10;
++v24;
}
else
{
*(_DWORD *)v9 &= ~v10;
++v24;
}
}
}
else //这个else逻辑处理地方没用到,不用看这部分
{
if ( v4 % 3 && v4 != 20 )
{
if ( v4 & 1 || v4 == 16 )
{
v11 = (*(_DWORD *)(a2 + 4 * (v25 >> 5) + 8) & (1 << (v25 & 0x1F))) != 0;
++v25;
}
else
{
v11 = (*(_DWORD *)(a2 + 4 * (v26 >> 5) + 8) & (1 << (v26 & 0x1F))) != 0;
++v26;
}
}
else
{
v11 = (*(_DWORD *)(a2 + 4 * (v5 >> 5) + 8) & (1 << (v5 & 0x1F))) != 0;
v24 = v5 + 1;
}
if ( v11 )
*(_DWORD *)(a1 + 4 * (v23 >> 5) + 8) |= 1 << (v23 & 0x1F);
else
*(_DWORD *)(a1 + 4 * (v23 >> 5) + 8) &= ~(1 << (v23 & 0x1F));
}
++v23;
v3 = v23;
++v4;
if ( (signed int)v4 >= 21 )
break;
v5 = v24;
}
if ( v23 >= 105 )
break;
v5 = v24;
v4 = 0;
}
v12 = 107;
do
{
v14 = 1 << ((v12 - 2) & 0x1F);
v13 = 4 * ((v12 - 2) >> 5) + 8;
if ( v14 & *(_DWORD *)(v13 + a2) )
*(_DWORD *)(v13 + a1) |= v14;
else
*(_DWORD *)(v13 + a1) &= ~v14;
v16 = 1 << ((v12 - 1) & 0x1F);
v15 = 4 * ((v12 - 1) >> 5) + 8;
if ( v16 & *(_DWORD *)(v15 + a2) )
*(_DWORD *)(v15 + a1) |= v16;
else
*(_DWORD *)(v15 + a1) &= ~v16;
v17 = 1 << (v12 & 0x1F);
v18 = 4 * (v12 >> 5) + 8;
if ( v17 & *(_DWORD *)(v18 + a2) )
*(_DWORD *)(v18 + a1) |= v17;
else
*(_DWORD *)(v18 + a1) &= ~v17;
v20 = 1 << ((v12 + 1) & 0x1F);
v19 = 4 * ((v12 + 1) >> 5) + 8;
if ( v20 & *(_DWORD *)(v19 + a2) )
*(_DWORD *)(v19 + a1) |= v20;
else
*(_DWORD *)(v19 + a1) &= ~v20;
v22 = 1 << ((v12 + 2) & 0x1F);
result = 4 * ((v12 + 2) >> 5) + 8;
if ( v22 & *(_DWORD *)(result + a2) )
*(_DWORD *)(result + a1) |= v22;
else
*(_DWORD *)(result + a1) &= ~v22;
v12 += 5;
}
while ( v12 - 2 < 125 );
毫无疑问地说,11239100,11239400这两个地方逻辑是很繁琐很麻烦的,我当初也花了很多时间理解这两个过程,
但是各位读者想做出注册机,必须逆向理解这两个地方的算法,并加以调试分析。http://bbs.pediy.com/images/smilies/124.gif
回1123A190再进入11239CD0,很多干扰代码,经过我分析,只需看11239DB1到11239E10的代码,主要将处理结果返回给参数
11239DB1|.8B45 08 mov eax, dword ptr ss:
11239DB4|.C600 00 mov byte ptr ds:, 0
11239DB7|.F746 14 00200>test dword ptr ds:, 2000 ;以下检测第二次还原数组第13位
11239DBE|.74 03 je short 11239DC3 ;是否符合条件
11239DC0|.C600 01 mov byte ptr ds:, 1 ;加一
11239DC3|>D020 shl byte ptr ds:, 1 ;左移一位
11239DC5|.F746 14 00100>test dword ptr ds:, 1000 ;以下几步处理过程大致相同
11239DCC|.8A08 mov cl, byte ptr ds:
11239DCE|.74 05 je short 11239DD5
11239DD0|.80C1 01 add cl, 1
11239DD3|.8808 mov byte ptr ds:, cl
11239DD5|>D020 shl byte ptr ds:, 1
11239DD7|.F746 14 00080>test dword ptr ds:, 800
11239DDE|.8A08 mov cl, byte ptr ds:
11239DE0|.74 05 je short 11239DE7
11239DE2|.80C1 01 add cl, 1
11239DE5|.8808 mov byte ptr ds:, cl
11239DE7|>D020 shl byte ptr ds:, 1
11239DE9|.F746 14 00040>test dword ptr ds:, 400
11239DF0|.8A08 mov cl, byte ptr ds:
11239DF2|.74 05 je short 11239DF9
11239DF4|.80C1 01 add cl, 1
11239DF7|.8808 mov byte ptr ds:, cl
11239DF9|>D020 shl byte ptr ds:, 1
11239DFB|.F746 14 00020>test dword ptr ds:, 200
11239E02|.8A08 mov cl, byte ptr ds:
11239E04|.74 05 je short 11239E0B
11239E06|.80C1 01 add cl, 1
11239E09|.8808 mov byte ptr ds:, cl
11239E0B|>66:C702 0000mov word ptr ds:, 0
11239E10|.B8 7B000000 mov eax, 7B
11239E15|.C745 08 03000>mov dword ptr ss:, 3
11239E1C|.8D6424 00 lea esp, dword ptr ss:
回1123A190再进入11239EF0,与11239CD0相似很多干扰代码,只需看11239FB0到1123A030的代码,主要对压入的数组进行计算赋值
11239FB0|.33F6 xor esi, esi
11239FB2|.8858 08 mov byte ptr ds:, bl
11239FB5|.8970 34 mov dword ptr ds:, esi
11239FB8|.F742 0C 00000>test dword ptr ds:, 40000000
11239FBF|.74 03 je short 11239FC4
11239FC1|.8958 34 mov dword ptr ds:, ebx
11239FC4|>D160 34 shl dword ptr ds:, 1
11239FC7|.F742 0C 00000>test dword ptr ds:, 20000000
11239FCE|.8B48 34 mov ecx, dword ptr ds:
11239FD1|.74 05 je short 11239FD8
11239FD3|.03CB add ecx, ebx
11239FD5|.8948 34 mov dword ptr ds:, ecx
11239FD8|>8858 30 mov byte ptr ds:, bl
11239FDB|.8970 2C mov dword ptr ds:, esi
11239FDE|.F642 10 02 test byte ptr ds:, 2
11239FE2|.74 03 je short 11239FE7
11239FE4|.8958 2C mov dword ptr ds:, ebx
11239FE7|>D160 2C shl dword ptr ds:, 1 ;16位数组第9位的值直接影响到注册码的时间限制
11239FEA|.845A 10 test byte ptr ds:, bl ;测试第9位的值
11239FED|.8B48 2C mov ecx, dword ptr ds:
11239FF0|.74 05 je short 11239FF7
11239FF2|.03CB add ecx, ebx
11239FF4|.8948 2C mov dword ptr ds:, ecx
11239FF7|>D160 2C shl dword ptr ds:, 1
11239FFA|.F742 0C 00000>test dword ptr ds:, 80000000
1123A001|.8B48 2C mov ecx, dword ptr ds:
1123A004|.74 05 je short 1123A00B
1123A006|.03CB add ecx, ebx
1123A008|.8948 2C mov dword ptr ds:, ecx
1123A00B|>8858 28 mov byte ptr ds:, bl
1123A00E|.8970 04 mov dword ptr ds:, esi
1123A011|.F642 10 08 test byte ptr ds:, 8
1123A015|.74 03 je short 1123A01A
1123A017|.8958 04 mov dword ptr ds:, ebx
1123A01A|>D160 04 shl dword ptr ds:, 1
1123A01D|.F642 10 04 test byte ptr ds:, 4
1123A021|.8B48 04 mov ecx, dword ptr ds:
1123A024|.74 05 je short 1123A02B
1123A026|.03CB add ecx, ebx
1123A028|.8948 04 mov dword ptr ds:, ecx ;赋给时间数组,程序会判断该地址
1123A02B|>8970 24 mov dword ptr ds:, esi
1123A02E|.8818 mov byte ptr ds:, bl
1123A030|.BE 4E000000 mov esi, 4E
1123A035|.C745 FC 02000>mov dword ptr ss:, 2
1123A03C|.8D6424 00 lea esp, dword ptr ss:
回1123A190然后进入11238B30
11238B30/[ DISCUZ_CODE_65 ]nbsp; 55 push ebp
11238B31|.8BEC mov ebp, esp
11238B33|.83EC 20 sub esp, 20
11238B36|.B0 C0 mov al, 0C0
11238B38|.8845 EE mov byte ptr ss:, al
11238B3B|.8845 EF mov byte ptr ss:, al
11238B3E|.8B45 10 mov eax, dword ptr ss:
11238B41|.50 push eax ; /Arg6
11238B42|.8B45 08 mov eax, dword ptr ss: ; |
11238B45|.B1 BF mov cl, 0BF ; |
11238B47|.B2 C7 mov dl, 0C7 ; |
11238B49|.6A 20 push 20 ; |Arg5 = 00000020
11238B4B|.884D EC mov byte ptr ss:, cl ; |
11238B4E|.884D FF mov byte ptr ss:, cl ; |
11238B51|.8D4D E0 lea ecx, dword ptr ss: ; |
11238B54|.51 push ecx ; |Arg4
11238B55|.8855 E1 mov byte ptr ss:, dl ; |
11238B58|.8855 F8 mov byte ptr ss:, dl ; |
11238B5B|.8B55 0C mov edx, dword ptr ss: ; |
11238B5E|.52 push edx ; |Arg3
11238B5F|.6A 55 push 55 ; |Arg2 = 00000055
11238B61|.50 push eax ; |Arg1
11238B62|.C645 E0 7D mov byte ptr ss:, 7D ; |从开始是固定给112389A0处理的数组
11238B66|.C645 E2 89 mov byte ptr ss:, 89 ; |
11238B6A|.C645 E3 F9 mov byte ptr ss:, 0F9 ; |
11238B6E|.C645 E4 69 mov byte ptr ss:, 69 ; |
11238B72|.C645 E5 5D mov byte ptr ss:, 5D ; |
11238B76|.C645 E6 71 mov byte ptr ss:, 71 ; |
11238B7A|.C645 E7 90 mov byte ptr ss:, 90 ; |
11238B7E|.C645 E8 FA mov byte ptr ss:, 0FA ; |
11238B82|.C645 E9 84 mov byte ptr ss:, 84 ; |
11238B86|.C645 EA 22 mov byte ptr ss:, 22 ; |
11238B8A|.C645 EB CA mov byte ptr ss:, 0CA ; |
11238B8E|.C645 ED 1D mov byte ptr ss:, 1D ; |
11238B92|.C645 F0 88 mov byte ptr ss:, 88 ; |
11238B96|.C645 F1 42 mov byte ptr ss:, 42 ; |
11238B9A|.C645 F2 37 mov byte ptr ss:, 37 ; |
11238B9E|.C645 F3 D5 mov byte ptr ss:, 0D5 ; |
11238BA2|.C645 F4 70 mov byte ptr ss:, 70 ; |
11238BA6|.C645 F5 80 mov byte ptr ss:, 80 ; |
11238BAA|.C645 F6 2E mov byte ptr ss:, 2E ; |
11238BAE|.C645 F7 83 mov byte ptr ss:, 83 ; |
11238BB2|.C645 F9 92 mov byte ptr ss:, 92 ; |
11238BB6|.C645 FA A3 mov byte ptr ss:, 0A3 ; |
11238BBA|.C645 FB 59 mov byte ptr ss:, 59 ; |
11238BBE|.C645 FC C6 mov byte ptr ss:, 0C6 ; |
11238BC2|.C645 FD 95 mov byte ptr ss:, 95 ; |
11238BC6|.C645 FE 24 mov byte ptr ss:, 24 ; |
11238BCA|.E8 D1FDFFFF call 112389A0 ; \vmwareba.112389A0
11238BCF|.83C4 18 add esp, 18
11238BD2|.8BE5 mov esp, ebp
11238BD4|.5D pop ebp
11238BD5\.C3 retn
固定要sha的数组,长度0x20,如下:
0529F4E87D C7 89 F9 69 5D 71 90 FA 84 22 CA BF 1D C0 C0
0529F4F888 42 37 D5 70 80 2E 83 C7 92 A3 59 C6 95 24 BF
进入112389A0,sha 初始化处理,sha update处理,sha finalize处理不作说明,可到看雪论坛查阅,算法处理如下,
112389A0/[ DISCUZ_CODE_39 ]nbsp; 55 push ebp
112389A1|.8BEC mov ebp, esp
112389A3|.81EC 80000000 sub esp, 80
112389A9|.56 push esi
112389AA|.8B75 0C mov esi, dword ptr ss:
112389AD|.83C6 07 add esi, 7
112389B0|.C1EE 03 shr esi, 3
112389B3|.57 push edi
112389B4|.56 push esi ; /size
112389B5|.8975 0C mov dword ptr ss:, esi ; |
112389B8|.FF15 8C263911 call dword ptr ds:[<&MSVCR80.malloc>] ; \malloc
112389BE|.8BF8 mov edi, eax
112389C0|.83C4 04 add esp, 4
112389C3|.85FF test edi, edi
112389C5|.0F84 4B010000 je 11238B16
112389CB|.33C0 xor eax, eax
112389CD|.85F6 test esi, esi
112389CF|.53 push ebx
112389D0|.0F86 D3000000 jbe 11238AA9
112389D6|.C745 F8 2E000>mov dword ptr ss:, 2E
112389DD|.8D49 00 lea ecx, dword ptr ds:
112389E0|>8B75 F8 /mov esi, dword ptr ss: ;以下是循环分离出第二次还原数据最后11位
112389E3|.C60438 00 |mov byte ptr ds:, 0 ;跟1123A200的代码相似,存在迷惑解密者的嫌疑
112389E7|.C745 F4 02000>|mov dword ptr ss:, 2
112389EE|.8BFF |mov edi, edi
112389F0|>D02438 |/shl byte ptr ds:, 1
112389F3|.8D56 01 ||lea edx, dword ptr ds:
112389F6|.8BCA ||mov ecx, edx
112389F8|.83E1 1F ||and ecx, 1F
112389FB|.BB 01000000 ||mov ebx, 1
11238A00|.D3E3 ||shl ebx, cl
11238A02|.C1FA 05 ||sar edx, 5
11238A05|.8BCB ||mov ecx, ebx
11238A07|.8B5D 08 ||mov ebx, dword ptr ss:
11238A0A|.854C93 08 ||test dword ptr ds:, ec>
11238A0E|.74 09 ||je short 11238A19
11238A10|.8A0C38 ||mov cl, byte ptr ds:
11238A13|.80C1 01 ||add cl, 1
11238A16|.880C38 ||mov byte ptr ds:, cl
11238A19|>D02438 ||shl byte ptr ds:, 1
11238A1C|.8BCE ||mov ecx, esi
11238A1E|.83E1 1F ||and ecx, 1F
11238A21|.BA 01000000 ||mov edx, 1
11238A26|.D3E2 ||shl edx, cl
11238A28|.8BCE ||mov ecx, esi
11238A2A|.C1F9 05 ||sar ecx, 5
11238A2D|.85548B 08 ||test dword ptr ds:, ed>
11238A31|.74 09 ||je short 11238A3C
11238A33|.8A0C38 ||mov cl, byte ptr ds:
11238A36|.80C1 01 ||add cl, 1
11238A39|.880C38 ||mov byte ptr ds:, cl
11238A3C|>D02438 ||shl byte ptr ds:, 1
11238A3F|.8D56 FF ||lea edx, dword ptr ds:
11238A42|.8BCA ||mov ecx, edx
11238A44|.83E1 1F ||and ecx, 1F
11238A47|.BB 01000000 ||mov ebx, 1
11238A4C|.D3E3 ||shl ebx, cl
11238A4E|.8B4D 08 ||mov ecx, dword ptr ss:
11238A51|.C1FA 05 ||sar edx, 5
11238A54|.855C91 08 ||test dword ptr ds:, eb>
11238A58|.74 09 ||je short 11238A63
11238A5A|.8A0C38 ||mov cl, byte ptr ds:
11238A5D|.80C1 01 ||add cl, 1
11238A60|.880C38 ||mov byte ptr ds:, cl
11238A63|>D02438 ||shl byte ptr ds:, 1
11238A66|.8D56 FE ||lea edx, dword ptr ds:
11238A69|.8BCA ||mov ecx, edx
11238A6B|.83E1 1F ||and ecx, 1F
11238A6E|.BB 01000000 ||mov ebx, 1
11238A73|.D3E3 ||shl ebx, cl
11238A75|.8B4D 08 ||mov ecx, dword ptr ss:
11238A78|.C1FA 05 ||sar edx, 5
11238A7B|.855C91 08 ||test dword ptr ds:, eb>
11238A7F|.74 09 ||je short 11238A8A
11238A81|.8A0C38 ||mov cl, byte ptr ds:
11238A84|.80C1 01 ||add cl, 1
11238A87|.880C38 ||mov byte ptr ds:, cl
11238A8A|>83EE 04 ||sub esi, 4
11238A8D|.836D F4 01 ||sub dword ptr ss:, 1
11238A91|.^ 0F85 59FFFFFF |\jnz 112389F0
11238A97|.8B75 0C |mov esi, dword ptr ss:
11238A9A|.8345 F8 08 |add dword ptr ss:, 8
11238A9E|.83C0 01 |add eax, 1
11238AA1|.3BC6 |cmp eax, esi
11238AA3|.^ 0F82 37FFFFFF \jb 112389E0
11238AA9|>8D55 80 lea edx, dword ptr ss:
11238AAC|.52 push edx ;edx为sha的数据结构
11238AAD|.E8 6E93EDFF call #207 ;sha 初始化
11238AB2|.56 push esi ; |esi为edi的长度
11238AB3|.8D45 80 lea eax, dword ptr ss: ; |
11238AB6|.57 push edi ; |edi为分离出的11位数组
11238AB7|.50 push eax ; |edx为sha的数据结构
11238AB8|.E8 A393EDFF call #206 ; \sha update 11位值
11238ABD|.8B75 10 mov esi, dword ptr ss:
11238AC0|.8BC6 mov eax, esi
11238AC2|.83C4 10 add esp, 10
11238AC5|.8D50 01 lea edx, dword ptr ds:
11238AC8|>8A08 /mov cl, byte ptr ds:
11238ACA|.83C0 01 |add eax, 1
11238ACD|.84C9 |test cl, cl
11238ACF|.^ 75 F7 \jnz short 11238AC8
11238AD1|.2BC2 sub eax, edx
11238AD3|.50 push eax ;eax为esi的长度
11238AD4|.8D4D 80 lea ecx, dword ptr ss:
11238AD7|.56 push esi ;esi为11234201代码处返回的数组,11234201位于注册算法开始的地方
11238AD8|.51 push ecx ;ecx为sha的数据结构
11238AD9|.E8 8293EDFF call #206 ;sha update 循环提供的常量数组
11238ADE|.8B75 18 mov esi, dword ptr ss:
11238AE1|.8B5D 14 mov ebx, dword ptr ss:
11238AE4|.56 push esi ;esi为ebx的长度
11238AE5|.8D55 80 lea edx, dword ptr ss:
11238AE8|.53 push ebx ;ebx为上层11238B62代码处提供的数组
11238AE9|.52 push edx ;ecx为sha的数据结构
11238AEA|.E8 7193EDFF call #206 ;sha update 固定数组
11238AEF|.8D45 80 lea eax, dword ptr ss:
11238AF2|.50 push eax
11238AF3|.8D4D DC lea ecx, dword ptr ss:
11238AF6|.51 push ecx ;ecx为hash后返回数组地址
11238AF7|.E8 243CF1FF call #205 ;sha final处理
11238AFC|.56 push esi ; |/n = 20 (32.)
11238AFD|.6A 00 push 0 ; ||c = 00
11238AFF|.53 push ebx ; ||s
11238B00|.E8 7BB90F00 call <jmp.&MSVCR80.memset> ; |\memset
11238B05|.8B75 1C mov esi, dword ptr ss: ; |
11238B08|.6A 28 push 28 ; |Arg1 = 00000028
11238B0A|.8D4D DC lea ecx, dword ptr ss: ; |
11238B0D|.E8 EEFDFFFF call 11238900 ; \这个函数比较简单,对hash后的20位值
11238B12|.83C4 30 add esp, 30 ;通过处理,异或转变为5位数值存入到esi的地址
11238B15|.5B pop ebx
11238B16|>57 push edi ; /block
11238B17|.FF15 BC253911 call dword ptr ds:[<&MSVCR80.free>] ; \free
11238B1D|.83C4 04 add esp, 4
11238B20|.5F pop edi
11238B21|.5E pop esi
11238B22|.8BE5 mov esp, ebp
11238B24|.5D pop ebp
11238B25\.C3 retn
入11238900,通过ida分析的代码如下:
v4 = (unsigned __int8)(*(_BYTE *)(a1 + 4) ^ *(_BYTE *)(a1 + 9) ^ *(_BYTE *)(a1 + 14) ^ *(_BYTE *)(a1 + 19));
HIDWORD(v5) = (unsigned __int64)(v4 << 8) >> 32;
LODWORD(v5) = (unsigned __int8)(*(_BYTE *)(a1 + 3) ^ *(_BYTE *)(a1 + 8) ^ *(_BYTE *)(a1 + 13) ^ *(_BYTE *)(a1 + 18)) | ((_DWORD)v4 << 8);
HIDWORD(v5) = (unsigned __int64)(v5 << 8) >> 32;
LODWORD(v5) = (unsigned __int8)(*(_BYTE *)(a1 + 2) ^ *(_BYTE *)(a1 + 7) ^ *(_BYTE *)(a1 + 12) ^ *(_BYTE *)(a1 + 17)) | ((_DWORD)v5 << 8);
HIDWORD(v5) = (unsigned __int64)(v5 << 8) >> 32;
LODWORD(v5) = (unsigned __int8)(*(_BYTE *)(a1 + 1) ^ *(_BYTE *)(a1 + 6) ^ *(_BYTE *)(a1 + 11) ^ *(_BYTE *)(a1 + 16)) | ((_DWORD)v5 << 8);
result = (unsigned __int8)(*(_BYTE *)a1 ^ *(_BYTE *)(a1 + 5) ^ *(_BYTE *)(a1 + 10) ^ *(_BYTE *)(a1 + 15));
*(_DWORD *)a2 = result | ((_DWORD)v5 << 8);
*(_DWORD *)(a2 + 4) = (unsigned __int64)(v5 << 8) >> 32;
简单来说,就是sha后的20位值分别进行异或,产生5位的值,对压入11238b30第三个地址赋值,至此返回到1123A2E7,判断对比ebx,edi的值是否相同。
然后程序再返回到11234286,再到11233D80来判断时间数组,进入11233D80
11233E4A|.8B93 10020000 mov edx, dword ptr ds:
11233E50|.52 push edx ; /Arg2
11233E51|.56 push esi ; |Arg1
11233E52|.E8 19EEEDFF call 11112C70 ; \vmwareba.11112C70
11233E57|.83C4 08 add esp, 8
11233E5A|>80BB EC010000>cmp byte ptr ds:, 0 ;前2 4字节随便为0
11233E61|.0F84 56030000 je 112341BD
11233E67|.83BB F0010000>cmp dword ptr ds:, 0 ;判断该位是否为0,不为0有时间限制,0没时间限制
11233E6E|.0F86 49030000 jbe 112341BD
11233D80其他的代码不多说,这里只说11233E67,主要是11239EF0作处理的,可参考之前11239EF0的说明。
【软件加密思路】
1:在一个循环中,分别获取注册码,在索引数组中获取索引值,根据索引值获取注册码的值,计算注册码在固定数组中的位置为Index,
转换数组A循环从0x7C位开始到0位结束,每一循环处理5位,每一次判断Index低位为1时,对其数组A置1,否则不作处理,然后Index右
移一位。
2:根据步骤1数组A进行处理,循环控制从0到105位之间的处理,分别获取当前位数的值C,内循环控制0到20位,分别对3求余,然后根据
求余的值,去到新数组B ,从0,40,80位开始的索引范围内,然后根据值C判断是否对数组B当前位置1,然后索引加一,最后从107位开
始到128位,直接原值到B数组。
3:经过上述两步后,还原出数组B,然后经过0x11239CD0的处理,获取第14位的值,判断是否在合理值范围内。
4:根据数组B,然后经过0x11239CD0的处理,判断第9位的值,是否有时间限制,产生时间数组C。
5:分离前5位 ,后11位, 对 (11位字节 + 注册算法循环提供的固定字节数组 + 算法内sha固定字节数组) 进行sha散列。sha后的20位
值分别进行call 11238900异或处理,产生5位的新值,然后与之前的前5位比较,是否相同。
6:对时间数组C进行计算,计算限制日期,至此,完成注册过程。
【逆向解密思路】
1:随机产生11位字节,第4位为日期验证值,要求为0,第9位为范围验证值,异或0x1F,第11位为0到0x1f。
2:对(11位字节 + 注册算法循环提供的固定字节数组 + 算法内sha固定字节数组) 进行sha散列。
3:sha后的20位值分别进行call 11238900异或处理,产生5位的值,然后跟11位字节组合,产生16位字节。
4:第一次还原操作,还原3步骤后的16位数组,两个循环,第一个循环控制0到20位,分别对3求余,然后根据求余的值,分别判断其从0,
40,80位开始的值是否为1,然后写入第二个循环的0到105位的新数组范围内,最后,从107位开始到128位,直接复制值。
5:还原到原始key值,根据4步骤后的数组进行操作,用一个循环,循环从0x7C开始到0结束,每一次获取5位,转换为其key值,用key值根
据其数组获取数字值,在循环中获取数组索引 ,然后写入数字值到相应数组位置中。
【经验总结】
发觉软件的加密者擅长用位操作,给解密者带来一定困难,还有验证地方也不少,需要很大的耐性和恒心,不过做出注册机还是一件很兴奋的事!http://bbs.pediy.com/images/smilies/wink.gif
【版权声明】
本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!
2011 年 3月 6日by Daniel
谢分享 顶楼主下 呵呵 学习了。。{:1_921:} 好厉害,VM7.1.3占内存太大,还是6.x的好用些。 太棒了地方法 感谢分享!!下载了``` 支持发布原创破文
感谢分享哈 回复 风吹屁屁凉 的帖子
此贴必火
顶起 感谢分享,受教了。 这个这么长啊看懂了一点点 还得努力啊