| 
  1、实验环境
 操作系统: mac os x 10.12
 调试工具:hopper disassemble v4
 程序:010 editor for mac
 官网地址:http://www.sweetscape.com/010editor/
 
 2、开始分析
 2.1、寻找线索
 看一下正常执行时的整个流程,并从中获得线索。
 在关于里面找到注册然后弹出注册的信息框,输入用户名和密码,点击 check license,然后提示 “Invalid name or password…….”,如图-1。
 现在找到了第一条线索,记为线索1。线索1:stringInvalidNameOrPassword字符串“Invalid name or password…”。
 图-1
 
 
 2.2、分析线索1
 打开 hopper disassembler v4,将010editor 拖拽到hopperdisassembler上,如下图:
 
   通过hopper中的字符串查找定位到stringInvalidNameOrPassword出现的位置,如图-2。
 
   图-2
 再查看stringInvalidNameOrPassword在哪些地方被引用了。
 选中stringInvalidNameOrPassword所在地址,按一下“X”键,显示出该地址的所有引用,如图-3。
 
   图-3
 
 双击图-3中的地址,即可显示出该调用地址处的反汇编代码,如图-4。
 接下来就要分析 sub_1002e5f10 这个函数。到这里,我门又有了新的疑点:
 1、        stringInalidNameOrPassword这条路是从哪里走过来的?
 2、        该函数中有没有正确的路?如果有,哪么正确的路在哪里?
 3、        正确的路与stringInalidNameOrPassword的路是在哪里走岔的?
 上面的三个疑点都在 sub_1002e5f10 函数中找。
 
   图-4
 
 光标放在1002e69e4 处,然后点击工具栏中的CFG module 显示函数流程图如图-5。
 
   图-5
 
 总的来说loc_1002e6900 是一条错误的路(trial+invalidNameOrPassword)。
 再找loc_1002e6900 的来源,如图-6。
 
   图-6
 
 再向上找,找 loc_1002e65b8 的来源,如图-7。可以看到是在loc_1002e6363处和正常的授权路分岔了。
 关键是 ebx的值,如果ebx == 0xdb 该函数就走授权的路。
 现在用伪代码模式查看这块代码,如图-8。这时,我们定位到了三个重要函数 sub_1000c9230 sub_1000c90e0 sub_1002e9e40。
 其中sub_1002e9e40函数是用来联网校验授权信息的,这里就不进入该函数分析来。
 ebx 的值是 sub_1000c9230 的返回值,所以如果能控制sub_1000c90e0 的返回值就能控制该函数走授权的路了。
 
   图-7
 
   图-8
 
 进入sub_1000c90e0 函数进行分析,如图-9。sub_1000c90e0 的返回值有 0x113, 0xdb, 0x20c, 0xed, 0x71, 0x177, 0xf9,0x2f共8种。
 其中0xdb是走的授权路线。在该函数中调用了sub_1000c9230 函数,如果能控制 sub_1000c9230 的返回值为0x2d 就能让sub_1000c90e0返回 0xdb。
 其实为了保险起见可以将 sub_1000c90e0 函数中的第三行 rax = 0x113改成rax = 0xdb。这样就能保证 sub_1000c90e0 返回的是 0xdb。
 
   图-9
 
 函数分析sub_1000c9230。
 先来查看该函数的所以引用。
 00000001000c9106         call       sub_1000c9230 ;在sub_1000c90e0 函数中。
 00000001002e62f2         call       sub_1000c9230 ;在sub_1002e5f10 函数中。
 没有授权时,在sub_1002e5f10返回的是0xe7,在 sub_1000c90e0中返回的不是 0x2d。
 函数sub_1000c9230的返回值有rax= 0x93, 0xe7, 0x2d,0x4e四种,每个返回值都有自己的特殊含义。
 其中0x2d就是走授权道路的返回值;0x93 是tial 或者 Invalid name or password。
 [size=14.6667px]
 修改 sub_1000c9230函数使其只返回0x2d,我的修改方式是将[size=14.666666984558105px]
 
[Asm] 纯文本查看 复制代码 
    
        
            | 1 2 3 | 
            00000001000c9268         mov       r12d, 0x93 00000001000c926e         cmp       dword [rax+4], 0x0 00000001000c9272         je          loc_1000c9552 |  修改成
 
[Asm] 纯文本查看 复制代码 
    
        
            | 1 2 3 4 | 
            00000001000c9268         mov       r12d, 0x2d 00000001000c926e         cmp       dword [rax+4], 0x0 00000001000c9272         jmp       loc_1000c9552 00000001000c9277         nop |  参照图-7,将sub_1002e5f10 函数中的
 
[Asm] 纯文本查看 复制代码 
    
        
            | 1 | 
            00000001002e631c         je        loc_1002e6363 |  修改成
 
[Asm] 纯文本查看 复制代码 
    
        
            | 1 | 
            00000001002e631c         jne        loc_1002e6363;目的是绕过sub_1002e9e40网络验证。 |  通过线索1,我们找到来正常授权的路,线索1的路也走完了。保存修改。
 运行修改后的文件时,提示图-10
 
   图-10
 
 
 2.3寻找新线索[size=14.6667px]
 其实在提示图-10窗口之前有个窗口一闪而退,那个窗口提示的是什么哪?
 通过录像的方式录下来然后慢放暂停。其实那个提示框是图-11。
 现在我们又找到了新的线索(2条)。
 [size=14.6667px]线索2: stringLicensedTo = “Licensed to:”
 [size=14.6667px]线索3: stringInvalid license=“Invalid license”。
 
 
 2.3.1分析线索2
 线索2:stringLicensedTo = “Licensed to:”通过字符串查找并锁定到引用函数,分析函数流程如图-12。修改成如图-13。
 
   图-11
 
   图-12
 
   图-13
 [size=14.6667px]
 
 2.3.2分析线索3[size=14.6667px]
 线索3: stringInvalid license=“Invalid license”。通过字符串查找并锁定到引用函数为sub_1002e7620。分析函数 sub_1002e7620 流程如图-14
 
   图-14
 [size=14.6667px]
 简化一下如下:
 
[C++] 纯文本查看 复制代码 
    
        
            | 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 | 
            
 if (eax > 0xda)//loc_1002e782a {          if       (eax > 0x20b)//1002e78b2          {                          if       ( eax != 0x20c)//1002e7b0f                    {                             goto 1002e8413;                    }                    else                    {                             Upgrade Required                    }          }          else          {                    if( eax > 0x176)                    {                             goto 1002e7b73;//Evaluation                    }                    else                    {                             if(eax > 0x112)                             {                                      if(eax != 0x113)//1002e7da4                                                invalid license                                      else                                                days left                             }                                   else                             {                                      if(eax == 0xdb)                                                goto 1002eb295;//OK registered                                      else                                                envaluied version                             }                                  }            } } else if(eax != 0x2f) {          goto 1002e8413;//Evaluation Version } else {          Bad Clock Dat; } |  可以修改成
 
[C++] 纯文本查看 复制代码 
    
        
            | 1 2 3 4 5 6 7 | 
            if (eax > 0xda){ goto 1002eb295;//OK registered } else { goto 1002eb295;//OK registered } |  
 
 即
 
[Asm] 纯文本查看 复制代码 
    
        
            | 1 2 3 | 
            00000001002e782a         mov       eax, dword [r15+0x18c]                      ; CODE XREF=sub_1002e7620+487, sub_1002e7620+501 00000001002e7831         cmp       eax, 0xda 00000001002e7836         ja        loc_1002e78b2 |  修改成
 
[Asm] 纯文本查看 复制代码 
    
        
            | 1 2 3 4 5 | 
            loc_1002e782a: 00000001002e782a         mov       eax, dword [r15+0x18c]                      ; CODE XREF=sub_1002e7620+487, sub_1002e7620+501 00000001002e7831         jmp       loc_1002e8295 00000001002e7836         nop 00000001002e7837         nop |  
 
 |