playboysen 发表于 2008-11-11 16:07:14

Better File Rename V5.3.1算法逆向+系列注册机源码

【破文标题】Better File Rename V5.3.1算法逆向+系列注册机源码
【破文作者】Playboysen
【作者邮箱】[email protected]
【破解工具】PEiD,OD
【破解平台】Windows XP
【软件大小】1.6 MB
【软件授权】共享版($19.95)
【软件语言】英文
【原版下载】http://www.publicspace.net/windows/BetterFileRename/download.html
【保护方式】注册码
【软件简介】一款WINDOWS资源管理器的扩展外壳, 可以帮助你快速简便地修改文件名和文件修改时间。功能有:强大的命名方式,文字、日期和序列数字的添加、去除、插入和替换;支持数字列表的创建、改变、添加、抽取等;支持文件建立日期、修正日期、EXIF中日期的修改;可以分别处理文件名和扩展名
【破解声明】一点心得,愿与大家分享o(∩_∩)o 版权所有,转载注明作者!
【破解内容】

    昨天整理一些试题材料(一二百份文件)需要修改一下文件名,就找了一款别人推荐的文件重命名的软件,很好用,但是不注册每次只能修改10个文件名,害我折腾了半个多小时才弄完,火气——我只不过是想用一次,就仅仅一次,都不给机会!干脆,拉出来练手!
    Better File Rename V5.3.1(081103更新),无壳,未注册启动有NAG,功能限制,单一注册码保护方式,有错误提示,OD载入查找字符串无果,怀疑是字符串加密或者软件多数功能并不在主程序中,查看软件根目录有同名dll文件——可疑之处。
    踩点完毕,开工。OD载入后运行至出现NAG,下MessageBoxA和MessageBoxW断点(以防万一),随便填写注册码注册后断下,逆跟踪至此:

1000D705|> \6A 00            push 0                     ;错误对话框
1000D707|.68 00820910      push Bfr_1.10098200      ;error
1000D70C|.68 B4810910      push Bfr_1.100981B4      ;the registration code is not correct.
1000D711|.8B8D 94FEFFFF    mov ecx,dword ptr ss:
1000D717|.E8 11370600      call Bfr_1.10070E2D
1000D71C|>C645 FC 00       mov byte ptr ss:,0
1000D720|.8D8D 4CFFFFFF    lea ecx,dword ptr ss:
1000D726|.E8 5E520600      call Bfr_1.10072989
1000D72B|>C745 FC 09000000 mov dword ptr ss:,9

看前面的基址——dll文件,符合我们先前猜测。此段首下段,重新加载并注册,单步跟踪:

