通过逆向的方法隐藏Sublime Text标题栏的UNREGISTERED
0. 预备
相关操作仅供学习,请勿用于非法操作,否则后果自负!
a. 硬件:MacBook或者安装macOS的虚拟机;
b. 最少软件:insert_dylib (直接跳转第5步下载编译好的静态库,然后通过第6步的注入进行操作);
c. 全文涉及软件:ida、insert_dylib、Sublime Text、otool、class-dump、svn
d. 版本号Sublime Text 3.2.1 Build 3207
1. 介绍
没有购买license的Sublime Text编辑器,在右上角会显示一个字符串“UNREGISTERED”,刚好最近在macOS复习一些逆向知识,准备练练手隐藏字符串“UNREGISTERED”。
2. 导出头文件
先用class-dump导出头文件:
class-dump -H "/Applications/Sublime Text.app/Contents/MacOS/Sublime Text" -o ~/tmp/SublimeText_header
拖文件夹入Sublime Text,不多的几个文件:
3. 静态分析
没有找到isRegister/isBuy类似的简单方法,说明有比较复杂的防破解算法,应该要花好些功夫才能搞定。因为相应的字符显示在标题栏,先静态分析看看有没有处理标题栏相关的操作。
通过关键字符串“UNREGISTERED”找到处理的逻辑,前置算法确认v19的值,然后新建NSTextField控件v22,一并传入set_title_accessory_style方法,然后通过ns_title_bar_view获取到标题栏控件,再通过-(void)addSubview方法把新建v22做为子控件添加到标题栏上。
如此分析到这里就比较简单了,只需要编写一个tweak,通过类似ns_title_bar_view的算法找到标题栏控件,然后把其中字符值为“UNREGISTERED”的子控件移除即可。
分析ns_title_bar_view可知,标题栏是一个NSTitlebarView控件,它是NSTitlebarContainerView的子控件。
4. 编写tweak
xcode新建masOS平台的framework,为了hook Objective-C方法,我们还需要引入一个框架JRSwizzle,我们项目结构如下:
- (id)ns_title_bar_view:(NSWindow *)win {
id res = nil;
NSView *contenView = [win contentView];
NSArray *views = [[contenView superview] subviews];
Class titleBarClass = NSClassFromString(@"NSTitlebarContainerView");
for (id item in views) {
if ([item isKindOfClass:titleBarClass]) {
res = item;
break;
}
}
if (res) {
NSArray *views = [res subviews];
for (id item in views) {
if ([item isKindOfClass:NSClassFromString(@"NSTitlebarView")]) {
res = item;
break;
}
}
}
return res;
}
找到标题栏的算法如上,由于Sublime Text可以创建多窗口,所以我们不仅仅要实现启动的时候移除相关控件,新建了窗口我们也要对应移除一次,所以需要找一个经常被调用的OC方法,经过试验发现-[PXWindow update]被频繁调用,所以我们在此处进行移除相关控件的操作。
// - PXWindow
- (void)m_st_update {
// NSLog(@"SublimeText m_st_update");
[ ];
[ ];
}
- (void)m_hidden_registerMarkView {
NSDictionary *mark = [[NSUserDefaults standardUserDefaults] objectForKey:@"removedMark"];
if (mark) {
if ([[mark allKeys] containsObject:[self m_set_key]]) {
return;
}
}
NSArray *titleBars = [self ns_title_bar_views];
if (!titleBars) {
return;
}
for (id item in titleBars) {
[ ];
}
}
通过调用自定义的方法 -(void)m_hidden_registerMarkView 来移除对应的控件,由于是多窗口程序,我们自定义方法[self ns_title_bar_views]获取到的标题栏不止一个,然后再一一处理。
5. 构建tweak
没有相关工具链的同学可以准备好insert_dylib之后,下载我编译的hookSublimeText静态库文件(https://github.com/coleflowers/tweaks/releases/download/test/hookSublimeText)参考第6步进行注入操作。
想要自己探索一番的同学,通过以下命令下载我开源在github的源码,或者扫描下方的二维码浏览。
svn co https://github.com/coleflowers/tweaks/trunk/hookSublimeText
下载完的项目,使用xcode编译,然后复制出编译完的hookSublimeText.framework,使用insert_dylib导入Sublime Text的符号表,再次执行就会发现,Sublime Text窗口不再显示"UNREGISTERED"
6.注入
sudo /path/to/insert_dylib --all-yes "/path/to/hookSublimeText.framework/hookSublimeText" "/Applications/Sublime Text.app/Contents/MacOS/SublimeBk" "/Applications/Sublime Text.app/Contents/MacOS/Sublime Text"
其中第一个SublimeBk为备份的Sublime Text原始可执行文件。
检查是否注入:
otool -L /path/to/Sublime\ Text
注入成功,重启检查无误。
之前:
之后: