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
|
|