作者语:由于本人乃一介菜鸟,叙述过程如有纰漏还请大家指出。
思路:
第一步:运行程序,找到出错时的的提示,如图所示
第二步:用ollydbg加载程序,再根据出错提示,找到判断语句,以及计算序列号的算法函数。如图所示
可能有人要问是咋找到这函数的,其实这很简单。在出错函数的上面找到转跳语句,再在它的上面不远处下一断点,然后执行到断点处,再单步执行,这时注意观察堆栈变化。如果是采用明文比较的方法,那么计算出的注册码迟早会出现在堆栈。filebus就是采用明文比较的办法。所很好找的。注册码出现在堆栈时的情况:
如果只是想找注册码,到这就行了。如果只是想搞爆破到这也就行了。不用分析。
第三步:算法分析,先看如下代码:
00407E22 /$ 55 push ebp ;
00407E23 |. 8BEC mov ebp, esp
00407E25 |. 6A FF push -1 ;
00407E27 |. 68 C3F74400 push 0044F7C3 ; SE 处理程序安装
00407E2C |. 64:A1 0000000> mov eax, dword ptr fs:[0]
00407E32 |. 50 push eax
00407E33 |. 64:8925 00000> mov dword ptr fs:[0], esp
00407E3A |. 83EC 54 sub esp, 54 ; 为局部变量开辟空间
00407E3D |. 56 push esi
00407E3E |. C745 C8 00000> mov dword ptr [ebp-38], 0
00407E45 |. C645 E0 00 mov byte ptr [ebp-20], 0
00407E49 |. 33C0 xor eax, eax
00407E4B |. 8945 E1 mov dword ptr [ebp-1F], eax ; 变量初始化
00407E4E |. 8945 E5 mov dword ptr [ebp-1B], eax
00407E51 |. 8945 E9 mov dword ptr [ebp-17], eax
00407E54 |. 66:8945 ED mov word ptr [ebp-13], ax
00407E58 |. 8845 EF mov byte ptr [ebp-11], al
00407E5B |. 68 0C9C4600 push 00469C0C
00407E60 |. 8D4D F0 lea ecx, dword ptr [ebp-10]
00407E63 |. E8 B4C60300 call 0044451C ; 函数功能还不确定,该函数我跟进去后发现,好像没对数据进行操作,我也就没对他进行分析。最后我自己写出来的函数和他的序列号相同,说明该函数有其他功能。对序列号的计算无影响。
00407E68 |. C745 FC 01000> mov dword ptr [ebp-4], 1
00407E68 |. C745 FC 01000> mov dword ptr [ebp-4], 1
00407E6F |. C745 DC 00000> mov dword ptr [ebp-24], 0 ; 这三个变量为
00407E76 |. C745 D8 00000> mov dword ptr [ebp-28], 0 ;最后存储前半段
00407E7D |. C745 D4 00000> mov dword ptr [ebp-2C], 0 ;变换的结果
00407E84 |. 8B4D 0C mov ecx, dword ptr [ebp+C] ; 取出指向用户名地址的指针
00407E87 |. E8 B497FFFF call 00401640 ; 取出用户名,存放在eax
00407E8C |. 50 push eax ; 把用户名压入栈
00407E8D |. E8 3E6D0200 call 0042EBD0 ; 求取用户名的长度,存放在eax
00407E92 |. 83C4 04 add esp, 4
00407E95 |. 8945 CC mov dword ptr [ebp-34], eax ; 把用户名的长度,放入局部变量len
00407E98 |. 837D CC 00 cmp dword ptr [ebp-34], 0 ; 判断输入用户名是否为空
00407E9C |. 0F84 80020000 je 00408122 ;
00407EA2 |. C745 D0 01000> mov dword ptr [ebp-30], 1 ; 局部变量初始化,i=1,
00407EA9 |. EB 09 jmp short 00407EB4
00407EAB |> 8B4D D0 /mov ecx, dword ptr [ebp-30]
00407EAE |. 83C1 01 |add ecx, 1
00407EB1 |. 894D D0 |mov dword ptr [ebp-30], ecx ; i++
00407EB4 |> 8B55 D0 mov edx, dword ptr [ebp-30] ; 取出变量i
00407EB7 |. 3B55 CC |cmp edx, dword ptr [ebp-34] ; if(i>len)
00407EBA |. 0F8F F5000000 |jg 00407FB5
00407EC0 |. 8B45 DC |mov eax, dword ptr [ebp-24] ; else 变量[ebp-24]为变量b
00407EC3 |. 83C0 0C |add eax, 0C ; j=j+0xc
00407EC6 |. 8945 C4 |mov dword ptr [ebp-3C], eax ; b=j
00407EC9 |. DB45 C4 |fild dword ptr [ebp-3C] ; 把b转换成双精度浮点型
00407ECC |. DD5D BC |fstp qword ptr [ebp-44] ; [ebp-44]为变量c=(double)(b+0xc)
00407ECF |. 8B4D D0 |mov ecx, dword ptr [ebp-30]
00407ED2 |. 83E9 01 |sub ecx, 1
00407ED5 |. 51 |push ecx
00407ED6 |. 8B4D 0C |mov ecx, dword ptr [ebp+C] ; 用户名指针放入ecx
00407ED9 |. E8 220F0000 |call 00408E00 ; 取出用户名
00407EDE |. 0FBED0 |movsx edx, al ; edx=name[i--]
00407EE1 |. 0FAF55 D0 |imul edx, dword ptr [ebp-30] ; edx=edx*i
00407EE5 |. 0FAF55 D0 |imul edx, dword ptr [ebp-30] ; edx=edx*i
00407EE9 |. 8955 B8 |mov dword ptr [ebp-48], edx ; [ebp-48]为d=name[i-1]*i*i
00407EEC |. DB45 B8 |fild dword ptr [ebp-48]
00407EEF |. DD5D B0 |fstp qword ptr [ebp-50] ; [ebp-50]为e=(double)d
00407EF2 |. DB45 D0 |fild dword ptr [ebp-30]
00407EF5 |. DD5D A8 |fstp qword ptr [ebp-58] ; 【ebp-58】为f=(double)i
00407EF8 |. 8B45 D0 |mov eax, dword ptr [ebp-30] ; j=i
00407EFB |. 83E8 01 |sub eax, 1
00407EFE |. 50 |push eax
00407EFF |. 8B4D 0C |mov ecx, dword ptr [ebp+C] ; ptr=&name
00407F02 |. E8 F90E0000 |call 00408E00
00407F07 |. 0FBEC8 |movsx ecx, al ; ecx=name[i--]
00407F0A |. 894D A4 |mov dword ptr [ebp-5C], ecx ; 【ebp-5c】为g=name[i-1];(双字)
00407F0D |. DB45 A4 |fild dword ptr [ebp-5C]
00407F10 |. 83EC 08 |sub esp, 8
00407F13 |. DD1C24 |fstp qword ptr [esp] ; c2=(double)name[i-1]
00407F16 |. E8 096C0200 |call 0042EB24 ; 求平方根函数
结果存放在st0中,传入的参数也是放在st0里。
00407F1B |. 83C4 08 |add esp, 8
00407F1E |. DC4D A8 |fmul qword ptr [ebp-58] ;完成f与根号c2的浮点相乘
00407F21 |. DC05 18534500 |fadd qword ptr [455318] ;加上常数1
00407F27 |. DC4D B0 |fmul qword ptr [ebp-50] ;再与变量e相乘
00407F2A |. DC45 BC |fadd qword ptr [ebp-44] ;再与变量c相加
表示成C代码如下:
(sqrt(c2)*f+1)*e+c);
00407F2D |. E8 6A6D0200 |call 0042EC9C ; 把结果为整数型
00407F32 |. 99 |cdq ;扩展成四字
00407F33 |. B9 A0860100 |mov ecx, 186A0
00407F38 |. F7F9 |idiv ecx ;求余,结果存在edx
00407F3A |. 8955 DC |mov dword ptr [ebp-24], edx
00407F3D |. 8B75 D8 |mov esi, dword ptr [ebp-28]
00407F40 |. 0FAF75 D0 |imul esi, dword ptr [ebp-30]
00407F44 |. 68 00000040 |push 40000000 ;传入参数y。注意传入的是双精度。
00407F49 |. 6A 00 |push 0
00407F4B |. 8B55 D0 |mov edx, dword ptr [ebp-30]
00407F4E |. 83EA 01 |sub edx, 1
00407F51 |. 52 |push edx,
00407F52 |. 8B4D 0C |mov ecx, dword ptr [ebp+C]
00407F55 |. E8 A60E0000 |call 00408E00 ; 取出用户名的函数
00407F5A |. 0FBEC0 |movsx eax, al
00407F5D |. 8945 A0 |mov dword ptr [ebp-60], eax
00407F60 |. DB45 A0 |fild dword ptr [ebp-60]
00407F63 |. 83EC 08 |sub esp, 8
00407F66 |. DD1C24 |fstp qword ptr [esp] ;传入参数x
00407F69 |. E8 9B690200 |call 0042E909 ; pow(x,y)求x的y次幂结果存放在st0.
00407F6E |. 83C4 10 |add esp, 10
00407F71 |. DA4D D0 |fimul dword ptr [ebp-30]
00407F74 |. E8 236D0200 |call 0042EC9C ; 把浮点型转换为整形
00407F79 |. 8D4406 16 |lea eax, dword ptr [esi+eax+16];
完成功能eax=eax+esi+0x16
00407F7D |. 99 |cdq
00407F7E |. B9 A0860100 |mov ecx, 186A0
00407F83 |. F7F9 |idiv ecx
00407F85 |. 8955 D8 |mov dword ptr [ebp-28], edx
00407F88 |. DB45 DC |fild dword ptr [ebp-24]
00407F8B |. 83EC 08 |sub esp, 8
00407F8E |. DD1C24 |fstp qword ptr [esp]
00407F91 |. E8 8E6B0200 |call 0042EB24 ; 求平方根函数
00407F96 |. 83C4 08 |add esp, 8
00407F99 |. E8 FE6C0200 |call 0042EC9C ; 把浮点型转换为整形
00407F9E |. 8B55 D8 |mov edx, dword ptr [ebp-28]
00407FA1 |. 8D4402 1F |lea eax, dword ptr [edx+eax+1F];
00407FA5 |. 99 |cdq
00407FA6 |. B9 A0860100 |mov ecx, 186A0
00407FAB |. F7F9 |idiv ecx
00407FAD |. 8955 D4 |mov dword ptr [ebp-2C], edx
00407FB0 |.^ E9 F6FEFFFF \jmp 00407EAB
以上从00407EA2到这是完成的一个循环。再循环体里面完成计算,把计算结果放在[ebp-0x20][ebp-0x24],[ebp-0x28],[ebp-0x2c]
以下是计算的第二部分其中。分析知道有三个一层循环,一个嵌套循环;
00407FB5 |> C745 D0 00000> mov dword ptr [ebp-30], 0 ;循环控制量i=0
00407FBC |. EB 09 jmp short 00407FC7
00407FBE |> 8B55 D0 /mov edx, dword ptr [ebp-30]
00407FC1 |. 83C2 01 |add edx, 1
00407FC4 |. 8955 D0 |mov dword ptr [ebp-30], edx;i++
00407FC7 |> 837D D0 05 cmp dword ptr [ebp-30], 5;判断是否大于5
00407FCB |. 7D 28 |jge short 00407FF5
00407FCD |. 8B45 D0 |mov eax, dword ptr [ebp-30]
00407FD0 |. 0FAF45 D0 |imul eax, dword ptr [ebp-30]
00407FD4 |. 0FAF45 D0 |imul eax, dword ptr [ebp-30]
00407FD8 |. 8B4D DC |mov ecx, dword ptr [ebp-24]
00407FDB |. 8D5401 1F |lea edx, dword ptr [ecx+eax+1F]
00407FDF |. 81E2 7F000080 |and edx, 8000007F;这条指令完成求余
00407FE5 |. 79 05 |jns short 00407FEC
00407FE7 |. 4A |dec edx
00407FE8 |. 83CA 80 |or edx, FFFFFF80
00407FEB |. 42 |inc edx
00407FEC |> 8B45 D0 |mov eax, dword ptr [ebp-30]
00407FEF |. 885405 E0 |mov byte ptr [ebp+eax-20], dl//保存计算结果
00407FF3 |.^ EB C9 \jmp short 00407FBE
第一个循环结束第二个循环开始;完成功能如下伪代码:
while ( [ebp-0x30]< 5 )
{
serial[[ebp-0x30]] = ([ebp-0x24] + [ebp-0x30] * [ebp-0x30] * [ebp-0x30] + 0x31) % 128;
++[ebp-0x30];
}
其中serial=ebp-0x20
下面第二和第三个循环完成功能和循环一类似,就不多说了
00407FF5 |> C745 D0 05000>mov dword ptr [ebp-30], 5
00407FFC |. EB 09 jmp short 00408007
00407FFE |> 8B4D D0 /mov ecx, dword ptr [ebp-30]
00408001 |. 83C1 01 |add ecx, 1
00408004 |. 894D D0 |mov dword ptr [ebp-30], ecx
00408007 |> 837D D0 0A cmp dword ptr [ebp-30], 0A
0040800B |. 7D 28 |jge short 00408035
0040800D |. 8B55 D0 |mov edx, dword ptr [ebp-30]
00408010 |. 0FAF55 D0 |imul edx, dword ptr [ebp-30]
00408014 |. 0FAF55 D0 |imul edx, dword ptr [ebp-30]
00408018 |. 8B45 D8 |mov eax, dword ptr [ebp-28]
0040801B |. 8D4C10 1F |lea ecx, dword ptr [eax+edx+1F]
0040801F |. 81E1 7F000080 |and ecx, 8000007F
00408025 |. 79 05 |jns short 0040802C
00408027 |. 49 |dec ecx
00408028 |. 83C9 80 |or ecx, FFFFFF80
0040802B |. 41 |inc ecx
0040802C |> 8B55 D0 |mov edx, dword ptr [ebp-30]
0040802F |. 884C15 E0 |mov byte ptr [ebp+edx-20], cl
00408033 |.^ EB C9 \jmp short 00407FFE
第二个循环结束,第三循环开始
00408035 |> C745 D0 0A000>mov dword ptr [ebp-30], 0A
0040803C |. EB 09 jmp short 00408047
0040803E |> 8B45 D0 /mov eax, dword ptr [ebp-30]
00408041 |. 83C0 01 |add eax, 1
00408044 |. 8945 D0 |mov dword ptr [ebp-30], eax
00408047 |> 837D D0 0F cmp dword ptr [ebp-30], 0F
0040804B |. 7D 27 |jge short 00408074
0040804D |. 8B4D D0 |mov ecx, dword ptr [ebp-30]
00408050 |. 0FAF4D D0 |imul ecx, dword ptr [ebp-30]
00408054 |. 0FAF4D D0 |imul ecx, dword ptr [ebp-30]
00408058 |. 8B55 D4 |mov edx, dword ptr [ebp-2C]
0040805B |. 8D440A 1F |lea eax, dword ptr [edx+ecx+1F]
0040805F |. 25 7F000080 |and eax, 8000007F
00408064 |. 79 05 |jns short 0040806B
00408066 |. 48 |dec eax
00408067 |. 83C8 80 |or eax, FFFFFF80
0040806A |. 40 |inc eax
0040806B |> 8B4D D0 |mov ecx, dword ptr [ebp-30]
0040806E |. 88440D E0 |mov byte ptr [ebp+ecx-20], al
00408072 |.^ EB CA \jmp short 0040803E
第三个循环结束,
00408074 |> C645 EF 00 mov byte ptr [ebp-11], 0;本条指令不影响序列号的计算。
嵌套循环开始
00408078 |. C745 D0 00000> mov dword ptr [ebp-30], 0
0040807F |. EB 09 jmp short 0040808A
00408081 |> 8B55 D0 /mov edx, dword ptr [ebp-30]
00408084 |. 83C2 01 |add edx, 1
00408087 |. 8955 D0 |mov dword ptr [ebp-30], edx
0040808A |> 837D D0 0F cmp dword ptr [ebp-30], 0F
0040808E |. 7D 7D |jge short 0040810D
00408090 |> 8B45 D0 |/mov eax, dword ptr [ebp-30]
00408093 |. 0FBE4C05 E0 ||movsx ecx, byte ptr [ebp+eax-20]
00408098 |. 83F9 30 ||cmp ecx, 30
0040809B |. 7C 0D ||jl short 004080AA
0040809D |. 8B55 D0 ||mov edx, dword ptr [ebp-30]
004080A0 |. 0FBE4415 E0 ||movsx eax, byte ptr [ebp+edx-20]
004080A5 |. 83F8 39 ||cmp eax, 39
004080A8 |. 7E 5E ||jle short 00408108
004080AA |> 8B4D D0 ||mov ecx, dword ptr [ebp-30]
004080AD |. 0FBE540D E0 ||movsx edx, byte ptr [ebp+ecx-20]
004080B2 |. 83FA 41 ||cmp edx, 41
004080B5 |. 7C 0D ||jl short 004080C4
004080B7 |. 8B45 D0 ||mov eax, dword ptr [ebp-30]
004080BA |. 0FBE4C05 E0 ||movsx ecx, byte ptr [ebp+eax-20]
004080BF |. 83F9 5A ||cmp ecx, 5A
004080C2 |. 7E 44 ||jle short 00408108
004080C4 |> 8B55 D0 ||mov edx, dword ptr [ebp-30]
004080C7 |. 0FBE4415 E0 ||movsx eax, byte ptr [ebp+edx-20]
004080CC |. 83F8 61 ||cmp eax, 61
004080CF |. 7C 0D ||jl short 004080DE
004080D1 |. 8B4D D0 ||mov ecx, dword ptr [ebp-30]
004080D4 |. 0FBE540D E0 ||movsx edx, byte ptr [ebp+ecx-20]
004080D9 |. 83FA 7A ||cmp edx, 7A
004080DC |. 7E 2A ||jle short 00408108
004080DE |> 8B45 D0 ||mov eax, dword ptr [ebp-30]
004080E1 |. 0FBE4C05 E0 ||movsx ecx, byte ptr [ebp+eax-20]
004080E6 |. 8B55 D0 ||mov edx, dword ptr [ebp-30]
004080E9 |. 6BD2 0C ||imul edx, edx, 0C
004080EC |. 8D8411 F10400>||lea eax, dword ptr [ecx+edx+4F1]
004080F3 |. 25 7F000080 ||and eax, 8000007F
004080F8 |. 79 05 ||jns short 004080FF
004080FA |. 48 ||dec eax
004080FB |. 83C8 80 ||or eax, FFFFFF80
004080FE |. 40 ||inc eax
004080FF |> 8B4D D0 ||mov ecx, dword ptr [ebp-30]
00408102 |. 88440D E0 ||mov byte ptr [ebp+ecx-20], al
00408106 |.^ EB 88 |\jmp short 00408090
00408108 |>^ E9 74FFFFFF \jmp 00408081
while ( a[0] < 15 )
{
while ( ((signed int)serial[a[0]] < 48 || (signed int)serial[a[0]] > 57)
&& ((signed int)serial[a[0]] < 65 || (signed int)serial[a[0]] > 90)
&& ((signed int)serial[a[0]] < 97 || (signed int)serial[a[0]] > 122) )
serial[a[0]] = (serial[a[0]] + 12 * a[0] + 1265) % 128;
++a[0];
}
计算的第二部分,主要是有ida识别出来的伪代码,我做的事就是把他们的参数对应关系找到。
ida。确实是个好东西啊。呵呵
上面是本人弄了两星期才弄出来的。主要是太菜了。
写的不好的地方望大家躲到指教。
补充:filebus是一个点对点文件传输工具。
filebus安装包:filebus_cn.rar
注册机源代码filebus_keygen.rar