破文作者: ZabShow
破解平台: WinXP
软件名称: FileRecoveryAngel
软件大小: 777 KB
软件语言: 英文
软件类别: 国外软件 / 共享版 / 数据备份
应用平台: Win9x/NT/2000/XP
界面预览: 无
加入时间: 2005-01-22 16:47:00
下载次数: 715
推荐等级:
开 发 商: http://www.filerecoveryangel.com/
软件介绍:
Filerecoveryangle是一款文件恢复工具,它能够帮助你从格式化成FAT12、FAT16、FAT32、NTFS文件系统的磁盘中恢复被删除的文件。它不仅仅可以针对硬盘进行文件恢复,它还很好地适用于软盘、数码相机、USB驱动器、ZIP盘、CompactFlash卡、SmartMedia,以及索尼记忆棒。
保护方式:用户名+ 序列号
破解目的:学习中。。。
破解工具:Peid,OD
破解声明:我乃小菜鸟一只,偶得一点心得,愿与大家分享:)
破解过程:
用peid查看为:Borland Delphi 4.0 - 5.0 没壳。呵呵~~~
注册失败后会显示“Register False!”,用od载入后用字符串插件找到“Register False!”双击后来到004808EC:
004808E0 |. BA B8094800 mov edx,FileReco.004809B8 ; ASCII "IsRegister"
004808E5 |. 8BC7 mov eax,edi
004808E7 |. E8 549AFEFF call FileReco.0046A340
004808EC |. B8 700A4800 mov eax,FileReco.00480A70 ; ASCII "Register`False!" <--------------来到这里
004808F1 |. E8 A6FAFCFF call FileReco.0045039C
004808F6 |. 8BC7 mov eax,edi
004808F8 |. E8 9325F8FF call FileReco.00402E90
往上找到:
004807B6 |. /75 0F jnz short FileReco.004807C7 ;比较用户名是否为空
004807B8 |. |B8 4C094800 mov eax,FileReco.0048094C ; ASCII "Name can not been empty!"
004807BD |. |E8 DAFBFCFF call FileReco.0045039C
004807C2 |. |E9 36010000 jmp FileReco.004808FD
004807C7 |> \8B45 FC mov eax,dword ptr ss:[ebp-4] <----------- 在这里下断
我们在004807C7 处下断运行程序,在注册栏输入:
Name: ZabShow
Key: 123456
点击Register后被od断下,一路往下分析:
004807C7 |> \8B45 FC mov eax,dword ptr ss:[ebp-4] ; 用户名:ZabShow
004807CA |. E8 0936F8FF call FileReco.00403DD8 ; 取长度:6位
004807CF |. 8BF8 mov edi,eax
004807D1 |. 03FF add edi,edi
004807D3 |. 8D55 EC lea edx,dword ptr ss:[ebp-14]
004807D6 |. 8B86 E4020000 mov eax,dword ptr ds:[esi+2E4]
004807DC |. E8 639AFAFF call FileReco.0042A244 ; 注册码:123456
004807E1 |. 8B45 EC mov eax,dword ptr ss:[ebp-14]
004807E4 |. 8D55 F8 lea edx,dword ptr ss:[ebp-8]
004807E7 |. E8 407DF8FF call FileReco.0040852C
004807EC |. 8D45 F8 lea eax,dword ptr ss:[ebp-8]
004807EF |. 50 push eax
004807F0 |. 8BCF mov ecx,edi
004807F2 |. BA 02000000 mov edx,2
004807F7 |. 8B45 F8 mov eax,dword ptr ss:[ebp-8] ; 注册码:123456
004807FA |. E8 E137F8FF call FileReco.00403FE0
004807FF |. 8D55 F4 lea edx,dword ptr ss:[ebp-C]
00480802 |. 8B45 FC mov eax,dword ptr ss:[ebp-4] ; 用户名:ZabShow
00480805 |. E8 7EA0FEFF call FileReco.0046A888 ; 关键!!!我们等会进去
0048080A |. 8B45 F4 mov eax,dword ptr ss:[ebp-C] ; 真注册码
0048080D |. 8B55 F8 mov edx,dword ptr ss:[ebp-8] ; 假注册码
00480810 |. E8 D336F8FF call FileReco.00403EE8
00480815 |. 75 02 jnz short FileReco.00480819
到我们到达0048080A处,便可以看到真的注册码: DFF9D6A9898IDC,好!我们重新来过。
Name:ZabShow
Key: DFF9D6A9898IDC
点击Register后,传说中的对话框又出来了,竟然提示错误!怎么回事呢?咱们稍后分解!
现在进入按F7跟进 00480805 call FileReco.0046A888,也就是算注册码的地方:
0046A888 /$ 55 push ebp
0046A889 |. 8BEC mov ebp,esp
0046A88B |. 33C9 xor ecx,ecx
0046A88D |. 51 push ecx
0046A88E |. 51 push ecx
0046A88F |. 51 push ecx
0046A890 |. 51 push ecx
0046A891 |. 51 push ecx
0046A892 |. 51 push ecx
0046A893 |. 51 push ecx
0046A894 |. 51 push ecx
0046A895 |. 53 push ebx
0046A896 |. 56 push esi
0046A897 |. 57 push edi
0046A898 |. 8955 F8 mov dword ptr ss:[ebp-8],edx
0046A89B |. 8945 FC mov dword ptr ss:[ebp-4],eax ; 用户名
0046A89E |. 8B45 FC mov eax,dword ptr ss:[ebp-4]
0046A8A1 |. E8 E696F9FF call FileReco.00403F8C
0046A8A6 |. 33C0 xor eax,eax
0046A8A8 |. 55 push ebp
0046A8A9 |. 68 D2A94600 push FileReco.0046A9D2
0046A8AE |. 64:FF30 push dword ptr fs:[eax]
0046A8B1 |. 64:8920 mov dword ptr fs:[eax],esp
0046A8B4 |. 8D45 F4 lea eax,dword ptr ss:[ebp-C]
0046A8B7 |. E8 9C92F9FF call FileReco.00403B58
0046A8BC |. 8B45 FC mov eax,dword ptr ss:[ebp-4] ; 用户名
0046A8BF |. E8 1495F9FF call FileReco.00403DD8 ; 取用户名长度
0046A8C4 |. 8BF0 mov esi,eax ; EAX内为用户名长度
0046A8C6 |. 85F6 test esi,esi
0046A8C8 |. 7E 29 jle short FileReco.0046A8F3 ; 若长度为0则跳
0046A8CA |. BB 01000000 mov ebx,1 ; 设置读取字符标记位
0046A8CF |> 8D4D EC /lea ecx,dword ptr ss:[ebp-14]
0046A8D2 |. 8B45 FC |mov eax,dword ptr ss:[ebp-4] ; 用户名
0046A8D5 |. 0FB64418 FF |movzx eax,byte ptr ds:[eax+ebx-1] ; 逐位取用户名字符,把ASCII码存入EAX
0046A8DA |. BA 02000000 |mov edx,2
0046A8DF |. E8 2CDDF9FF |call FileReco.00408610 ; 把ASCII码由数值型变为字符型
0046A8E4 |. 8B55 EC |mov edx,dword ptr ss:[ebp-14] ; 字符型的ASCII
0046A8E7 |. 8D45 F4 |lea eax,dword ptr ss:[ebp-C]
0046A8EA |. E8 F194F9FF |call FileReco.00403DE0 ; 存入字符串
0046A8EF |. 43 |inc ebx
0046A8F0 |. 4E |dec esi ; 计数器减1
0046A8F1 |.^ 75 DC \jnz short FileReco.0046A8CF ; 没取完则跳
0046A8F3 |> 8B45 F4 mov eax,dword ptr ss:[ebp-C] ; 由ASCII码变换后的字符串
0046A8F6 |. E8 DD94F9FF call FileReco.00403DD8 ; 取长度
0046A8FB |. 8BD8 mov ebx,eax
0046A8FD |. E8 4680F9FF call FileReco.00402948
0046A902 |. 83FB 14 cmp ebx,14 ; 长度与14h比较
0046A905 |. 7E 1B jle short FileReco.0046A922 ; 小于则跳
0046A907 |. 8D45 F4 lea eax,dword ptr ss:[ebp-C]
0046A90A |. 50 push eax
0046A90B |. B9 14000000 mov ecx,14
0046A910 |. BA 01000000 mov edx,1
0046A915 |. 8B45 F4 mov eax,dword ptr ss:[ebp-C]
0046A918 |. E8 C396F9FF call FileReco.00403FE0 ; 把20位后的字符全部去掉
0046A91D |. BB 14000000 mov ebx,14
0046A922 |> 8BF3 mov esi,ebx ; 把长度给ESI
0046A924 |. 85F6 test esi,esi ; 测试长度是否为0
0046A926 |. 7E 7F jle short FileReco.0046A9A7 ; 为0则跳
0046A928 |. BB 01000000 mov ebx,1 ; 设置读取字符标记位
0046A92D |> 8D45 E8 /lea eax,dword ptr ss:[ebp-18]
0046A930 |. 8B55 F4 |mov edx,dword ptr ss:[ebp-C] ; 由ASCII码变换后的字符串
0046A933 |. 8A541A FF |mov dl,byte ptr ds:[edx+ebx-1] ; 逐位取字符。把ASCII码存入dl
0046A937 |. E8 C493F9FF |call FileReco.00403D00
0046A93C |. 8B45 E8 |mov eax,dword ptr ss:[ebp-18]
0046A93F |. BA E8A94600 |mov edx,FileReco.0046A9E8 ; 表1:abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ
0046A944 |. E8 7B97F9FF |call FileReco.004040C4 ; 将字符与表1比对找到其所在位置,记下位置数,存在EAX内
0046A949 |. 8BF8 |mov edi,eax ; 把EAX送给edi,设为数1
0046A94B |. 85FF |test edi,edi
0046A94D |. 7F 0C |jg short FileReco.0046A95B
0046A94F |. 8B45 F4 |mov eax,dword ptr ss:[ebp-C]
0046A952 |. 8A4418 FF |mov al,byte ptr ds:[eax+ebx-1]
0046A956 |. 8845 F3 |mov byte ptr ss:[ebp-D],al
0046A959 |. EB 2F |jmp short FileReco.0046A98A
0046A95B |> 8D45 E4 |lea eax,dword ptr ss:[ebp-1C]
0046A95E |. BA 30AA4600 |mov edx,FileReco.0046AA30 ; 表2:85987456212365897456
0046A963 |. 8A541A FF |mov dl,byte ptr ds:[edx+ebx-1] ; 取上面的表2的各位的ASCII码
0046A967 |. E8 9493F9FF |call FileReco.00403D00
0046A96C |. 8B45 E4 |mov eax,dword ptr ss:[ebp-1C]
0046A96F |. E8 D8DCF9FF |call FileReco.0040864C ; 把从表2取的字符转化为数字,设为数2
0046A974 |. 03F8 |add edi,eax ; 数1与数2相加
0046A976 |. 83FF 3E |cmp edi,3E ; 比较是否小于62
0046A979 |. 7E 03 |jle short FileReco.0046A97E ; 小于则跳
0046A97B |. 83EF 3E |sub edi,3E ; 如果大于62则减62
0046A97E |> B8 E8A94600 |mov eax,FileReco.0046A9E8 ; 表1:abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ
0046A983 |. 8A4438 FF |mov al,byte ptr ds:[eax+edi-1] ; 从表中依据edi找到找到相应的字符
0046A987 |. 8845 F3 |mov byte ptr ss:[ebp-D],al ; 存入内存
0046A98A |> 8D45 E0 |lea eax,dword ptr ss:[ebp-20]
0046A98D |. 8A55 F3 |mov dl,byte ptr ss:[ebp-D]
0046A990 |. E8 6B93F9FF |call FileReco.00403D00 ; 连接成字符串
0046A995 |. 8B55 E0 |mov edx,dword ptr ss:[ebp-20]
0046A998 |. 8B45 F8 |mov eax,dword ptr ss:[ebp-8]
0046A99B |. E8 4094F9FF |call FileReco.00403DE0
0046A9A0 |. 8B45 F8 |mov eax,dword ptr ss:[ebp-8]
0046A9A3 |. 43 |inc ebx
0046A9A4 |. 4E |dec esi ; 计数器减1
0046A9A5 |.^ 75 86 \jnz short FileReco.0046A92D
0046A9A7 |> 33C0 xor eax,eax
0046A9A9 |. 5A pop edx
0046A9AA |. 59 pop ecx
0046A9AB |. 59 pop ecx
0046A9AC |. 64:8910 mov dword ptr fs:[eax],edx
0046A9AF |. 68 D9A94600 push FileReco.0046A9D9
0046A9B4 |> 8D45 E0 lea eax,dword ptr ss:[ebp-20]
0046A9B7 |. BA 04000000 mov edx,4
0046A9BC |. E8 BB91F9FF call FileReco.00403B7C
0046A9C1 |. 8D45 F4 lea eax,dword ptr ss:[ebp-C]
0046A9C4 |. E8 8F91F9FF call FileReco.00403B58
0046A9C9 |. 8D45 FC lea eax,dword ptr ss:[ebp-4]
0046A9CC |. E8 8791F9FF call FileReco.00403B58
0046A9D1 \. C3 retn
0046A9D2 .^ E9 198CF9FF jmp FileReco.004035F0
0046A9D7 .^ EB DB jmp short FileReco.0046A9B4
0046A9D9 . 5F pop edi
0046A9DA . 5E pop esi
0046A9DB . 5B pop ebx
0046A9DC . 8BE5 mov esp,ebp
0046A9DE . 5D pop ebp
0046A9DF . C3 retn ;返回
综上:
本软件为典型的用户名+注册码式的注册方式
其中要用到两个表
T1=abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ
T2=85987456212365897456
1.对用户名的每一位字符取ASCII码保存为16进制,在把 ASCII码由数值型转为字符串型并依次存入字符串STR1中,如果STR1的长度大于14H(20)则把20位后的截掉.
2.对STR1中的每一个字符,依次从T1表中找到与其相同字符,并记下位置号记为pos,再对T2表中依次取字符,并变为数值型与pos相加得到tmp1.
3.将tmp1与3EH(62)相比较,如果大于则将tmp1减去62.
4.再从T1表中由tmp1的值确定相应位置的一个字符设为tmpKey
5.最后将所有的tmpKey相连则就是所要的注册码了.
好!
下面来解答我们前面留下的问题,为什么输入正确的注册码后仍然不能注册呢?
原因在这里:
0048080A |. 8B45 F4 mov eax,dword ptr ss:[ebp-C] ; 真注册码
0048080D |. 8B55 F8 mov edx,dword ptr ss:[ebp-8] ; 假注册码
当在0048080A 时我们能看到程序算出的真注册码,下d eax可以看到注册码为DFF9D6A9898IDC
而0048080D 是我们自己输入的注册码,下d edx可以看到注册码为FF9D6A9898IDC。呵呵
看出来了吧,原来程序把我们输入的注册码的第一位给去掉了,也就是说第一位注册码不参与比较,只是用来凑数的,或是让人家做的内存注册机没用(因为别人不知道注册码的第一位被省去啦),所以我们只要在真注册码前面随便添一位就可以了( 我加的是D ).
Name: ZabShow
Key: DDFF9D6A9898IDC
另附注册机代码(Delphi):
for i:=1 to length(name) do
tmp1:=tmp1+inttohex(ord(name[i]),2);
if length(tmp1)>20 then
tmp1:=copy(tmp1,1,20);
for i:=1 to length(tmp1) do
begin
tmpPos:=pos(tmp1[i],t1);
tmp3:=copy(t2,i,1);
tmpCode:=tmpPos+strtoint(tmp3);
if tmpCode>62 then
tmpCode:=tmpCode-62;
key:=key+copy(t1,tmpCode,1);
end;
key:='D'+key;