飘云阁

 找回密码
 加入我们

QQ登录

只需一步,快速开始

查看: 1870|回复: 6

[08版] 移花接木解决程序的多重效检

[复制链接]

该用户从未签到

发表于 2008-6-14 15:46:58 | 显示全部楼层 |阅读模式
——

    本课的分析目标为:IP-Tools 2.54,程序非明码,无壳,有自效检。我们通过这个个例的分析来了解非码文比较的程序的验证过程,以及处理程序的效检的基本思路。我们OD载入程序,运行后随意输入注册信息,下万能断点,中断后返回到程序凌空,我们在这里下断:

0050F174  |.  E8 9B6FF2FF   CALL Ip_tools.00436114
0050F179  |.  8B45 F8       MOV EAX,DWORD PTR SS:[EBP-8]             ;  下万能断点 返回到这里
0050F17C  |.  8D55 FC       LEA EDX,DWORD PTR SS:[EBP-4]
0050F17F  |.  E8 40A3EFFF   CALL Ip_tools.004094C4
……
……
0050F1C0  |.  E8 4F6FF2FF   CALL Ip_tools.00436114
0050F1C5  |.  8B45 EC       MOV EAX,DWORD PTR SS:[EBP-14]
0050F1C8  |.  E8 47A1FCFF   CALL Ip_tools.004D9314                   ;  比较用户名是否在黑名单
0050F1CD  |.  84C0          TEST AL,AL
0050F1CF  |.  74 3C         JE SHORT Ip_tools.0050F20D
……
……
0050F218  |.  E8 F76EF2FF   CALL Ip_tools.00436114
0050F21D  |.  837D E0 00    CMP DWORD PTR SS:[EBP-20],0              ;  比较用户名是否为空
0050F221  |.  0F84 CB010000 JE Ip_tools.0050F3F2
0050F227  |.  8D55 DC       LEA EDX,DWORD PTR SS:[EBP-24]
0050F22A  |.  8B06          MOV EAX,DWORD PTR DS:[ESI]
0050F22C  |.  8B80 E8020000 MOV EAX,DWORD PTR DS:[EAX+2E8]
0050F232  |.  E8 DD6EF2FF   CALL Ip_tools.00436114
0050F237  |.  837D DC 00    CMP DWORD PTR SS:[EBP-24],0
0050F23B  |.  0F84 B1010000 JE Ip_tools.0050F3F2                     ;  比较注册码是否为空
0050F241  |.  8D55 D8       LEA EDX,DWORD PTR SS:[EBP-28]
0050F244  |.  8B06          MOV EAX,DWORD PTR DS:[ESI]
0050F246  |.  8B80 E4020000 MOV EAX,DWORD PTR DS:[EAX+2E4]
0050F24C  |.  E8 C36EF2FF   CALL Ip_tools.00436114
0050F251  |.  8B45 D8       MOV EAX,DWORD PTR SS:[EBP-28]            ;  用户名送EAX
0050F254  |.  E8 13BFFEFF   CALL Ip_tools.004FB16C                   ;  对用户名做加密运算 设为 f(name)
0050F259  |.  8BF8          MOV EDI,EAX
0050F25B  |.  8D55 D4       LEA EDX,DWORD PTR SS:[EBP-2C]
0050F25E  |.  8B06          MOV EAX,DWORD PTR DS:[ESI]
0050F260  |.  8B80 E8020000 MOV EAX,DWORD PTR DS:[EAX+2E8]
0050F266  |.  E8 A96EF2FF   CALL Ip_tools.00436114
0050F26B  |.  8B45 D4       MOV EAX,DWORD PTR SS:[EBP-2C]            ;  注册码送EAX
0050F26E  |.  E8 95BFFEFF   CALL Ip_tools.004FB208                   ;  对注册码做加密运算 设为 g(key)
0050F273  |.  66:3BF8       CMP DI,AX                                ;  比较加密后的数据长度是否都为50H
0050F276  |.  0F85 76010000 JNZ Ip_tools.0050F3F2
0050F27C  |.  A1 C82F5500   MOV EAX,DWORD PTR DS:[552FC8]            ;  f(name)结果送EAX
0050F281  |.  BA FF010000   MOV EDX,1FF
0050F286  |.  E8 C5BEFEFF   CALL Ip_tools.004FB150
0050F28B  |.  8BF8          MOV EDI,EAX
0050F28D  |.  A1 442E5500   MOV EAX,DWORD PTR DS:[552E44]            ;  f(key)结果送EAX
0050F292  |.  BA FF010000   MOV EDX,1FF
0050F297  |.  E8 B4BEFEFF   CALL Ip_tools.004FB150                   ;  比较函数
0050F29C  |.  3BF8          CMP EDI,EAX
0050F29E  |.  0F85 4E010000 JNZ Ip_tools.0050F3F2
0050F2A4  |.  A1 C82F5500   MOV EAX,DWORD PTR DS:[552FC8]            ;  f(name)结果送EAX
0050F2A9  |.  83C0 07       ADD EAX,7
0050F2AC  |.  8B00          MOV EAX,DWORD PTR DS:[EAX]
0050F2AE  |.  8B15 442E5500 MOV EDX,DWORD PTR DS:[552E44]            ;  f(key)结果送EAX
0050F2B4  |.  83C2 07       ADD EDX,7
0050F2B7  |.  3B02          CMP EAX,DWORD PTR DS:[EDX]
0050F2B9  |.  0F85 33010000 JNZ Ip_tools.0050F3F2                    ;  继续比较 若f(name)==g(key) 下面代码将保存注册信息
……

    综上分析,我们修改跳转,先将注册信息保存。作者在这里设置了一个小陷阱,将注册信息保存在注册表的两个位置,程序启动时验证的其实是第二处保存的数据。

Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\Software\KS-Soft\IP-Tools]
"UserName"="rE3YHz^g?"
"UserSNum"="=E8x?9"