1000D59B|.C645 FC 01       mov byte ptr ss:,1
1000D59F|.8D8D 4CFFFFFF    lea ecx,dword ptr ss:
1000D5A5|.E8 FA580600      call Bfr_1.10072EA4                  ;取注册码
1000D5AA|.8D8D 4CFFFFFF    lea ecx,dword ptr ss:
1000D5B0|.E8 31FC0500      call Bfr_1.1006D1E6
1000D5B5|.C785 48FFFFFF 00>mov dword ptr ss:,0
1000D5BF|.EB 0F            jmp short Bfr_1.1000D5D0
1000D5C1|>8B8D 48FFFFFF    /mov ecx,dword ptr ss:       ;这一段循环目的是加密所输入的注册码
1000D5C7|.83C1 01          |add ecx,1                           ;每循环一次计数器加1
1000D5CA|.898D 48FFFFFF    |mov dword ptr ss:,ecx
1000D5D0|>8B95 4CFFFFFF   mov edx,dword ptr ss:       ;注册码放入
1000D5D6|.8B42 F8          |mov eax,dword ptr ds:      ;注册码长度放入
1000D5D9|.8985 9CFEFFFF    |mov dword ptr ss:,eax
1000D5DF|.8B8D 48FFFFFF    |mov ecx,dword ptr ss:       ;计数器
1000D5E5|.3B8D 9CFEFFFF    |cmp ecx,dword ptr ss:      ;比较是否加密完成
1000D5EB|.7D 3E            |jge short Bfr_1.1000D62B
1000D5ED|.8B95 48FFFFFF    |mov edx,dword ptr ss:       ;计数器的值放入EDX
1000D5F3|.8B85 4CFFFFFF    |mov eax,dword ptr ss:       ;加密后的注册码放入EAX
1000D5F9|.66:8B0C50      |mov cx,word ptr ds:      ;从前到后依次取注册码的每一位
1000D5FD|.66:898D 98FEFFFF |mov word ptr ss:,cx
1000D604|.8B95 98FEFFFF    |mov edx,dword ptr ss:      ;取出的每一位单独放入EDX
1000D60A|.81E2 FFFF0000    |and edx,0FFFF
1000D610|.0395 48FFFFFF    |add edx,dword ptr ss:       ;取出的注册码的每一位+(其所在的位数-1)
1000D616|.52               |push edx
1000D617|.8B85 48FFFFFF    |mov eax,dword ptr ss:       ;计数器的值放入
1000D61D|.50               |push eax
1000D61E|.8D8D 4CFFFFFF    |lea ecx,dword ptr ss:
1000D624|.E8 B1580600      |call Bfr_1.10072EDA
1000D629|.^ EB 96            \jmp short Bfr_1.1000D5C1
1000D62B|>51               push ecx
1000D62C|.8BCC             mov ecx,esp
1000D62E|.89A5 A0FEFFFF    mov dword ptr ss:,esp
1000D634|.8D95 4CFFFFFF    lea edx,dword ptr ss:      ;出现加密后的假码
1000D63A|.52               push edx
1000D63B|.E8 B6500600      call Bfr_1.100726F6
1000D640|.8985 90FEFFFF    mov dword ptr ss:,eax      
1000D646|.E8 5549FFFF      call Bfr_1.10001FA0                  ;跟踪发现此为关键call
1000D64B|.83C4 04          add esp,4
1000D64E|.8985 8CFEFFFF    mov dword ptr ss:,eax
1000D654|.8B85 8CFEFFFF    mov eax,dword ptr ss:
1000D65A|.8985 50FFFFFF    mov dword ptr ss:,eax
1000D660|.83BD 50FFFFFF 00 cmp dword ptr ss:,0
1000D667|.75 2A            jnz short Bfr_1.1000D693             ;关键跳
1000D669|.8D8D 4CFFFFFF    lea ecx,dword ptr ss:
1000D66F|.51               push ecx
1000D670|.8B8D 94FEFFFF    mov ecx,dword ptr ss:
1000D676|.83C1 5C          add ecx,5C
1000D679|.E8 52540600      call Bfr_1.10072AD0
1000D67E|.68 21300000      push 3021
1000D683|.8B8D 94FEFFFF    mov ecx,dword ptr ss:
1000D689|.E8 3A1B0600      call Bfr_1.1006F1C8
1000D68E|.E9 89000000      jmp Bfr_1.1000D71C
1000D693|>83BD 50FFFFFF 00 cmp dword ptr ss:,0
1000D69A|.7E 69            jle short Bfr_1.1000D705             ;关键跳
......
1000D705|>6A 00            push 0                               ; /错误对话框
1000D707|.68 00820910      push Bfr_1.10098200                  ; |error
1000D70C|.68 B4810910      push Bfr_1.100981B4                  ; |the registration code is not correct.
1000D711|.8B8D 94FEFFFF    mov ecx,dword ptr ss:       ; |
1000D717|.E8 11370600      call Bfr_1.10070E2D                  ; \Bfr_1.10070E2D

F7跟进1000D646的关键call至此:

