Sbulime_text3

Sublime Text3

入门级爆破

下载Sublime Text3 x64(3211),需要的工具是看雪论坛的x64dbg

讨厌的地方有两个:首页 、弹窗。

首页

弹窗

针对首页上的字样,在符号中搜索 setwindowtext

去首页一

跳转到函数位置下断点,重新载入程序,在栈区跳转到返回地址。

定位setwindowtext函数

现在跳转到了调用 setwindowtext 函数的代码地址,向上寻找函数块起始位置。

调用函数

函数块起始处

下断重载,逐条运行,发现关键点:

关键点

这里应该知道,是第三个条件跳转语句是什么关键跳转了,根据跳转目的地判断,第三个跳转是正常显示的点。 二进制修改如下:

000000013FCB3CC7   | 75 1E                 | jne sublime_text.13FCB3CE7         |
修改为:
000000013FCB3CC7   | EB 77                 | jmp sublime_text.13FCB3D40         |

保存补丁

去掉首页后,需要该弹窗,弹窗内容可以使用字符搜索来进行。

搜索字符串

搜索hello

关键字符串

下断点,触发并执行过来

关键位置

触发了断点,说明位置是正确的,观察上下文

000000013F38098D   | 48:83EC 28            | sub rsp,28                         |
000000013F380991   | 48:8D15 B6D95C00      | lea rdx,qword ptr ds:[13F94E34E]   | 000000013F94E34E:"Hello! Thanks for trying out Sublime Text.\n\nThis is an unregistered evaluation version, and although the trial is untimed, a license must be purchased for continued use.\n\nWould you like to purchase a license now?"
000000013F380998   | 4C:8D05 B1DC5B00      | lea r8,qword ptr ds:[13F93E650]    | 000000013F93E650:"This is an unregistered copy"
000000013F38099F   | 4C:8D0D 91675C00      | lea r9,qword ptr ds:[13F947137]    | 000000013F947137:"Purchase"
000000013F3809A6   | 31C9                  | xor ecx,ecx                        |
000000013F3809A8   | E8 9F9E1000           | call sublime_text_s.13F48A84C      |
000000013F3809AD   | 84C0                  | test al,al                         |
000000013F3809AF   | 74 10                 | je sublime_text_s.13F3809C1        |
000000013F3809B1   | 48:8D0D 62D95B00      | lea rcx,qword ptr ds:[13F93E31A]   | 000000013F93E31A:"https://www.sublimetext.com/buy"
000000013F3809B8   | 48:83C4 28            | add rsp,28                         |
000000013F3809BC   | E9 AD581000           | jmp sublime_text_s.13F48626E       |

发现整段代码都是用来进行弹窗的,那么直接在代码起始地ret,就可以实现最小化修改了4

最小化修改

至此爆破就结束了。

最小化特征码替换

版本:x64“Sublime Text Version 3.2.2 Buile 3211”

特征码是:

66 83 25 F0 CF 6F 00 00

修改为:

C6 05 F1 CF 6F 00 01 90

追码过程记录

如果针对特定功能点进行爆破的话,改动的地方会很多,打补丁的话也不太方便。所以为了实现最小化修改, 进行追码。随便寻找一个关键点进行追码,这里从 title 上的 (unregistered) 入手。

第一步:对 setwindowtextw 下断;

第一步

第二步:重载,找到关键跳转;

第二步

第三步:这里知道 r15寄存器的值是关键值,现在开始向上追码;

第三步

第四步:继续追码 r9

第四步

第五步:发现 r13 与 1 进行了异或运算;

命令 二进制数
A 1010
1 0001
or A,1 1011
B 1011

第五步

第六步:找到关键内存地址;

第六步

第七步:现在知道了整个过程是如何影响最终走向的,接下来梳理一下算法过程:


mov rax,qword ptr ds:[r15+4E8] ;关键内存地址赋值给rax
xor ebx,ebx                    ;将ebx制空
xor ecx,ecx                    ;将ecx制空
cmp byte ptr ds:[rax],bl       ;将rax地址中的值与0比较
sete cl                        ;rax地址中的值为0,则cl为1,否则cl为0
lea edx,qword ptr ds:[rcx+rcx] ;将rcx+rcx的值赋值给edx
cmp byte ptr ds:[rax+1],bl     ;对比[rax+1]的值是否为0,用来影响cmove赋值。
lea edi,qword ptr ds:[rcx+rcx+4];将edx+4赋值给edi
cmove edi,edx                  ;此时如果zf为1,则将edx的值赋给edi,否则跳过该条命令。
lea r13d,qword ptr ds:[rdi+8]  ;将rdi+8的值赋值给r13
or r13d,eax                    ;将r13与eax进行异或运算
mov r9d,r13d                   ;将r13的值赋值给r9
mov r15d,r9d                   ;将r9的值赋值给r15
test r15b,2                    ;r15的值是关键
jne sublime_text.13F8A3CE7
test r15b,4
jne sublime_text.13F8A3D30
test r15b,10
je sublime_text.13F8A3D40      ;here