[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Devices\00102]
"DATA5"="NCiUsDyF[XPFYNGX]H"
"DATA6"="2C5U9D7F7X5F8N"

    我们猜测程序启动时还会调用相同的算法CALL来对KEY进行验证。我们查看一下对KEY做计算的函数:CALL 004FB208,发现有两处调用:局部调用来自 0050F26E, 00547F99 我们来到地址00547F99处,在上方的地址处下断即可。当然我们也可以查看用户名是否属于黑名单的CALL的调用来定位启动时的验证地址,这种快速定位的小技巧将省去我们下API函数断点的麻烦。



00547F51  |.  E8 BE13F9FF   CALL Ip_tools.004D9314                   ;  检测用户名是否在黑名单
00547F56  |.  84C0          TEST AL,AL
00547F58  |.  74 34         JE SHORT Ip_tools.00547F8E
00547F5A  |.  68 84835400   PUSH Ip_tools.00548384                   ;  Sorry, your registration name (
00547F5F  |.  FF75 EC       PUSH DWORD PTR SS:[EBP-14]
00547F62  |.  68 AC835400   PUSH Ip_tools.005483AC                   ;  ) is found on the "Black List".\r\n\r\n
00547F67  |.  68 D8835400   PUSH Ip_tools.005483D8                   ;  If you have any questions, please, contact KS-Soft: line1@ks-soft.net; line2@ks-soft.net
00547F6C  |.  8D45 D4       LEA EAX,DWORD PTR SS:[EBP-2C]
00547F6F  |.  BA 04000000   MOV EDX,4
00547F74  |.  E8 2BC3EBFF   CALL Ip_tools.004042A4
00547F79  |.  8B45 D4       MOV EAX,DWORD PTR SS:[EBP-2C]
00547F7C  |.  E8 236AF1FF   CALL Ip_tools.0045E9A4
00547F81  |.  A1 202E5500   MOV EAX,DWORD PTR DS:[552E20]
00547F86  |.  C600 01       MOV BYTE PTR DS:[EAX],1
00547F89  |.  E9 89000000   JMP Ip_tools.00548017
00547F8E      8B45 EC       MOV EAX,DWORD PTR SS:[EBP-14]            ;  用户名送EAX
00547F91  |.  E8 D631FBFF   CALL Ip_tools.004FB16C                   ;  f(name)
00547F96  |.  8B45 E8       MOV EAX,DWORD PTR SS:[EBP-18]            ;  注册码送EAX
00547F99  |.  E8 6A32FBFF   CALL Ip_tools.004FB208                   ;  g(key)
00547F9E  |.  A1 C82F5500   MOV EAX,DWORD PTR DS:[552FC8]
00547FA3  |.  BA FF010000   MOV EDX,1FF
00547FA8      E8 A331FBFF   CALL Ip_tools.004FB150
00547FAD  |.  8BF0          MOV ESI,EAX
00547FAF  |.  A1 442E5500   MOV EAX,DWORD PTR DS:[552E44]
00547FB4  |.  BA FF010000   MOV EDX,1FF
00547FB9  |.  E8 9231FBFF   CALL Ip_tools.004FB150                   ;  比较CALL
00547FBE  |.  3BF0          CMP ESI,EAX
00547FC0  |.  75 33         JNZ SHORT Ip_tools.00547FF5              ;  第一处比较
00547FC2  |.  A1 C82F5500   MOV EAX,DWORD PTR DS:[552FC8]
00547FC7  |.  83C0 07       ADD EAX,7
00547FCA  |.  8B00          MOV EAX,DWORD PTR DS:[EAX]
00547FCC  |.  8B15 442E5500 MOV EDX,DWORD PTR DS:[552E44]            ;  Ip_tools.00555BF8
00547FD2  |.  83C2 07       ADD EDX,7
00547FD5  |.  3B02          CMP EAX,DWORD PTR DS:[EDX]
00547FD7  |.  75 1C         JNZ SHORT Ip_tools.00547FF5              ;  再次比较
00547FD9  |.  A1 F8315500   MOV EAX,DWORD PTR DS:[5531F8]