10001FB8|.81EC A8000000    sub esp,0A8
10001FBE|.C745 FC 00000000 mov dword ptr ss:,0
10001FC5|.68 14830910      push Bfr_1.10098314                  ;bgt0exzo5:<ce:ahcj?gink
10001FCA|.8D4D EC          lea ecx,dword ptr ss:
10001FCD|.E8 800A0700      call Bfr_1.10072A52
10001FD2|.C645 FC 01       mov byte ptr ss:,1
10001FD6|.8B45 EC          mov eax,dword ptr ss:
10001FD9|.8945 A0          mov dword ptr ss:,eax
10001FDC|.8B4D A0          mov ecx,dword ptr ss:
10001FDF|.51               push ecx
10001FE0|.8B55 08          mov edx,dword ptr ss:
10001FE3|.52               push edx
10001FE4|.E8 10360400      call Bfr_1.100455F9                  ;关键处,F7跟进
10001FE9|.83C4 08          add esp,8
10001FEC|.8945 9C          mov dword ptr ss:,eax      ; 上面call的返回值放入
10001FEF|.33C0             xor eax,eax
10001FF1|.837D 9C 00       cmp dword ptr ss:,0          ; 其实还是比较上面call的返回值
10001FF5|.0F94C0         sete al
10001FF8|.25 FF000000      and eax,0FF
10001FFD|.85C0             test eax,eax
10001FFF|.0F85 E4000000    jnz Bfr_1.100020E9                   ;如果跳转则提示输入的是v4版本的注册码
10002005|.68 FC820910      push Bfr_1.100982FC                  ;bgv0fxzz5b<be:bbij?gjnk
1000200A|.8D4D E4          lea ecx,dword ptr ss:
......
10002048|.85D2             test edx,edx
1000204A|.0F85 99000000    jnz Bfr_1.100020E9                   ;提示V4版本注册码
10002050|.68 E4820910      push Bfr_1.100982E4                  ;bgt0exzo5;=@b:?ceg?ifnn
10002055|.8D4D DC          lea ecx,dword ptr ss:
......
1000208D|.81E1 FF000000    and ecx,0FF
10002093|.85C9             test ecx,ecx
10002095|.75 52            jnz short Bfr_1.100020E9             ;提示V4版本注册码
10002097|.68 CC820910      push Bfr_1.100982CC                  ;bgv0fxzz5@>=a:ceii?lgjj
1000209C|.8D4D D4          lea ecx,dword ptr ss:
......
100020D4|.25 FF000000      and eax,0FF
100020D9|.85C0             test eax,eax
100020DB|.75 0C            jnz short Bfr_1.100020E9             ;提示V4版本注册码
100020DD|.C785 70FFFFFF 00>mov dword ptr ss:,0
100020E7|.EB 0A            jmp short Bfr_1.100020F3
100020E9|>C785 70FFFFFF 01>mov dword ptr ss:,1
100020F3|>8A8D 70FFFFFF    mov cl,byte ptr ss:
100020F9|.884D F0          mov byte ptr ss:,cl
100020FC|.C645 FC 00       mov byte ptr ss:,0
10002100|.8D4D EC          lea ecx,dword ptr ss:
10002103|.E8 81080700      call Bfr_1.10072989
10002108|.8B55 F0          mov edx,dword ptr ss:
1000210B|.81E2 FF000000    and edx,0FF
10002111|.85D2             test edx,edx
10002113|.74 1E            je short Bfr_1.10002133            ;如果没有跳,说明是V4注册码
10002115|.C745 D0 01000000 mov dword ptr ss:,1
1000211C|.C745 FC FFFFFFFF mov dword ptr ss:,-1
10002123|.8D4D 08          lea ecx,dword ptr ss:
10002126|.E8 5E080700      call Bfr_1.10072989
1000212B|.8B45 D0          mov eax,dword ptr ss:
1000212E|.E9 E3010000      jmp Bfr_1.10002316
10002133|>68 B4820910      push Bfr_1.100982B4                  ;bgt0exlo5=<ce:ahid?lgjl
10002138|.8D4D C8          lea ecx,dword ptr ss:
1000213B|.E8 12090700      call Bfr_1.10072A52
10002140|.C645 FC 02       mov byte ptr ss:,2
10002144|.8B45 C8          mov eax,dword ptr ss:
10002147|.8945 80          mov dword ptr ss:,eax
1000214A|.8B4D 80          mov ecx,dword ptr ss:
1000214D|.51               push ecx
1000214E|.8B55 08          mov edx,dword ptr ss:
10002151|.52               push edx
10002152|.E8 A2340400      call Bfr_1.100455F9                  ;关键,同上         
10002157|.83C4 08          add esp,8
1000215A|.8985 7CFFFFFF    mov dword ptr ss:,eax
10002160|.33C0             xor eax,eax
10002162|.83BD 7CFFFFFF 00 cmp dword ptr ss:,0
10002169|.0F94C0         sete al
1000216C|.25 FF000000      and eax,0FF
10002171|.85C0             test eax,eax
10002173|.75 5F            jnz short Bfr_1.100021D4
10002175|.68 9C820910      push Bfr_1.1009829C                  ;bgv0fxlz5<<ae:fhhj?lgnk
1000217A|.8D4D C0          lea ecx,dword ptr ss:
1000217D|.E8 D0080700      call Bfr_1.10072A52

