飘云阁

 找回密码
 加入我们

QQ登录

只需一步,快速开始

查看: 7632|回复: 6

[原创] 一款图象处理软件 PhoXo v6.0 的注册算法分析 + 注册机源代码

[复制链接]

该用户从未签到

发表于 2007-11-10 16:14:01 | 显示全部楼层 |阅读模式
一款图象处理软件 PhoXo v6.0 的注册算法分析 + 注册机源代码


一款感觉还不错的图象处理软件,分析了下,简单写出来。

软件在未注册的状态下,每次启动时会弹出一个NAG提示对话框;先打开注册窗口,输入注册名:aCaFeeL,输入注册码:12345678,点击OK按钮,程序提示下次启动时检查。

故确定软件用的是重启验证的方式,将PhoXo.exe文件拖入OD中后,下断点: bp MessageBoxExA,按F9键运行程序,此时程序被中断下来:

>>>>>>
77D5055C >/$  8BFF               mov     edi, edi                   ; 被断在了这里
77D5055E  |.  55                 push    ebp
77D5055F  |.  8BEC               mov     ebp, esp
77D50561  |.  6A FF              push    -1
77D50563  |.  FF75 18            push    dword ptr [ebp+18]
77D50566  |.  FF75 14            push    dword ptr [ebp+14]
77D50569  |.  FF75 10            push    dword ptr [ebp+10]
77D5056C  |.  FF75 0C            push    dword ptr [ebp+C]
77D5056F  |.  FF75 08            push    dword ptr [ebp+8]
77D50572  |.  E8 4D5A0100        call    USER32.MessageBoxTimeoutA
77D50577  |.  5D                 pop     ebp
77D50578  \.  C2 1400            retn    14
>>>>>>



再按ALT+F9建后,弹出NAG对话框,点击‘OK’按钮后,便回到了PhoXo的领空:

