不慌不忙V2.51 爆破及注册算法分析(By torjan at 2011-11-1)
本帖最后由 torjan 于 2011-11-17 21:11 编辑敝人处女破,不足之处,请大家见谅
打开软件算变输入用户名和密码;出现 “您输入的注册码有误” 的提示框 ,这个时候在OD里按F12,然后调出 调用堆栈
0012E6A8
0012E6B0 000708A8 hOwner = 000708A8 ('注册',class='#32770',parent=00080876)
0012E6B4 002928F0 Text = "您输入的注册码有误!"
0012E6B8 0040C190 Title = "不慌不忙 v2.51"
0012E6BC 00000000 Style = MB_OK|MB_APPLMODAL
0012E6C0 00000000 LanguageID = 0 (LANG_NEUTRAL)
0012E6C8 69D9F3DD USER32.MessageBoxA MFC42.69D9F3D7 0012E6C4
0012E6CC 000708A8 hOwner = 000708A8 ('注册',class='#32770',parent=00080876)
0012E6D0 002928F0 Text = "您输入的注册码有误!"
0012E6D4 0040C190 Title = "不慌不忙 v2.51"
0012E6D8 00000000 Style = MB_OK|MB_APPLMODAL
0012E6E4 00402C4D <jmp.&MFC42.#4224> Unhurrie.00402C48 //双击这个 0012E6E0
0012E6E8 002928F0 Arg1 = 002928F0
双击最后一个就来到调用MessageBox的call了
00402C45 50 push eax
00402C46 8BCE mov ecx,esi
00402C48 E8 89490000 call <jmp.&MFC42.#4224> ; 调用messagebox输出出错信息的call
00402C4D 8D4C24 14 lea ecx,dword ptr ss:
00402C51 885C24 68 mov byte ptr ss:,bl
然后向上可以看到写注册表的信息,最重要的是找到关键跳。还有计算比较的一些Call
00402A61 E8 464B0000 call <jmp.&MFC42.#860>
00402A66 8B96 10010000 mov edx,dword ptr ds:
00402A6C 837A F8 17 cmp dword ptr ds:,17 ; 序列号个数必须等于23个
00402A70 0F85 83010000 jnz Unhurrie.00402BF9
00402A76 8D4424 10 lea eax,dword ptr ss:
00402A7A 57 push edi
00402A7B 50 push eax
00402A7C 8BCE mov ecx,esi
00402A7E E8 1D020000 call Unhurrie.00402CA0 ; 计算真码的call, 跟进去是真码算法
00402A83 50 push eax
00402A84 8D4C24 10 lea ecx,dword ptr ss:
00402A88 C64424 6C 02 mov byte ptr ss:,2
00402A8D E8 624B0000 call <jmp.&MFC42.#858>
00402A92 8D4C24 10 lea ecx,dword ptr ss:
00402A96 885C24 68 mov byte ptr ss:,bl
00402A9A E8 014B0000 call <jmp.&MFC42.#800>
00402A9F 8B4C24 0C mov ecx,dword ptr ss:
00402AA3 8B86 10010000 mov eax,dword ptr ds:
00402AA9 51 push ecx
00402AAA 50 push eax
00402AAB FF15 24934000 call dword ptr ds:[<&MSVCRT._mbscmp>] ; 比较真假码的call
00402AB1 83C4 08 add esp,8
00402AB4 85C0 test eax,eax
00402AB6 0F85 9E010000 jnz Unhurrie.00402C5A ; 关键跳转
00402ABC 8D5424 10 lea edx,dword ptr ss:
00402AC0 52 push edx
00402AC1 68 06000200 push 20006
注意输入的假码必须是23位,一般在比较真码的时候可以在堆栈里看到真码,至此可以用内存注册机编写注册机了下面是真码生成的算法分析:重要算法1:根据用户名,计算出4个余数C表示为:str保存用户名float val; long res1 = 5, res2 = 2, res3, res4;for (int i = 1; i < len ; i++){
val = str*1.0;
res1 = 的开平方 * i+ 1 ) + res1] % 10 0000;
res2 = % 10 0000;
res3 = 的开平方 + res2] % 10 0000;
res4 = 的开平方] % 10 0000;}
00402CFB 8B11 mov edx,dword ptr ds: ; 取得用户名的指针
00402CFD 83C9 FF or ecx,FFFFFFFF
00402D00 8BFA mov edi,edx
00402D02 897424 48 mov dword ptr ss:,esi
00402D06 F2:AE repne scas byte ptr es:
00402D08 F7D1 not ecx
00402D0A 49 dec ecx ; 得到用户名的长度
00402D0B BD 02000000 mov ebp,2 ; 2初始参数
00402D10 BB 09000000 mov ebx,9 ; 9初始参数
00402D15 C74424 1C 04000000 mov dword ptr ss:,4
00402D1D 895424 18 mov dword ptr ss:,edx
00402D21 8BF9 mov edi,ecx
00402D23 0F84 49020000 je Unhurrie.00402F72
00402D29 3BFE cmp edi,esi
00402D2B 897424 54 mov dword ptr ss:,esi
00402D2F 0F8C CA000000 jl Unhurrie.00402DFF
00402D35 DD05 C0994000 fld qword ptr ds: ; 5初始参数
00402D3B EB 04 jmp short Unhurrie.00402D41
00402D3D 8B5424 18 mov edx,dword ptr ss:
00402D41 8A5C32 FF mov bl,byte ptr ds: ; 取得用户名第i个字符
00402D45 DB4424 54 fild dword ptr ss:
00402D49 0FBED3 movsx edx,bl
00402D4C DD5C24 1C fstp qword ptr ss:
00402D50 895424 54 mov dword ptr ss:,edx
00402D54 DB4424 54 fild dword ptr ss:
00402D58 0FBEC3 movsx eax,bl
00402D5B D9FA fsqrt
00402D5D 0FAFC6 imul eax,esi
00402D60 DC4C24 1C fmul qword ptr ss:
00402D64 DC05 B8994000 fadd qword ptr ds:
00402D6A 0FAFC6 imul eax,esi
00402D6D 894424 54 mov dword ptr ss:,eax
00402D71 DB4424 54 fild dword ptr ss:
00402D75 DEC9 fmulp st(1),st
00402D77 D8C1 fadd st,st(1)
00402D79 E8 584A0000 call <jmp.&MSVCRT._ftol> ;(str*i*i)*(str的开平方*i+1)+b, b第一次为5,以后为上一次的余数1
00402D7E 99 cdq
00402D7F DDD8 fstp st
00402D81 B9 A0860100 mov ecx,186A0
00402D86 F7F9 idiv ecx
00402D88 895424 14 mov dword ptr ss:,edx ; 得到余数1
00402D8C 0FBED3 movsx edx,bl
00402D8F 895424 54 mov dword ptr ss:,edx
00402D93 DB4424 54 fild dword ptr ss:
00402D97 DD05 B0994000 fld qword ptr ds:
00402D9D E8 2E4A0000 call <jmp.&MSVCRT._CIpow> ; 计算str * str
00402DA2 DC4C24 1C fmul qword ptr ss: ; (str * str) * i
00402DA6 E8 2B4A0000 call <jmp.&MSVCRT._ftol> ; (str * str) * i ==> long
00402DAB DB4424 14 fild dword ptr ss:
00402DAF 8BCE mov ecx,esi
00402DB1 0FAFCD imul ecx,ebp ; ebp来自于上一次的余数2, 初始值为2
00402DB4 D9C0 fld st
00402DB6 D9FA fsqrt ; 余数1开平方
00402DB8 03C1 add eax,ecx ; (str * str) * i + i*ebp
00402DBA B9 A0860100 mov ecx,186A0
00402DBF 99 cdq
00402DC0 F7F9 idiv ecx
00402DC2 8BEA mov ebp,edx ; 余数2保存到ebp
00402DC4 896C24 54 mov dword ptr ss:,ebp ; 余数2保存
00402DC8 E8 094A0000 call <jmp.&MSVCRT._ftol>
00402DCD DB4424 54 fild dword ptr ss:
00402DD1 03C5 add eax,ebp ; 余数1的开平方 + 余数2
00402DD3 B9 A0860100 mov ecx,186A0
00402DD8 99 cdq
00402DD9 D9FA fsqrt ; 余数2开平方
00402DDB F7F9 idiv ecx ; (余数1的开平方 + 余数2) / 186A0
00402DDD 8BDA mov ebx,edx ; 得到余数3
00402DDF E8 F2490000 call <jmp.&MSVCRT._ftol>
00402DE4 03C3 add eax,ebx ; 余数3+余数2的开平方
00402DE6 B9 A0860100 mov ecx,186A0
00402DEB 99 cdq
00402DEC F7F9 idiv ecx ; (余数3+余数2的开平方)/186A0 得到余数4保存在EDX
00402DEE 46 inc esi
00402DEF 3BF7 cmp esi,edi
00402DF1 897424 54 mov dword ptr ss:,esi
00402DF5^ 0F8E 42FFFFFF jle Unhurrie.00402D3D ; 重要的循环,对输入的用户名进行计算,得到4个余数
00402DFB DDD8 fstp st
00402DFD EB 04 jmp short Unhurrie.00402E03
重要算法2:根据上面计算得到的4个余数,依次算出真码真码保存地址:result;long val;for (i = 1; i <5 ; i ++){ long res = resi;//第i个余数 for (j = 0; j < 5) { int k = (i-1)*5+j; val = (k*k*k + res + 0x1F) & 0x8000007F; if(val < 0) {
val -- ;
val |= 0Xffffff80;
val++; } result = val;}}
00402DFF 8B5424 1C mov edx,dword ptr ss:
00402E03 33C0 xor eax,eax
00402E05 8BC8 mov ecx,eax
00402E07 8B7424 14 mov esi,dword ptr ss:
00402E0B 0FAFC8 imul ecx,eax
00402E0E 0FAFC8 imul ecx,eax
00402E11 8D4C31 1F lea ecx,dword ptr ds: ; esi为最后一次的余数1
00402E15 81E1 7F000080and ecx,8000007F
00402E1B 79 05 jns short Unhurrie.00402E22
00402E1D 49 dec ecx
00402E1E 83C9 80 or ecx,FFFFFF80
00402E21 41 inc ecx
00402E22 884C04 28 mov byte ptr ss:,cl
00402E26 40 inc eax
00402E27 83F8 05 cmp eax,5
00402E2A^ 7C D9 jl short Unhurrie.00402E05 ; 真码的第一个五个字符由余数1按一定算法得到
00402E2C B8 05000000 mov eax,5
00402E31 8BC8 mov ecx,eax
00402E33 0FAFC8 imul ecx,eax
00402E36 0FAFC8 imul ecx,eax
00402E39 8D4C29 1F lea ecx,dword ptr ds: ; ebp为最后一次的余数2
00402E3D 81E1 7F000080 and ecx,8000007F
00402E43 79 05 jns short Unhurrie.00402E4A
00402E45 49 dec ecx
00402E46 83C9 80 or ecx,FFFFFF80
00402E49 41 inc ecx
00402E4A 884C04 28 mov byte ptr ss:,cl
00402E4E 40 inc eax
00402E4F 83F8 0A cmp eax,0A
00402E52^ 7C DD jl short Unhurrie.00402E31 ; 真码的第2个五个字符由余数2按一定算法得到
00402E54 B8 0A000000 mov eax,0A
00402E59 8BC8 mov ecx,eax
00402E5B 0FAFC8 imul ecx,eax
00402E5E 0FAFC8 imul ecx,eax
00402E61 8D4C19 1F lea ecx,dword ptr ds: ; ebx为余数3
00402E65 81E1 7F000080and ecx,8000007F
00402E6B 79 05 jns short Unhurrie.00402E72
00402E6D 49 dec ecx
00402E6E 83C9 80 or ecx,FFFFFF80
00402E71 41 inc ecx
00402E72 884C04 28 mov byte ptr ss:,cl
00402E76 40 inc eax
00402E77 83F8 0F cmp eax,0F
00402E7A^ 7C DD jl short Unhurrie.00402E59 ; 真码的第3个五个字符由余数3按一定算法得到
00402E7C B8 0F000000 mov eax,0F
00402E81 8BC8 mov ecx,eax
00402E83 0FAFC8 imul ecx,eax
00402E86 0FAFC8 imul ecx,eax
00402E89 8D4C11 1F lea ecx,dword ptr ds: ; edx为余数4
00402E8D 81E1 7F000080and ecx,8000007F
00402E93 79 05 jns short Unhurrie.00402E9A
00402E95 49 dec ecx
00402E96 83C9 80 or ecx,FFFFFF80
00402E99 41 inc ecx
00402E9A 884C04 28 mov byte ptr ss:,cl
00402E9E 40 inc eax
00402E9F 83F8 14 cmp eax,14
00402EA2^ 7C DD jl short Unhurrie.00402E81 ; 真码的第4个五个字符由余数4按一定算法得到
00402EA4 33D2 xor edx,edx
上面4个就是计算真码4个段的过程重要算法3:把result中不在 的字符转变到这个范围里int j = 0;for (int i= 0; i< 20; i++){ While( result not in ) { result = ( result+j+1F ) & 0X8000007F;
if(result < 0) {
result--;
result |=0Xffffff80;
result++; } } j += 7;}
00402EAD 8A4414 28 mov al,byte ptr ss:
00402EB1 3C 30 cmp al,30
00402EB3 7C 04 jl short Unhurrie.00402EB9
00402EB5 3C 39 cmp al,39
00402EB7 7E 29 jle short Unhurrie.00402EE2 ; 如果在 0 - 9之间就跳
00402EB9 3C 41 cmp al,41
00402EBB 7C 04 jl short Unhurrie.00402EC1
00402EBD 3C 5A cmp al,5A
00402EBF 7E 21 jle short Unhurrie.00402EE2 ; 如果在 A- Z之间则跳
00402EC1 3C 61 cmp al,61
00402EC3 7C 04 jl short Unhurrie.00402EC9
00402EC5 3C 7A cmp al,7A
00402EC7 7E 19 jle short Unhurrie.00402EE2 ; 如果在 a - z之间则跳
00402EC9 0FBEC0 movsx eax,al ; 否则经过特殊处理
00402ECC 8D4408 1F lea eax,dword ptr ds:
00402ED0 25 7F000080 and eax,8000007F
00402ED5 79 05 jns short Unhurrie.00402EDC
00402ED7 48 dec eax
00402ED8 83C8 80 or eax,FFFFFF80
00402EDB 40 inc eax
00402EDC 884414 28 mov byte ptr ss:,al
00402EE0^ EB CB jmp short Unhurrie.00402EAD ; 处理过后重新比较
00402EE2 83C1 07 add ecx,7
00402EE5 42 inc edx
00402EE6 81F9 8C000000cmp ecx,8C
00402EEC^ 7C BF jl short Unhurrie.00402EAD ; 20个字符处理完毕的判断
重要算法4:就是对result的进行处理处理1
0 è2
oèq
OèQ
1è3
lèn
LèN处理2
将小写字符转换为大写字符处理3
在每5个字符之间添加 “-” 例如 AB23MRLWKE432SDKJ3J2 è AB23M-RLWKE-432SD-KJ3J2
00402EEE 33C9 xor ecx,ecx
00402EF0 8A440C 28 mov al,byte ptr ss:
00402EF4 3C 30 cmp al,30
00402EF6 74 14 je short Unhurrie.00402F0C
00402EF8 3C 6F cmp al,6F
00402EFA 74 10 je short Unhurrie.00402F0C
00402EFC 3C 4F cmp al,4F
00402EFE 74 0C je short Unhurrie.00402F0C
00402F00 3C 31 cmp al,31
00402F02 74 08 je short Unhurrie.00402F0C
00402F04 3C 4C cmp al,4C
00402F06 74 04 je short Unhurrie.00402F0C
00402F08 3C 6C cmp al,6C
00402F0A 75 06 jnz short Unhurrie.00402F12
00402F0C 04 02 add al,2
00402F0E 88440C 28 mov byte ptr ss:,al
00402F12 41 inc ecx
00402F13 83F9 14 cmp ecx,14
00402F16^ 7C D8 jl short Unhurrie.00402EF0 ; 循环检查 将真码中的 0,O,o, 1, L, l, 变为2, Q, q, 3, N, n
00402F18 33C9 xor ecx,ecx
00402F1A 8A440C 28 mov al,byte ptr ss:
00402F1E 3C 61 cmp al,61
00402F20 7C 0A jl short Unhurrie.00402F2C
00402F22 3C 7A cmp al,7A
00402F24 7F 06 jg short Unhurrie.00402F2C
00402F26 2C 20 sub al,20
00402F28 88440C 28 mov byte ptr ss:,al
00402F2C 41 inc ecx
00402F2D 83F9 14 cmp ecx,14
00402F30^ 7C E8 jl short Unhurrie.00402F1A ; 循环检查 将真码中的小写字母变大写
00402F32 8D4C24 28 lea ecx,dword ptr ss:
00402F36 8D5424 10 lea edx,dword ptr ss:
00402F3A 51 push ecx
00402F3B 68 DCC24000 push Unhurrie.0040C2DC ; ASCII "%s"
00402F40 52 push edx
00402F41 E8 26470000call <jmp.&MFC42.#2818> ; 不晓得干嘛的
00402F46 83C4 0C add esp,0C
00402F49 8D4C24 10 lea ecx,dword ptr ss:
00402F4D 6A 2D push 2D
00402F4F 6A 05 push 5
00402F51 E8 10470000call <jmp.&MFC42.#6778> ; 添加真码中的第1个 “-”
00402F56 6A 2D push 2D
00402F58 6A 0B push 0B
00402F5A 8D4C24 18 lea ecx,dword ptr ss:
00402F5E E8 03470000 call <jmp.&MFC42.#6778> ; 添加真码中的第2个 “-”
00402F63 6A 2D push 2D
00402F65 6A 11 push 11
00402F67 8D4C24 18 lea ecx,dword ptr ss:
00402F6B E8 F6460000 call <jmp.&MFC42.#6778> ; 添加真码中的第3个 “-”
00402F70 EB 0E jmp short Unhurrie.00402F80
至此,算法分析完毕,个人比较懒,用工具生成了一个内存注册机。
前排支持,很详细的分析 一如既往的支持! 分析的不错,算法在哪学的?我对不太会分析算法 太强悍了菜鸟看不懂 支持 学习 尼玛,我表示还是看不懂 算法。 太强悍了看不懂菜鸟飘过{:1_937:} 太强悍了菜鸟看不懂 强悍的分析啊,本人数学不及格啊{:1_908:}