从截取的代码来看,要进行到最后的跳转,需要满足以下条件:

r15 and 0010b = 1
r15 and 0100b = 1
r15 and 10000b = 1

抛开最后 ‘r13’ 与 ’eax’ 进行异或操作,观察 ‘r13’ 的来源值为’ rdi+8’ ,‘rdi’ 等于 ’edx+4’ ,或者 ’edx’ ,’edx’ 则等于 ‘2h’ 或者 ‘0h’ ,简单测试一下 ‘[rax] = 1h’ ,则满足以下所有条件,且在异或操作时,’eax’ 的值被赋值为了 ‘0h’ ,对 ‘r13’ 没有影响。

第八步:给关键地址下硬件写入断点,来定位它最开始被修改的地址;

第八步

第九步:重载、运行;

第九步

第十步:修改汇编代码,并测试是否有效: 先在此处将关键地址修改为1,运行查看情况:

仅修改

按如下方式修改代码:

000000013F701FA8 | 66:8325 F0CF6F00 00     | and word ptr ds:[13FDFEFA0],0      | 将关键地址赋值为1h
修改为:
000000013F701FA8 | C605 F1CF6F00 01        | mov byte ptr ds:[13FDFEFA0],1      | 将关键地址赋值为1h
000000013F701FAF | 90                      | nop                                |

修改代码

最后总结得出最小特征码

66 83 25 F0 CF 6F 00 00

修改为:

C6 05 F1 CF 6F 00 01 90

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

2020年3月28日更新:制作补丁

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

偶然间的到了一个补丁编写软件(dup2),然后就试着用它来制作了一个patch补丁。另外修改一个隐藏的校验。 在以往的经验中,发现关于上显示的 "Unregistered" 上面的判断跳转是根据内存地址来的,搜索字符串 "Unregistered"

字符串搜索

找到上面的判断跳转:

关键点

结果显示如下:

显示结果

在刚才的rsi内存地址处,下一个硬件读取断点,重载程序:

目标

在硬件断点停留的位置,可以看到and运算将目标地址置零了,修改方式就很简单了: 原始代码:

00007FF681F31FA8 | 66:8325 F0CF6F00 00      | and word ptr ds:[7FF68262EFA0],0        | 第一个修改点
00007FF681F31FB0 | 8325 EDCF6F00 00         | and dword ptr ds:[7FF68262EFA4],0       |

修改方案一:

00007FF681F31FA8 | C605 F1CF6F00 01         | mov byte ptr ds:[7FF68262EFA0],1        | 第一个修改点
00007FF681F31FAF | 90                       | nop                                     |
00007FF681F31FB0 | 8325 EDCF6F00 00         | and dword ptr ds:[7FF68262EFA4],0       |

修改方案二:

00007FF681F31FA8 | 66:8325 F0CF6F00 00      | and word ptr ds:[7FF68262EFA0],0        | 第一个修改点
00007FF681F31FB0 | C605 E9CF6F00 01         | mov byte ptr ds:[7FF68262EFA0],1        |

方案一改的多,方案二改的少,因为7FF68262EFA4的值本来就是0,这里的置零是无意义代码,为了修改少我选择的是方案二进行修改。 删除当前硬件断点,在目标地址重新下一个硬件写入断点,运行程序,逐个点击功能点,尝试触发隐藏校验函数。 过了一段时间后,隐藏校验点触发,在尝试了不同的点击顺序后,貌似这是一个基于时间的校验点,

隐藏

00007FF70B29EB28 | C601 01                  | mov byte ptr ds:[rcx],1                 | 隐藏校验
00007FF70B29EB2B | C3                       | ret                                     |

补丁

这样爆破就算结束了。 制作补丁:

将原始文件和破解后的文件进行偏移对比,得出要修改替换的字节,点击保存,在点击方案-创建补丁-就可以生成path文件。 注:在目标文件处加上绝对路径,就可以直接打开目标文件,未加路劲的话,默认为当前patch文件目录,未找到会提示用户自行选取。