跟踪发现此call内出现几串加密后的字符串,很可疑。大致跟进10001FE4处的call得知程序会把加密完成的假码与上述字符比较,但是如果和最上面几个字符串相同,则提示所输入的是V4.0的注册码,如果修改最下面的跳转,则可以注册成功。
   明白了,上面出现的几个字符串都是注册码(不过已经加密),而且不光有软件最新版的注册码,还有老版本的注册码,试想如果我们能找到解密代码,那不就能做出此软件的系列“套装”注册机??
   观察发现我们的假码经过加密后,形式上竟然和真注册码一样,我们大胆的猜测——真码的加密方法是不是也和假码一样?此处还要注意这些加密后的注册码都是23位哦……

   再回到1000D5C1的循环处观察,仔细跟踪,发现软件的加密比较简单(窃喜),上面我已经详细注释了:
   假码的每一位+(其所处位数-1)=相应加密后的字符
   比如:假码是abc,则加密后就是ace。
   
   逆向算法应该是:
   加密后的字符-(其所处的位数-1)=真正的注册码

   我们来用Delphi内嵌汇编写逆向算法,用一个Combobox来存放上面出现的加密后的字符串,一个文本框来显示解密后的注册码,关键代码如下:procedure TForm1.btn1Click(Sender: TObject);
var
TempReg,RegCode:string;
begin
    TempReg:=Form1.ComboBox1.Text;
    asm
            pushad
            xor eax,eax
            xor edx,edx
            xor ecx,ecx
            jmp @Temp1
      @Temp:inc ecx
      @Temp1: mov eax,TempReg
            movzx edx,Byte ptr
            sub edx,ecx
            mov Byte ptr ,dl
            cmp ecx,$16
            jl @Temp
            mov RegCode,ebx
            popad
    end;
    Form1.Edit2.Text:=RegCode;
end;大致如此,时间仓促,我就不再调试了,如需要请自行修改代码。

我们跟踪的结果结合实际测试得出如下对应关系:V4.0前后的注册码:
BGT0EXZO5:<CE:AHCJ?GINK
BGV0FXZZ5B<BE:BBIJ?GJNK

V4.95
BGT0EXZO5;=@B:?CEG?IFNN
BGV0FXZZ5@>=A:CEII?LGJJ


V5.0以上
BGT0EXLO5=<CE:AHID?LGJL
BGV0FXLZ5<<AE:FHHJ?LGNK为了测试上面的代码,我使用逆向编写的Delphi代码对应“BGT0EXLO5=<CE:AHID?LGJL”所生成注册码是“BFR-ASFH-4289-3993-9356”,自己检验一下吧(*^__^*) 嘻嘻……

软件注册后将注册信息加进注册表如下位置:Windows Registry Editor Version 5.00


"registrationKey"="BGT0EXLO5=<CE:AHID?LGJL"看到这种形式,是不是乐了?其实,我们根本不需要去逆向写算法注册机,只要把registrationKey后的值修改成跟踪得出的字符串(注意版本对应关系)并导入注册表即可成功注册o(∩_∩)o...

逆向本身就是学习,给程序员的一点建议:
1.软件尽量加个强壳
2.既然要采取明码比较(即使是半明码)的方式注册,就应该采用不可逆算法对真正的注册码加密,如MD5等等,而且真注册码尽量写入特殊字符,以防止别人爆破MD5值,此类的典型如Quick Batch File
3.加密注册码的算法部分应该多下点功夫,不可应付,否则自己数日编写软件的辛苦终将白费

尊重论坛规则,不放注册机,做良好市民~~~

Nisy 发表于 2008-11-11 16:30:16

不错 学习下 ~
页: [1]
查看完整版本: Better File Rename V5.3.1算法逆向+系列注册机源码