>>>>>>
0055B883  |> \53                 push    ebx                        ; /Style
0055B884  |.  57                 push    edi                        ; |Title
0055B885  |.  FF75 08            push    dword ptr [ebp+8]          ; |Text
0055B888  |.  FF75 F4            push    dword ptr [ebp-C]          ; |hOwner
0055B88B  |.  FF15 B4E55700      call    dword ptr [<&USER32.Messag>; \MessageBoxA
0055B891  |.  85F6               test    esi, esi                   ; 回到了这里!
0055B893  |.  8BF8               mov     edi, eax
0055B895  |.  74 05              je      short PhoXo.0055B89C
0055B897  |.  8B45 F8            mov     eax, dword ptr [ebp-8]
0055B89A  |.  8906               mov     dword ptr [esi], eax
0055B89C  |>  837D FC 00         cmp     dword ptr [ebp-4], 0
0055B8A0      74 0B              je      short PhoXo.0055B8AD
0055B8A2  |.  6A 01              push    1                          ; /Enable = TRUE
0055B8A4  |.  FF75 FC            push    dword ptr [ebp-4]          ; |hWnd
0055B8A7  |.  FF15 C0E75700      call    dword ptr [<&USER32.Enable>; \EnableWindow
0055B8AD  |>  8B4D F0            mov     ecx, dword ptr [ebp-10]
0055B8B0  |.  6A 01              push    1
0055B8B2  |.  E8 F4FEFFFF        call    PhoXo.0055B7AB
0055B8B7  |.  8BC7               mov     eax, edi
0055B8B9  |.  5F                 pop     edi
0055B8BA  |.  5E                 pop     esi
0055B8BB  |.  5B                 pop     ebx
0055B8BC  |.  C9                 leave
0055B8BD  \.  C2 0C00            retn    0C
>>>>>>



F8键走完上面这个子call后,在继续分析,便来到了这里:

>>>>>>
0040B001   .  51                 push    ecx
0040B002   .  52                 push    edx
0040B003   .  C68424 58010000 18 mov     byte ptr [esp+158], 18
0040B00B   .  E8 D0510200        call    PhoXo.004301E0
0040B010   .  8B4424 2C          mov     eax, dword ptr [esp+2C]    ;  注册码 -> eax
0040B014   .  83C4 08            add     esp, 8
0040B017   .  85C0               test    eax, eax
0040B019   .  75 05              jnz     short PhoXo.0040B020
0040B01B   .  B8 D0F35700        mov     eax, PhoXo.0057F3D0
0040B020   >  8B4C24 28          mov     ecx, dword ptr [esp+28]    ;  注册码长度 -> ecx
0040B024   .  51                 push    ecx
0040B025   .  50                 push    eax
0040B026   .  E8 D54F0200        call    PhoXo.00430000             ;  注册算法,F7键进入分析:
0040B02B   .  83C4 08            add     esp, 8
0040B02E   .  8D4C24 20          lea     ecx, dword ptr [esp+20]
0040B032   .  8AD8               mov     bl, al
0040B034   .  C68424 50010000 17 mov     byte ptr [esp+150], 17
0040B03C   .  6A 01              push    1
0040B03E   .  E8 AD5D0000        call    PhoXo.00410DF0
0040B043   .  6A 01              push    1
0040B045   .  8D4C24 34          lea     ecx, dword ptr [esp+34]
0040B049   .  C68424 54010000 13 mov     byte ptr [esp+154], 13
0040B051   .  E8 9A5D0000        call    PhoXo.00410DF0
0040B056   .  84DB               test    bl, bl                     ;  bl = 0 ?
0040B058      75 0E              jnz     short PhoXo.0040B068       ;  关键跳,bl<>0,一跳便OK了
0040B05A   .  6A FF              push    -1
0040B05C   .  6A 00              push    0
0040B05E   .  68 81270000        push    2781
0040B063   .  E8 90081500        call    PhoXo.0055B8F8             ;  弹出NAG对话框
0040B068   >  8D4C24 40          lea     ecx, dword ptr [esp+40]    ;  停留在了这里,向上分析▲
0040B06C   .  C68424 50010000 12 mov     byte ptr [esp+150], 12
0040B074   .  E8 DEC31500        call    PhoXo.00567457
0040B079   .  8D9424 EC000000    lea     edx, dword ptr [esp+EC]
>>>>>>



毫无疑问,注册成功与否,便是看 0040B056 这里的bl是否为0了,不为0才注册成功,要分析算法,自然要进入 0040B026 地址的:

0040B026   .  E8 D54F0200        call    PhoXo.00430000

在这里F2键下断,用OD重新载入程序后,F9键运行,便断在了这里,按F7建进入该子程序后:

>>>>>>
00430000  /$  64:A1 00000000     mov     eax, dword ptr fs:[0]      ;  注册算法,开始:
00430006  |.  6A FF              push    -1
00430008  |.  68 601A5700        push    PhoXo.00571A60
0043000D  |.  8B5424 0C          mov     edx, dword ptr [esp+C]     ;  注册码 -> edx
00430011  |.  50                 push    eax
00430012  |.  64:8925 00000000   mov     dword ptr fs:[0], esp
00430019  |.  83EC 40            sub     esp, 40
0043001C  |.  56                 push    esi
0043001D  |.  33F6               xor     esi, esi                   ;  esi 清零
0043001F  |.  3BD6               cmp     edx, esi                   ;  edx 与 esi 比较
00430021  |.  0F84 A1010000      je      PhoXo.004301C8             ;  注册码为空,则跳
00430027  |.  837C24 58 0B       cmp     dword ptr [esp+58], 0B     ;  注册码长度与 $0B 比较
0043002C  |.  0F85 96010000      jnz     PhoXo.004301C8             ;  不等则跳走
00430032  |.  807A 05 2D         cmp     byte ptr [edx+5], 2D       ;  注册码第6位的ASCII码与 $2D 比较
00430036  |.  0F85 8C010000      jnz     PhoXo.004301C8             ;  不同则跳走
0043003C  |.  53                 push    ebx
0043003D  |.  57                 push    edi
0043003E  |.  B9 08000000        mov     ecx, 8                     ;  ecx := 8;
00430043  |.  33C0               xor     eax, eax                   ;  eax 清零
00430045  |.  8D7C24 2C          lea     edi, dword ptr [esp+2C]
00430049  |.  F3:AB              rep     stos dword ptr es:[edi]
0043004B  |.  8B02               mov     eax, dword ptr [edx]       ;  注册码1-4位 -> eax
0043004D      8B4A 04            mov     ecx, dword ptr [edx+4]     ;  注册码5-8位 -> ecx
00430050  |.  894424 2C          mov     dword ptr [esp+2C], eax
00430054  |.  66:8B42 08         mov     ax, word ptr [edx+8]       ;  注册码9,10位 -> ax
00430058  |.  894C24 30          mov     dword ptr [esp+30], ecx
0043005C  |.  8A4A 0A            mov     cl, byte ptr [edx+A]       ;  注册码11位 -> cl
0043005F  |.  66:894424 34       mov     word ptr [esp+34], ax
00430064  |.  884C24 36          mov     byte ptr [esp+36], cl
00430068  |.  33C0               xor     eax, eax                   ;  eax 清零
0043006A  |>  83F8 03            /cmp     eax, 3                    ;  eax 与 $3 比较
0043006D  |.  75 13              |jnz     short PhoXo.00430082      ;  不相等,跳
0043006F  |.  8A5424 35          |mov     dl, byte ptr [esp+35]     ;  注册码第10位 -> dl
00430073  |.  8A4C24 2F          |mov     cl, byte ptr [esp+2F]     ;  注册码第4位 -> cl
00430077  |.  80EA 30            |sub     dl, 30                    ;  dl := dl - $30;
0043007A  |.  02CA               |add     cl, dl                    ;  cl := cl + dl;
0043007C  |.  884C24 2F          |mov     byte ptr [esp+2F], cl     ;  重新写回 注册码第4位
00430080  |.  EB 11              |jmp     short PhoXo.00430093
00430082  |>  8A4C04 32          |mov     cl, byte ptr [esp+eax+32] ;  注册码第7,8,9,11位依次 -> cl
00430086  |.  8A5C04 2C          |mov     bl, byte ptr [esp+eax+2C] ;  注册码第1,2,3,5位依次 -> bl
0043008A  |.  2ACB               |sub     cl, bl                    ;  cl := cl - bl;
0043008C  |.  80C1 30            |add     cl, 30                    ;  cl := cl + $30;
0043008F  |.  884C04 2C          |mov     byte ptr [esp+eax+2C], cl ;  依次重新写回 注册码第1,2,3,5位
00430093  |>  40                 |inc     eax                       ;  eax := eax + 1;
00430094  |.  83F8 05            |cmp     eax, 5                    ;  eax 与 5 比较
00430097  |.^ 7C D1              \jl      short PhoXo.0043006A      ;  小于5,继续循环
00430099  |.  BF F4EB5C00        mov     edi, PhoXo.005CEBF4        ;  PhoXo -> edi
0043009E  |.  83C9 FF            or      ecx, FFFFFFFF
004300A1  |.  33C0               xor     eax, eax                   ;  eax 清零
004300A3  |.  8A5424 5C          mov     dl, byte ptr [esp+5C]
004300A7  |.  F2:AE              repne   scas byte ptr es:[edi]
004300A9  |.  F7D1               not     ecx                        ;  取反
004300AB  |.  49                 dec     ecx                        ;  ecx := ecx -1;
004300AC  |.  C64424 31 00       mov     byte ptr [esp+31], 0       ;  新生成的字符串的6位 设置为0
004300B1  |.  51                 push    ecx
004300B2  |.  68 F4EB5C00        push    PhoXo.005CEBF4             ;  PhoXo
004300B7  |.  8D4C24 24          lea     ecx, dword ptr [esp+24]    ;  'PhoXo' -> ecx
004300BB  |.  885424 24          mov     byte ptr [esp+24], dl
004300BF  |.  897424 28          mov     dword ptr [esp+28], esi
004300C3  |.  897424 2C          mov     dword ptr [esp+2C], esi
004300C7  |.  897424 30          mov     dword ptr [esp+30], esi
004300CB  |.  E8 F00BFEFF        call    PhoXo.00410CC0
004300D0  |.  8A4424 5C          mov     al, byte ptr [esp+5C]
004300D4  |.  8D7C24 2C          lea     edi, dword ptr [esp+2C]    ;  取新生成的字符串的前5位 -> edi
004300D8  |.  884424 0C          mov     byte ptr [esp+C], al
004300DC  |.  83C9 FF            or      ecx, FFFFFFFF
004300DF  |.  33C0               xor     eax, eax                   ;  eax 清零
004300E1  |.  897424 54          mov     dword ptr [esp+54], esi
004300E5  |.  F2:AE              repne   scas byte ptr es:[edi]
004300E7  |.  F7D1               not     ecx                        ;  取反
004300E9  |.  49                 dec     ecx                        ;  ecx := ecx -1;
004300EA  |.  897424 10          mov     dword ptr [esp+10], esi
004300EE  |.  51                 push    ecx
004300EF  |.  8D4C24 30          lea     ecx, dword ptr [esp+30]    ;  取新生成的字符串的前5位 -> ecx
004300F3  |.  51                 push    ecx
004300F4  |.  8D4C24 14          lea     ecx, dword ptr [esp+14]
004300F8  |.  897424 1C          mov     dword ptr [esp+1C], esi
004300FC  |.  897424 20          mov     dword ptr [esp+20], esi
00430100  |.  E8 BB0BFEFF        call    PhoXo.00410CC0
00430105  |.  8B4424 20          mov     eax, dword ptr [esp+20]    ;  'PhoXo' -> eax
00430109  |.  3BC6               cmp     eax, esi                   ;  比较是否为空
0043010B  |.  75 05              jnz     short PhoXo.00430112       ;  不为空字符串,跳
0043010D  |.  B8 D0F35700        mov     eax, PhoXo.0057F3D0
00430112  |>  8B5424 14          mov     edx, dword ptr [esp+14]
00430116  |.  8B5C24 24          mov     ebx, dword ptr [esp+24]
0043011A  |.  3BD3               cmp     edx, ebx
0043011C  |.  8BCA               mov     ecx, edx
0043011E  |.  72 02              jb      short PhoXo.00430122
00430120  |.  8BCB               mov     ecx, ebx
00430122  |>  55                 push    ebp
00430123  |.  8B6C24 14          mov     ebp, dword ptr [esp+14]    ;  取新生成的字符串的前5位 -> ebp
00430127  |.  8BF8               mov     edi, eax                   ;  'PhoXo' -> edi
00430129  |.  8BF5               mov     esi, ebp                   ;  取新生成的字符串的前5位 -> esi
0043012B  |.  33C0               xor     eax, eax
0043012D  |.  F3:A6              repe    cmps byte ptr es:[edi], by>;  取新生成的字符串的前5位 = 'PhoXo' ??
0043012F      74 05              je      short PhoXo.00430136       ;  相等,则成功,跳!
00430131  |.  1BC0               sbb     eax, eax
00430133  |.  83D8 FF            sbb     eax, -1
00430136  |>  33F6               xor     esi, esi
>>>>>>



通过上面的分析,我们知道了其注册算法的方式为:

读入注册名和注册码,注册码的长度应该为11位,且第6位必须为‘-’字符;

即是:
将:【注册码第 7位的ASCII值 - 注册码第1位的ASCII值 + $30】的结果 重新写回 注册码的第1位;
将:【注册码第 8位的ASCII值 - 注册码第2位的ASCII值 + $30】的结果 重新写回 注册码的第2位;
将:【注册码第 9位的ASCII值 - 注册码第3位的ASCII值 + $30】的结果 重新写回 注册码的第3位;
将:【注册码第10位的ASCII值 + 注册码第4位的ASCII值 - $30】的结果 重新写回 注册码的第4位;
将:【注册码第11位的ASCII值 - 注册码第5位的ASCII值 + $30】的结果 重新写回 注册码的第5位;

然后这个新生成的11位长度的字符串,取该新字符串的前5位(即上面运算的5个结果),与字符串 PhoXo 比较,只要两者相等,便注册成功了!

比如,输入假注册码:12345-789AB 后,经过上面的运算,便得到了 666E=-789AB 这个新字符串,取这个新字符串的前5位:666E=,然后与字符串PhoXo比较,看是否相同,相同,便注册成功了!



其注册算法转换成用 Delphi + KOL/MCK 写的代码即是如下形式:(已写成为一个string函数格式,方便你的调用和修改,嘿嘿 :)


function PhoXo_sn(codechk: string): string;   //PhoXo v6.0 软件的算法函数
var
  i, bl, cl, dl : integer;
begin
for i:=1 to 5 do    //还原 PhoXo v6.0 软件本身的算法
    begin
      if (i=4)
      then begin
             dl := ord(codechk[i + 6]);//注册码第10位
             cl := ord(codechk);    //注册码第 4位
             dl := dl - $30;
             cl := cl + dl;
             codechk := chr(cl);
           end
      else begin
             cl := ord(codechk[i + 6]);//注册码第7,8,9,11位依次
             bl := ord(codechk);    //注册码第1,2,3, 5位依次
             cl := cl - bl;
             cl := cl + $30;
             codechk := chr(cl);
           end;
  end;
  Result := codechk;
end;



而根据上面的算法,也就可以写出一个可用的注册机了;
用 Delphi + KOL/MCK 写的代码即是如下形式:(已写成为一个string函数格式,方便你的调用和修改,嘿嘿 :)


function PhoXo_KeyGen(RegName : string): string;  //PhoXo v6.0 注册机算法
var
  i : integer;
begin
  if RegName = ''
  then begin
         showmessage('InPut Your Name, First!');
         exit;
       end
  else Regname := 'PhoXo-' +
                   chr(ord($61 + random(26)))+
                   chr(ord($61 + random(26)))+
                   chr(ord($61 + random(26)))+
                   chr(ord($41 + random(26)))+
                   chr(ord($61 + random(26)));
  for i:=1 to 5 do
    begin
      case i of     //注册码第7,8,9,10,11位依次和字符串PhoXo运算
        1: Regname := chr($30 + ord(Regname[i+6]) - ord('P'));
        2: Regname := chr($30 + ord(Regname[i+6]) - ord('h'));
        3: Regname := chr($30 + ord(Regname[i+6]) - ord('o'));
        4: Regname := chr($30 - ord(Regname[i+6]) + ord('X'));
        5: Regname := chr($30 + ord(Regname[i+6]) - ord('o'));
      end;
    end;
  Result := Regname;
end;



上面的注册机算法在多台机器上使用不同注册名通过验证,但没有时间再优化它了,应该不存在bug的问题;

软件输入的注册信息保存在 register.ini 文件中,其格式为: 注册名长度 00 00 00 注册名 注册码长度 00 00 00 注册码



放上几组可用的Key:

注册名:aCaFeeL

注册码:QB(6)-qzgRh         或者
        J6222-jnqVq         或者
        MA814-mywWs         或者
        L=9=9-luxKx         或者
        T-546-tetTu         或者
        R+246-rcqTu         或者
        焎症-!注册         或者
        搼z忖-成功!


好的,就到这里结束吧!分析难免有不当之处,还望大家给我指出来!
PYG19周年生日快乐!

该用户从未签到

发表于 2007-11-10 18:31:36 | 显示全部楼层
抢先顶贴 , 保存一下该可以学到很多东西的, 嗯
PYG19周年生日快乐!

该用户从未签到

 楼主| 发表于 2007-11-16 14:13:44 | 显示全部楼层
原帖由 lgjxj 于 2007-11-10 18:31 发表
抢先顶贴 , 保存一下该可以学到很多东西的, 嗯

KAN大哥,不许过分谦虚哈~
PYG19周年生日快乐!

该用户从未签到

发表于 2007-11-19 17:07:32 | 显示全部楼层
学习逆向工程ing...
PYG19周年生日快乐!
  • TA的每日心情
    擦汗
    2017-9-24 22:49
  • 签到天数: 4 天

    [LV.2]偶尔看看I

    发表于 2007-11-21 17:09:45 | 显示全部楼层
    好东西,谢谢楼主
    PYG19周年生日快乐!
  • TA的每日心情
    擦汗
    2017-9-24 22:49
  • 签到天数: 4 天

    [LV.2]偶尔看看I

    发表于 2007-11-22 09:39:10 | 显示全部楼层
    可以学到很多东西的
    PYG19周年生日快乐!
  • TA的每日心情
    开心
    2024-8-24 08:50
  • 签到天数: 137 天

    [LV.7]常住居民III

    发表于 2007-11-22 10:55:43 | 显示全部楼层
    好东西!!!!继续吧
    PYG19周年生日快乐!
    您需要登录后才可以回帖 登录 | 加入我们

    本版积分规则

    快速回复 返回顶部 返回列表