分析出程序的验证流程,我们来考虑下如何爆破:

00547F9E  |.  A1 C82F5500   MOV EAX,DWORD PTR DS:[552FC8]            ;  [552FC8]中保存的地址送EAX
00547FA3  |.  BA FF010000   MOV EDX,1FF
00547FA8      E8 A331FBFF   CALL Ip_tools.004FB150
00547FAD  |.  8BF0          MOV ESI,EAX
00547FAF  |.  A1 442E5500   MOV EAX,DWORD PTR DS:[552E44]            ;  [552E44]中保存的地址送EAX

既然是对加密后的两组数据进行比较,我们何不使其比较同一字符串,做如下修改:
00547FAF  |.  A1 442E5500   MOV EAX,DWORD PTR DS:[552E44]            ;   MOV EAX,DWORD PTR DS:[552FC8]

比较同一字符串,结果肯定是相同的 ^_^ 第二处比较也做相同的修改

思考:程序启动时为何也调用检测用户名是在黑名单呢?对,若不检查这里,我们只需将被黑名单中用户的注册表信息导入即可实现注册。

    保存程序后运行,已显示为注册版,但程序的一些功能却出现了问题,比如我们选择Ping Scanner的功能时,出现以下提示,而运行原程序却没有问题。



    我们来分析一下原因:程序一直都在OD中,所以一定不是自身的效检问题,我们只对程序启动时验证注册码的真假做了修改,那么问题一定出在了这里。莫非程序有对注册信息做了验证?带着这种猜测,我们OD再次载入,并在[552FC8]该地址下硬件访问断点。程序过了前两道验证后,后然再次中断:

00535505   .  8B1D C82F5500 MOV EBX,DWORD PTR DS:[552FC8]            ;  Ip_tools.005559F8
0053550B   .  8B35 442E5500 MOV ESI,DWORD PTR DS:[552E44]            ;  Ip_tools.00555BF8
00535511   .  33C0          XOR EAX,EAX

    老方法,我们还是将MOV ESI,DWORD PTR DS:[552E44]修改为[552FC8],让程序去比较同一字符串好了。

    由于程序比较非明文,处于好奇,我们想对程序对加密后数据的比较探个究竟,在地址 00547F9E (次时程序已经执行完f(name)函数) 下断点,查看[00552FC8]地址所保存的数据。

DS:[00552FC8]=005559F8
DS:[00552E44]=00555BF8



