飘云阁

 找回密码
 加入我们

QQ登录

只需一步,快速开始

查看: 3512|回复: 3

[原创] XX电话通 算法分析+Delphi注册机

[复制链接]
  • TA的每日心情
    郁闷
    2021-10-2 23:26
  • 签到天数: 46 天

    [LV.5]常住居民I

    发表于 2009-5-6 19:55:40 | 显示全部楼层 |阅读模式
    标 题: 【原创】 XX电话通 算法分析+Delphi注册机
    作 者: as3852711
    时 间: 2009-05-06,20:20
    链 接: https://www.chinapyg.com/viewthr ... e%3D1&frombbs=1

    ―――――――――――――――――――――――――――――――――――――
    【文章标题】: XX电话通 算法分析+Delphi注册机
    【文章作者】: 莱莉
    【程序名称】: XX电话通.exe
    【程序大小】: 1.01 MB
    【下载地址】: http://www.rayfile.com/zh-cn/fil ... -a7f4-0014221b798a/
    【保护方式】: 注册码
    【编写语言】: Borland Delphi 6.0 - 7.0
    【使用工具】: PEID,OD
    【操作平台】: D-Windows XP3
    【程序介绍】: 一个供给菜鸟学习的练手程序.
    【作者声明】: 我只是一只小菜鸟,失误之处难免,敬望诸位大侠赐教!
    --------------------------------------------------------------------------------
    【详细过程】
      这是一个过期的软件,是N年的前估计已经没什么用了,不过算法就比较简单较为适合我们这种菜鸟学习算法时来练手!


      一、用PEID对程序进行查壳 → UPX 0.89.6 - 1.02 / 1.05 - 1.24 -> Markus & Laszlo ,用ESP定律秒脱,脱完后修复一下便可.

      二、用OD载入程序进行分析。
      
      载入OD后运行程序,试注册一下,有错误提示。用F12暂停法来到下面的地方(0048DA63)。然后我们到段首(0048D628)设置断点.
    ------------------------------(第一部分)----------------------------------------------------------

    1. 0048D628    55              push    ebp
    2. 0048D629    8BEC            mov     ebp, esp
    3. 0048D62B    B9 6E000000     mov     ecx, 6E
    4. 0048D630    6A 00           push    0
    5. 0048D632    6A 00           push    0
    6. 0048D634    49              dec     ecx
    7. 0048D635  ^ 75 F9           jnz     short 0048D630
    8. 0048D637    51              push    ecx
    9. 0048D638    53              push    ebx
    10. 0048D639    56              push    esi
    11. 0048D63A    57              push    edi
    12. 0048D63B    8945 FC         mov     dword ptr [ebp-4], eax
    13. 0048D63E    33C0            xor     eax, eax
    14. 0048D640    55              push    ebp
    15. 0048D641    68 BEDC4800     push    0048DCBE
    16. 0048D646    64:FF30         push    dword ptr fs:[eax]
    17. 0048D649    64:8920         mov     dword ptr fs:[eax], esp
    18. 0048D64C    E8 D7EEFFFF     call    0048C528                         ; 到我们C盘的这个目录获取一些数值:"C:\Documents and Settings\All Users"
    19. 0048D651    E8 2254F7FF     call    00402A78                         ; 对数值作运算;
    20. 0048D656    52              push    edx
    21. 0048D657    50              push    eax
    22. 0048D658    8D85 F0FCFFFF   lea     eax, dword ptr [ebp-310]
    23. 0048D65E    E8 F1ABF7FF     call    00408254                         ; 同上;
    24. 0048D663    8B85 F0FCFFFF   mov     eax, dword ptr [ebp-310]
    25. 0048D669    E8 CE6CF7FF     call    0040433C
    26. 0048D66E    48              dec     eax
    27. 0048D66F    50              push    eax
    28. 0048D670    E8 B3EEFFFF     call    0048C528                         ; 也是到C盘获取数值;
    29. 0048D675    E8 FE53F7FF     call    00402A78                         ; 同样是运算得到的数值;
    30. 0048D67A    52              push    edx
    31. 0048D67B    50              push    eax
    32. 0048D67C    8D85 ECFCFFFF   lea     eax, dword ptr [ebp-314]
    33. 0048D682    E8 CDABF7FF     call    00408254
    34. 0048D687    8B85 ECFCFFFF   mov     eax, dword ptr [ebp-314]         ; 计算后得到一个字符串,我的是(ASCII "2953");
    35. 0048D68D    8D8D F4FCFFFF   lea     ecx, dword ptr [ebp-30C]
    36. 0048D693    5A              pop     edx
    37. 0048D694    E8 4F1DFAFF     call    0042F3E8                         ; 把字符串截取到前三位;
    38. 0048D699    8B85 F4FCFFFF   mov     eax, dword ptr [ebp-30C]         ; 变成了(ASCII "295");
    39. 0048D69F    E8 00ACF7FF     call    004082A4                         ; 字符转化成数字;
    40. 0048D6A4    05 F9030000     add     eax, 3F9                         ; EAX装的是我们转化后的数值(127),加上3F9;
    41. 0048D6A9    69C0 D3020000   imul    eax, eax, 2D3                    ; EAX(520)再乘于2D3;
    42. 0048D6AF    8945 F8         mov     dword ptr [ebp-8], eax           ; 把最后得到的数字(E7960)传递给[EBP-8]这个地址;
    43. 0048D6B2    8D95 E4FCFFFF   lea     edx, dword ptr [ebp-31C]
    44. 0048D6B8    33C0            xor     eax, eax
    复制代码
    以上基本就是本程序的关键算法了,往下走就都是一些读取.INI文件的操作.我就不多说了就提一点,如果你的程序出现了自校验的话,就可到C盘WINDOWS的根目录下把WINDOWS.INI删掉就好了.下面再来说说注册验证的过程.

    ------------------------------(第二部分)-----------------------------------------------------------

    1. 0048D977    8B45 FC         mov     eax, dword ptr [ebp-4]
    2. 0048D97A    8B80 F8020000   mov     eax, dword ptr [eax+2F8]
    3. 0048D980    8B80 08020000   mov     eax, dword ptr [eax+208]
    4. 0048D986    BA 01000000     mov     edx, 1
    5. 0048D98B    E8 FCA3FAFF     call    00437D8C
    6. 0048D990    50              push    eax
    7. 0048D991    8D85 B4FCFFFF   lea     eax, dword ptr [ebp-34C]
    8. 0048D997    8B55 FC         mov     edx, dword ptr [ebp-4]
    9. 0048D99A    81C2 58050000   add     edx, 558
    10. 0048D9A0    E8 3B69F7FF     call    004042E0                     ; 获取用户名:hanyu;
    11. 0048D9A5    8B8D B4FCFFFF   mov     ecx, dword ptr [ebp-34C]
    12. 0048D9AB    8D85 B8FCFFFF   lea     eax, dword ptr [ebp-348]
    13. 0048D9B1    BA 10DE4800     mov     edx, 0048DE10                ; 授权使用:
    14. 0048D9B6    E8 CD69F7FF     call    00404388
    15. 0048D9BB    8B95 B8FCFFFF   mov     edx, dword ptr [ebp-348]     ; //在这里用户名不参与注册码的计算,只作标识罢了;
    16. 0048D9C1    58              pop     eax
    17. 0048D9C2    E8 21A3FAFF     call    00437CE8
    18. 0048D9C7    8D85 ACFCFFFF   lea     eax, dword ptr [ebp-354]
    19. 0048D9CD    8B55 FC         mov     edx, dword ptr [ebp-4]
    20. 0048D9D0    81C2 58050000   add     edx, 558
    21. 0048D9D6    E8 0569F7FF     call    004042E0
    22. 0048D9DB    8B8D ACFCFFFF   mov     ecx, dword ptr [ebp-354]
    23. 0048D9E1    8D85 B0FCFFFF   lea     eax, dword ptr [ebp-350]
    24. 0048D9E7    BA 24DE4800     mov     edx, 0048DE24                ; 本软件授权于:
    25. 0048D9EC    E8 9769F7FF     call    00404388
    26. 0048D9F1    8B95 B0FCFFFF   mov     edx, dword ptr [ebp-350]
    27. 0048D9F7    8B45 FC         mov     eax, dword ptr [ebp-4]
    28. 0048D9FA    8B80 34030000   mov     eax, dword ptr [eax+334]
    29. 0048DA00    E8 BB94FCFF     call    00456EC0
    30. 0048DA05    8D85 A4FCFFFF   lea     eax, dword ptr [ebp-35C]
    31. 0048DA0B    8B55 FC         mov     edx, dword ptr [ebp-4]
    32. 0048DA0E    81C2 58060000   add     edx, 658
    33. 0048DA14    E8 C768F7FF     call    004042E0                     ; 获取假码;
    34. 0048DA19    8B85 A4FCFFFF   mov     eax, dword ptr [ebp-35C]     ; 把假码(ASCII "123456"),传递给EAX;
    35. 0048DA1F    8D95 A8FCFFFF   lea     edx, dword ptr [ebp-358]
    36. 0048DA25    E8 B2EBFFFF     call    0048C5DC                     ; 关键算法CALL;
    37. 0048DA2A    8B85 A8FCFFFF   mov     eax, dword ptr [ebp-358]     ; 计算后得到假码字符串:(ASCII "2296281783")
    38. 0048DA30    50              push    eax
    39. 0048DA31    8D95 9CFCFFFF   lea     edx, dword ptr [ebp-364]
    40. 0048DA37    8B45 F8         mov     eax, dword ptr [ebp-8]
    41. 0048DA3A    E8 29A7F7FF     call    00408168                     ; 把第一部分算法得到的(E7960)数值转化成字符串;
    42. 0048DA3F    8B85 9CFCFFFF   mov     eax, dword ptr [ebp-364]     ; 得到(ASCII "948576");
    43. 0048DA45    8D95 A0FCFFFF   lea     edx, dword ptr [ebp-360]
    44. 0048DA4B    E8 8CEBFFFF     call    0048C5DC                     ; 也是关键算法CALL它和假码的运算CALL是一样的都是(0048C5DC);
    45. 0048DA50    8B95 A0FCFFFF   mov     edx, dword ptr [ebp-360]     ; 最后得到正确注册码:(ASCII "17643513783");
    46. 0048DA56    58              pop     eax                          ; 假码运算后得到的字符串:ASCII "2296281783"
    47. 0048DA57    E8 2C6AF7FF     call    00404488                     ; 经典字符串比较CALL;
    48. 0048DA5C    74 05           je      short 0048DA63               ; 关键跳转;(可作内存补丁);
    49. 0048DA5E    E8 3DF9FFFF     call    0048D3A0
    50. 0048DA63    8D85 F8FDFFFF   lea     eax, dword ptr [ebp-208]
    复制代码
    好了看完注册验证机制之后,我们再来看看关键算法CALL吧!


    ------------------------------(第三部分)-----------------------------------------------------------

    1. 0048C5DC    55              push    ebp
    2. 0048C5DD    8BEC            mov     ebp, esp
    3. 0048C5DF    83C4 F8         add     esp, -8
    4. 0048C5E2    53              push    ebx
    5. 0048C5E3    33C9            xor     ecx, ecx
    6. 0048C5E5    894D F8         mov     dword ptr [ebp-8], ecx
    7. 0048C5E8    8BDA            mov     ebx, edx
    8. 0048C5EA    8945 FC         mov     dword ptr [ebp-4], eax
    9. 0048C5ED    8B45 FC         mov     eax, dword ptr [ebp-4]
    10. 0048C5F0    E8 377FF7FF     call    0040452C
    11. 0048C5F5    33C0            xor     eax, eax
    12. 0048C5F7    55              push    ebp
    13. 0048C5F8    68 44C64800     push    0048C644
    14. 0048C5FD    64:FF30         push    dword ptr fs:[eax]
    15. 0048C600    64:8920         mov     dword ptr fs:[eax], esp
    16. 0048C603    8B45 FC         mov     eax, dword ptr [ebp-4]
    17. 0048C606    E8 99BCF7FF     call    004082A4                         ; 把字符串(ASCII "948576"),转化成数值;
    18. 0048C60B    69C0 BA000000   imul    eax, eax, 0BA                    ; 得到数值(E7960)乘于OBA;
    19. 0048C611    40              inc     eax                              ; 积(A842FC0)加1;
    20. 0048C612    8D55 F8         lea     edx, dword ptr [ebp-8]           ; 把[EBP-8]地址中的数值传递到EDX中;
    21. 0048C615    E8 4EBBF7FF     call    00408168                         ; 把数值转化成ASCII码;
    22. 0048C61A    8B55 F8         mov     edx, dword ptr [ebp-8]           ; 得到字符串:(ASCII "176435137")
    23. 0048C61D    8BC3            mov     eax, ebx
    24. 0048C61F    B9 58C64800     mov     ecx, 0048C658                    ; 83
    25. 0048C624    E8 5F7DF7FF     call    00404388                         ; 连接"83"和"176435137"两段字符串;
    26. 0048C629    33C0            xor     eax, eax
    27. 0048C62B    5A              pop     edx
    复制代码
    那个算法CALL也就只是简单的对数值做一下加,乘运算罢了.好了,当我们了解了整个注册机制以后,那么软件的作者又是如何发放注册码的了,只要我们细心看看提示就知道了.它是通过机器码来提供注册信息的,好现在我们就来看它的机器码是如何获取的,运用DELPHI获取按钮入口的方法,来到如下代码段:


    ------------------------------(第四部分)-----------------------------------------------------------

    1. 0048DECC    55              push    ebp
    2. 0048DECD    8BEC            mov     ebp, esp
    3. 0048DECF    33C9            xor     ecx, ecx
    4. 0048DED1    51              push    ecx
    5. 0048DED2    51              push    ecx
    6. 0048DED3    51              push    ecx
    7. 0048DED4    51              push    ecx
    8. 0048DED5    53              push    ebx
    9. 0048DED6    8BD8            mov     ebx, eax
    10. 0048DED8    33C0            xor     eax, eax
    11. 0048DEDA    55              push    ebp
    12. 0048DEDB    68 68DF4800     push    0048DF68
    13. 0048DEE0    64:FF30         push    dword ptr fs:[eax]
    14. 0048DEE3    64:8920         mov     dword ptr fs:[eax], esp
    15. 0048DEE6    E8 3DE6FFFF     call    0048C528
    16. 0048DEEB    E8 884BF7FF     call    00402A78
    17. 0048DEF0    52              push    edx
    18. 0048DEF1    50              push    eax
    19. 0048DEF2    8D45 F4         lea     eax, dword ptr [ebp-C]
    20. 0048DEF5    E8 5AA3F7FF     call    00408254
    21. 0048DEFA    8B45 F4         mov     eax, dword ptr [ebp-C]
    22. 0048DEFD    E8 3A64F7FF     call    0040433C
    23. 0048DF02    48              dec     eax
    24. 0048DF03    50              push    eax
    25. 0048DF04    E8 1FE6FFFF     call    0048C528
    26. 0048DF09    E8 6A4BF7FF     call    00402A78
    27. 0048DF0E    52              push    edx
    28. 0048DF0F    50              push    eax
    29. 0048DF10    8D45 F0         lea     eax, dword ptr [ebp-10]
    30. 0048DF13    E8 3CA3F7FF     call    00408254
    31. 0048DF18    8B45 F0         mov     eax, dword ptr [ebp-10]
    32. 0048DF1B    8D4D F8         lea     ecx, dword ptr [ebp-8]
    33. 0048DF1E    5A              pop     edx
    34. 0048DF1F    E8 C414FAFF     call    0042F3E8                       ; //以上的代码是不是很面熟啊!其实它和我们在开始看到的代码基本一样的都是用来获取 C盘的数据的;
    35. 0048DF24    8B45 F8         mov     eax, dword ptr [ebp-8]         ; 也是截取了头三位(ASCII "295");
    36. 0048DF27    E8 78A3F7FF     call    004082A4                       ; 同样是把字符转化成数字;
    37. 0048DF2C    69C0 D3020000   imul    eax, eax, 2D3                  ; 数值EAX(127)乘与2D3
    38. 0048DF32    05 F9030000     add     eax, 3F9                       ; eax=00034125再加上3F9;
    39. 0048DF37    8D55 FC         lea     edx, dword ptr [ebp-4]
    40. 0048DF3A    E8 29A2F7FF     call    00408168
    41. 0048DF3F    8B55 FC         mov     edx, dword ptr [ebp-4]         ; 数值转换成字符了:(ASCII "214302");
    42. 0048DF42    8B83 44050000   mov     eax, dword ptr [ebx+544]       ; //其实机器码和开始认证时的算法只是颠倒了一下循序而已,一个先加
    43. 0048DF48    E8 738FFCFF     call    00456EC0                       ; //后乘,另一个先乘后加;
    44. 0048DF4D    33C0            xor     eax, eax
    45. 0048DF4F    5A              pop     edx
    46. 0048DF50    59              pop     ecx
    47. 0048DF51    59              pop     ecx
    复制代码
    ---------------------------------------------------------------------------------------------
    【经验总结】
    1.我们要大概了解重启验证的程序它们的都有一个启动认证的注册部分,平时我们搞自校或是ANTI基本上都能在这里能搞定;

    2.要看懂基本的汇编指令,不懂也没问题.但是人手要有一个汇编指令查询器,我个人一直以来都是用"黑夜"兄汇编查询器.如果你连指令都看不懂,那么程序对数值做了什么操作你又怎么能知道呢!

    3.写算法注册机:放三个EXIT控件,以及一个BUTTON控件把源代码复制进去便可;

    ---------------------------------------------------------------------------------------------
    破解感悟】
      本人认为这个算法机制相当的不切合实际,先不说它的注册码计算的难易程度.就取C盘数据而言,如果人家使用的是GHOST版本的XP的话,那么就只有一个超级用户.此时C盘的All Users文件里的数据就会不时的变动.我叫人帮我调试注册机时,就发生过这种情况机器码不停的发生改变.也不懂作者是如何解决这个问题的,难道连他本人都是用内存补丁么?再来就是注册码验证部分,做的实在是有点画蛇添足了.他在0048DA3F处把注册码呈现出来了,然后又让此数值给运算了一遍.我真的搞不懂他的用意何在,要是你说要屏蔽掉人家的内存注册机的话,那么你就不要在0048DA3F处把注册码给字符化,这样就可避免人家编写内存的可能性.你现在把它字符化了然后又再数值化,都在做"无用工"耗内存.最后提醒一下大家,我们设计注册机制时千万不要使用一些不稳定的数值,如本题的C盘数据你可用电脑用户名,网卡号等等不易改变的数值皆可!

    【版权声明】: 转载请注明作者并保持文章的完整, 谢谢! 软件久远,如有雷同,敬请理解.

    [ 本帖最后由 as3852711 于 2009-5-6 20:00 编辑 ]
    PYG19周年生日快乐!
  • TA的每日心情
    郁闷
    2021-10-2 23:26
  • 签到天数: 46 天

    [LV.5]常住居民I

     楼主| 发表于 2009-5-6 19:57:44 | 显示全部楼层

    Delphi 注册机源码:

    --------------------------------------------------------------------------------------------------------

    1. procedure TForm1.Button1Click(Sender: TObject);
    2. var
    3. code:Double;  //定义注册码数值的变量;
    4. i:integer;    //定义记数变量;
    5. begin
    6. val(edit1.Text,code,i);  //把字符格式化成数字函数;
    7. if i = 0 then     //如果I等于0说明是一个整型数值;
    8. begin
    9.    if edit2.text <> '' then    //判断用户为不为空;
    10.    begin
    11.     code := (code - $3F9) / $2D3;   //把机器码进行运算得出C盘数据;
    12.     edit3.Text :=floattostr((code + $3F9) * $2D3 );    //再用得到的数据运算,最后转化成字符串;
    13.    end
    14.    else
    15.    showmessage('Please input your Name !');
    16. end
    17. else
    18. showmessage('Please input Number to Machine !');
    19. end;
    复制代码

    [ 本帖最后由 as3852711 于 2009-5-6 20:01 编辑 ]
    PYG19周年生日快乐!
  • TA的每日心情
    无聊
    2017-5-31 13:17
  • 签到天数: 5 天

    [LV.2]偶尔看看I

    发表于 2010-8-6 11:40:07 | 显示全部楼层
    谢谢,/:018
    PYG19周年生日快乐!

    该用户从未签到

    发表于 2010-8-6 12:02:19 | 显示全部楼层
    09的帖子/ch,支持一个
    PYG19周年生日快乐!
    您需要登录后才可以回帖 登录 | 加入我们

    本版积分规则

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