005559F8  56 D6 59 09 75 F9 24 05 FA AD 10 C8 2C 71 11 82  V諽.u???q
00555A08  8B F7 19 D6 C7 77 83 8E 9A E5 7B 88 FC E5 3C C1  嬿智w儙氬{堻?
00555A18  7F 33 38 00 A2 58 F8 F5 94 68 EB 52 1E 06 CA 42  38.??攈隦蔅
00555A28  87 4B EF 3E 40 C1 40 69 FD EA E7 46 E4 20 43 3A  嘖?@罖i?鏔?C:
00555A38  D2 BB 0E 48 12 52 EE 94 05 CD 58 42 12 70 97 6E  一HR顢蚗Bp梟

00555BF8  63 E6 08 EE 40 98 75 C3 76 9F 72 FE E2 EE 48 12  c?頏榰胿焤?頗
00555C08  30 06 C7 3A C7 9A 92 08 A0 33 C7 6B B2 95 30 AA  0?菤??莐矔0
00555C18  EC 3C 53 17 EB A2 38 53 B8 D7 E1 E1 0C C0 8D FB  ?S擘8S缸後.缻
00555C28  7E 0E CE FF 47 CA AD 9A 66 D4 43 D1 B2 75 18 24  ~?G虱歠訡巡u$
00555C38  2E 97 12 2C E5 8B 68 72 90 28 C8 B8 E4 2F 90 23  .?,鍕hr?雀??

    正好是50H个字节的比较,既然我们得知程序是比较NAME和KEY经过计算后的数据,我们何不写一段代码将f(name)的结果COPY到g(key)中呢 o(∩_∩)o... 有想法我们就要付诸实践,我们开工:

00547FB9  |.  E8 9231FBFF   CALL Ip_tools.004FB150                   ;  将这里修改为 CALL 005498AB

Patch代码如下:

005498AB  /$  56                   PUSH ESI
005498AC  |.  57                   PUSH EDI
005498AD  |.  51                   PUSH ECX
005498AE  |.  8B35 C82F5500        MOV ESI,DWORD PTR DS:[552FC8]                   ;  源地址送ESI
005498B4  |.  8B3D 442E5500        MOV EDI,DWORD PTR DS:[552E44]                   ;  目标地址送EDI
005498BA  |.  B9 50000000          MOV ECX,50                                      ;  长度为50H
005498BF  |.  FC                   CLD
005498C0  |.  F3:A4                REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]
005498C2  |.  59                   POP ECX
005498C3  |.  5F                   POP EDI
005498C4  |.  5E                   POP ESI
005498C5  |.  E8 8618FBFF          CALL Ip_tools.004FB150
005498CA  \.  C3                   RETN

    我们写这样一个功能函数来实现f(name)的结果对g(key)结果的替换,这样程序再多几道验证也就不怕了。我们保存文件后发现程序启动时出现提示:



我们F8单步几下就可以找到程序的效检地址:

005490C3   .  E8 0805F9FF   CALL Ip_tools.004D95D0                   ;  程序的自效检
005490C8   .  8B15 842D5500 MOV EDX,DWORD PTR DS:[552D84]            ;  Ip_tools.00555810
005490CE   .  3B82 B4000000 CMP EAX,DWORD PTR DS:[EDX+B4]            ;  自效检的比较
005490D4      74 0F         JE SHORT Ip_tools.005490E5               ;  不等则提示程序出错
005490D6   .  B8 CC965400   MOV EAX,Ip_tools.005496CC                ;  Program was corrupted !
005490DB   .  E8 C458F1FF   CALL Ip_tools.0045E9A4
005490E0   .  E9 2E050000   JMP Ip_tools.00549613
005490E5   >  68 8C965400   PUSH Ip_tools.0054968C                   ;  [

我们将JE 修改为 JMP 后,运行程序发现部分功能仍旧无法使用。:-) 这下就很好分析了,问题肯定出在了自效检上了。



    原程序的自效检值为:77B8FADC,而修改后的程序的效检变为了:9E62EC0F,如果程序在执行中又对效检值做了验证,就会出问题。呵呵,这个提示程序出错的NAG,看来作者是聪明反被聪明误了。我们跟进跳转上方的CALL 004D95D0,跟踪一下是哪句指令对EAX进行了赋值。

004D9737  |.  E8 50CEF2FF   CALL Ip_tools.0040658C                   ; 我们在这里做手脚
004D973C  |.  8B45 FC       MOV EAX,DWORD PTR SS:[EBP-4]             ; 在这里对EAX赋予了程序的效检值
004D973F  |.  A3 94FF5400   MOV DWORD PTR DS:[54FF94],EAX
004D9744  |>  33C0          XOR EAX,EAX
004D9746  |.  5A            POP EDX
004D9747  |.  59            POP ECX
004D9748  |.  59            POP ECX
004D9749  |.  64:8910       MOV DWORD PTR FS:[EAX],EDX
004D974C  |.  68 64974D00   PUSH Ip_tools.004D9764
004D9751  |>  8D85 A4BEFFFF LEA EAX,DWORD PTR SS:[EBP+FFFFBEA4]
004D9757  |.  E8 08A8F2FF   CALL Ip_tools.00403F64
004D975C  \.  C3            RETN

为了更好的迷惑大家,使其不容易发现我们的修改痕迹,这里我们不使用JMP指令来Patch代码,而修改上方的CALL指令。

004D9737  |.  E8 50CEF2FF   CALL Ip_tools.0040658C                      ; 修改为 CALL 005498CC

Patch代码:

005498CC  /$  E8 BBCCEBFF          CALL Ip_tools.0040658C                ; 还原覆盖的代码
005498D1  |.  C745 FC DCFAB877     MOV DWORD PTR SS:[EBP-4],77B8FADC     ;自身的效检值
005498D8  \.  C3                   RETN

    再次保存程序,:-) 这下就OK了。在爆破上修改跳转是下策,更优的方法就是在比较前使其数据相等,当然,为追求快速,我们更常用的还是修改跳转。

    由于程序的对name和key计算后的结果地址放在两个指针变量中,我们通过查看程序的区段,发现指针变量[00552FC8]和[00552E44]位于数据段,所以我们可以得知这两个变量为全局变量(全局变量保存在数据段中)。如图:



    我们OD载入程序后,先不运行,输入 d 00552FC8 发现[00552FC8]中已保存了数据,通过几次的调试我们发现该地址为固定值:



DS:[00552FC8]=005559F8
DS:[00552E44]=00555BF8

    通过对PE各区段地址的了解,我们得知 地址005559F8 和 地址00555BF8 位于数据段下方区段名为BBS的的区段,在调试中我们可以发现该区段保存程序执行时的一些数据,所以我们推测该区段为附加的数据段。由于[00552FC8]和[00552E44]为定值,那我们可直接将这两个指针变量保存相同的地址,即将[00552E44]中的地址00555BF8 修改为地址005559F8 ,为避免程序的自效检,我们使用Loader来实现,这样只需要修改一个字节即可实现程序的爆破,若注册表信息也保存在Loader中,便可无需输入注册信息即可实现程序的注册。

    我们调试一款程序,不要刻意去追求结果,而要通过发现的一个个的线索,来洞察程序的加密体系。当我们掌握了程序的加密体系,破解自然水到渠成。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?加入我们

x
PYG19周年生日快乐!
  • TA的每日心情
    无聊
    2020-4-10 17:02
  • 签到天数: 5 天

    [LV.2]偶尔看看I

    发表于 2008-6-14 18:39:32 | 显示全部楼层
    学习爆破,我说不会爆破,你肯定不信!!!!!!!!
    PYG19周年生日快乐!
  • TA的每日心情
    开心
    2016-4-25 19:39
  • 签到天数: 3 天

    [LV.2]偶尔看看I

    发表于 2008-6-14 20:36:14 | 显示全部楼层
    程序启动时验证的其实是验证的是第二处保存的数据。
    感觉怎么有些拗口!


    程序启动时验证的其实是第二处保存的数据。
    是否可以!
    个人见解!
    PYG19周年生日快乐!
  • TA的每日心情
    开心
    2019-3-15 21:05
  • 签到天数: 5 天

    [LV.2]偶尔看看I

    发表于 2008-6-14 22:15:05 | 显示全部楼层
    :loveliness: 学习下,下个练习:loveliness:
    PYG19周年生日快乐!

    该用户从未签到

     楼主| 发表于 2008-6-14 22:21:09 | 显示全部楼层
    原帖由 lmg7005 于 2008-6-14 20:36 发表
    程序启动时验证的其实是验证的是第二处保存的数据。
    感觉怎么有些拗口!


    程序启动时验证的其实是第二处保存的数据。
    是否可以!
    个人见解!



    感谢提醒 已修改 :loveliness:  这些程序都是第一课教学的练习程序 如果我们一开始就这样来学习破解 相信提高的速度会很快

    这样Patch代码的方式我也是最近才玩的 试了一下 确实很爽 可以对付大多数的非明码比较的软件 爆破后如同正版一样坚挺
    PYG19周年生日快乐!
  • TA的每日心情
    郁闷
    2019-7-7 00:14
  • 签到天数: 3 天

    [LV.2]偶尔看看I

    发表于 2008-6-15 09:16:39 | 显示全部楼层
    学习一下,
    PYG19周年生日快乐!

    该用户从未签到

     楼主| 发表于 2008-6-15 10:35:04 | 显示全部楼层
    原帖由 何求 于 2008-6-15 09:16 发表
    学习一下,



    不要灌水
    PYG19周年生日快乐!
    您需要登录后才可以回帖 登录 | 加入我们

    本版积分规则

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