Navicat Premium 16.1.9激活([MacOS逆向]激活成功教程Navicat Premium 16.1.7: 基于lldb动态调试配合静态注入+FridaHook)

Navicat Premium 16.1.9激活([MacOS逆向]激活成功教程Navicat Premium 16.1.7: 基于lldb动态调试配合静态注入+FridaHook)


Navicat Premium 16.1.9激活([MacOS逆向]激活成功教程Navicat Premium 16.1.7: 基于lldb动态调试配合静态注入+FridaHook)

下载地址是MacAppStore应用商店。



Navicat Premium 16.1.9激活([MacOS逆向]激活成功教程Navicat Premium 16.1.7: 基于lldb动态调试配合静态注入+FridaHook)

IDA 7.0
Hopper Disassembler 5.7.7
Xcode
VS Code + Frida


Navicat Premium 16.1.9激活([MacOS逆向]激活成功教程Navicat Premium 16.1.7: 基于lldb动态调试配合静态注入+FridaHook)

首先老样子找到界面上的关键字,在HP里面找到对应的地址。


Navicat Premium 16.1.9激活([MacOS逆向]激活成功教程Navicat Premium 16.1.7: 基于lldb动态调试配合静态注入+FridaHook)

我们看到只有一个地方引用了



Navicat Premium 16.1.9激活([MacOS逆向]激活成功教程Navicat Premium 16.1.7: 基于lldb动态调试配合静态注入+FridaHook)



跟到这里你会发现



Navicat Premium 16.1.9激活([MacOS逆向]激活成功教程Navicat Premium 16.1.7: 基于lldb动态调试配合静态注入+FridaHook)



这个地方引用了这个字符串,那么我们看看上面有没有jmp大跳:

一翻发现有这段代码:



Navicat Premium 16.1.9激活([MacOS逆向]激活成功教程Navicat Premium 16.1.7: 基于lldb动态调试配合静态注入+FridaHook)



首先他获取了IAPHelper这个类拿到了insatnce,然后rax 执行了一个方法


通过这个方法得到了返回值如果是1那就进入开始试用阶段。
我们编写简单的frida试一下:


Navicat Premium 16.1.9激活([MacOS逆向]激活成功教程Navicat Premium 16.1.7: 基于lldb动态调试配合静态注入+FridaHook)

然后用python启动:


js脚本的代码可以参阅我其他的帖子,这里就不重复贴出来了。
启动发现变成了这样:


Navicat Premium 16.1.9激活([MacOS逆向]激活成功教程Navicat Premium 16.1.7: 基于lldb动态调试配合静态注入+FridaHook)

显然光绕过不行,这里是免费试用到期的状态,因为上面那个if完事了有一个else



Navicat Premium 16.1.9激活([MacOS逆向]激活成功教程Navicat Premium 16.1.7: 基于lldb动态调试配合静态注入+FridaHook)



这里就是继续享受强大功能的提示。

注意 我们这个时候其实是frida把App挂在了Hook上了,所以我们需要用lldb来动态调试反汇编:

加载完之后可以看到stop在这里了:


Navicat Premium 16.1.9激活([MacOS逆向]激活成功教程Navicat Premium 16.1.7: 基于lldb动态调试配合静态注入+FridaHook)

为了反汇编代码与IDA/Hopper Disassembler一致,我们需要将其反汇编代码风格改为intel:


Navicat Premium 16.1.9激活([MacOS逆向]激活成功教程Navicat Premium 16.1.7: 基于lldb动态调试配合静态注入+FridaHook)



这样就可以和IDA里的反汇编代码风格一致了。

这里是自动断下的,我们先输入c让他继续运行:



Navicat Premium 16.1.9激活([MacOS逆向]激活成功教程Navicat Premium 16.1.7: 基于lldb动态调试配合静态注入+FridaHook)



那么我们需要下个断点在这个调用函数上.

前面我们说到这里是通过搜索string找到的windowDidLoad函数引用,所以我们就要在这个函数的开头下breakpoint让他Suspend,方便我观察Stack。

/
@Class IAPWindowController /

-(void)windowDidLoad {}

输入:



Navicat Premium 16.1.9激活([MacOS逆向]激活成功教程Navicat Premium 16.1.7: 基于lldb动态调试配合静态注入+FridaHook)



这里地址是



Navicat Premium 16.1.9激活([MacOS逆向]激活成功教程Navicat Premium 16.1.7: 基于lldb动态调试配合静态注入+FridaHook)



这个地方得到的偏移地址.

然后我们输入r重启app



Navicat Premium 16.1.9激活([MacOS逆向]激活成功教程Navicat Premium 16.1.7: 基于lldb动态调试配合静态注入+FridaHook)



直接回车即可.

可以看到函数这个时候被断下了:



Navicat Premium 16.1.9激活([MacOS逆向]激活成功教程Navicat Premium 16.1.7: 基于lldb动态调试配合静态注入+FridaHook)



现在我们要查这个函数从哪里调用的堆栈,输入简写bt看堆栈:


可以看到调用方来自frame #3,我们输入up来跳到调用方:


可以看到我们在#1,我们在跳两次到#3:


这里输入up 3就是跳3次堆栈,我这里还down 1是因为我跳到#4了,所以往回跳1个堆栈.
我们看下这个代码:


我们看->的指向位置,回到Hopper我们看下对应位置到底写了什么.


为了方便操作堆栈,我们输入gui切换到GUI模式.


Navicat Premium 16.1.9激活([MacOS逆向]激活成功教程Navicat Premium 16.1.7: 基于lldb动态调试配合静态注入+FridaHook)

现在他默认在堆栈顶部,我们要切换到右侧”___lldb
unnamed“开头的堆栈查看源代码:

按下TAB,我们会按顺序切换到右侧:



Navicat Premium 16.1.9激活([MacOS逆向]激活成功教程Navicat Premium 16.1.7: 基于lldb动态调试配合静态注入+FridaHook)



现在高亮#4就代表我们在堆栈#4,左侧的代码会对应显示出来.我们记下这个地址到Hopper里面查一下:

0x0000000100ab284a

按下G键开始跳转:



Navicat Premium 16.1.9激活([MacOS逆向]激活成功教程Navicat Premium 16.1.7: 基于lldb动态调试配合静态注入+FridaHook)


很明显 我们看到上面调用了一个函数:isProductSubscriptionInGracePeriod,以楼主没几两墨水的肚子勉强猜出来这个函数是否产品订阅在宽容周期内,也就是已过期但是你还可以用.

由于Hopper对原始C函数反编译能力较弱,我们用IDA看下比较精确的伪代码:


可以看到isProductSubscriptionInGracePeriod如果返回1那么就会提示你product expired,这显然不是我们需要的结果。那如果不在宽容周期内呢?
我们直接翻到最底下赫然发现函数isProductSubscriptionStillValid:


如果产品一直验证通过,那么直接返回v45,也就是说v45必须等于1否则terminate.
我们Hook一下看看.


Navicat Premium 16.1.9激活([MacOS逆向]激活成功教程Navicat Premium 16.1.7: 基于lldb动态调试配合静态注入+FridaHook)



Navicat Premium 16.1.9激活([MacOS逆向]激活成功教程Navicat Premium 16.1.7: 基于lldb动态调试配合静态注入+FridaHook)



可以看到确实调用了这个函数,crack OK!

现在可以直接体验正版。但是我们显然不能每次都要开frida,有没有办法静态注入进app呢?

我们发现isProductSubscriptionStillValid是一个ObjectC函数,那么ObjectC有一个method Swizzing技术,也就是替换IMP函数具体实现的地址来用我们的代码替换原始函数实现代码。我们只需要Hook掉isProductSubscriptionStillValid这个函数返回值即可:


这里switchMethod和getMethod/getMethodStr函数我也贴一下避免有些朋友看不懂.
而实际上我们注入只需要一行代码即可,由于这个插件我写了二十多个app的激活hook代码,所以可以看到上面有很多的app版本和bundleid检查。


至于如何新建Xcode项目,可以看我之前的帖子,也有详细说明,这里再写就万字长文了,就不贴了。
command b编译 注入,我们挑一个好欺负的framework来注入:


Navicat Premium 16.1.9激活([MacOS逆向]激活成功教程Navicat Premium 16.1.7: 基于lldb动态调试配合静态注入+FridaHook)

选它没别的原因 ,就是这个文件只有800KB方便复制,你也不想选个10MB的大文件Copy来Copy去吧?

注入工具和编译后的dylib文件可以查阅我的github,这里就不写了。



Navicat Premium 16.1.9激活([MacOS逆向]激活成功教程Navicat Premium 16.1.7: 基于lldb动态调试配合静态注入+FridaHook)



我们直接打开App看看.



Navicat Premium 16.1.9激活([MacOS逆向]激活成功教程Navicat Premium 16.1.7: 基于lldb动态调试配合静态注入+FridaHook)



小小的脑袋大大的疑惑,大无语事件发生,集美们!那么这种情况我们不慌,可以看到app实际上是打开了的。这种错误其实是exit(173),也就是告诉macOS用户授权票不匹配或者不存在,也就是说他检测到了app不是你购买过的,没有有效的订阅授权文件。

那么我们怎么去调试他?

很简单,直接lldb hook exit函数即可。因为我阿妈每天早上六点起来给我充电子烟,所以exit(173)是固定写法,不这么写是不会弹出这个提示的。


Navicat Premium 16.1.9激活([MacOS逆向]激活成功教程Navicat Premium 16.1.7: 基于lldb动态调试配合静态注入+FridaHook)

我们来看下,直接通过lldb可以看出他exited with status = 173 (0x000000ad) ,说明我所言非虚。


我们输入br s -n ‘_exit’来设置当App退出时的断点,这样app退出时我们可以让lldb接收到堆栈信息。
我们看上面的堆栈,可以看到libsystem_c.dylib和libsystem_kernel.dylib都不谈了,妥妥的系统库。

但是下面这个内存地址不是以0x00007ff8随机化地址开头的函数就有意思了,0x0000000108b70734显然是在app的内存空间里,说明了一个问题,这个库是App的。那么我们就需要知道这个库到底搞了什么鬼让他exit。我们记下偏移地址0x0000000108b70734去查一下。

在查之前我们需要一个概念,Apple有一个技术叫ASLR,随机化虚拟内存启动地址,也就是说,我们要找到偏移需要通过ASLR偏移计算出原始二进制文件的偏移。我们先看一下内存地址模块导出的基本地址:
输入image list -o -f回车。


我们看下这里起始地址为:
[  3] 0x0000000107a02000 /Applications/Navicat Premium.app/Contents/Frameworks/libcc-premium.dylib

计算公式为 0x0000000107a02000 + 文件二进制偏移 = 内存地址偏移0x0000000108b70734
所以0xb38 – 0x0000000107a02000 = 0x116E734。


Navicat Premium 16.1.9激活([MacOS逆向]激活成功教程Navicat Premium 16.1.7: 基于lldb动态调试配合静态注入+FridaHook)

确实存在,我们用hopper看下。

直接G跳转到0x116E734看一下:



Navicat Premium 16.1.9激活([MacOS逆向]激活成功教程Navicat Premium 16.1.7: 基于lldb动态调试配合静态注入+FridaHook)

其实我们直接lldb里面可以看到


mov        edi, 0xad 就是173,call exit就不谈了,懂得都懂。
IDA看下伪代码:


Navicat Premium 16.1.9激活([MacOS逆向]激活成功教程Navicat Premium 16.1.7: 基于lldb动态调试配合静态注入+FridaHook)

我们发现这个函数中执行了exit(173)的操作。



Navicat Premium 16.1.9激活([MacOS逆向]激活成功教程Navicat Premium 16.1.7: 基于lldb动态调试配合静态注入+FridaHook)



稍有不慎就是exit(173),好狠的手段!欺我风灵月影宗无人!今日我倒要看看,就算我实力不足全盛时期十之二三,你Navicat代码混淆就算没有符号表又能奈我何?区区蝼蚁罢了,本座反手堆栈跟踪覆灭之!

话到一半,却又眉头一紧:”这厮竟然无法使用xref大法查找溯源?事情有些棘手,我却要如何?不如查看堆栈#3看调用方.”

当即长啸一声,回到终端:


Navicat Premium 16.1.9激活([MacOS逆向]激活成功教程Navicat Premium 16.1.7: 基于lldb动态调试配合静态注入+FridaHook)

按下Tab键切换到Threads,找到#3。当即便复制0x0000000b38 – 0x0000000107a02000 = 0xC74B38,拿到地址后质问IDA Pro,冷笑道:“你可知此地址为何处?我已知晓其中关键,再敢搪塞本座,必要你小命!”

那IDA惶恐道:


Navicat Premium 16.1.9激活([MacOS逆向]激活成功教程Navicat Premium 16.1.7: 基于lldb动态调试配合静态注入+FridaHook)


原来此乃Navicat不知名内存偏移调用方,以指针方式访问内存地址,故不可得到其实际引用。

既然+[AppStoreReceiptValidation validate]是exit(173)祸首,那么此人也不必留着,该永绝后患。适时眼中寒芒一闪,表面却淡淡一笑“这次就饶你一条狗命!滚!”

那Navicat正兀自暗喜自以为暗桩未被神识检测到,却不料被反手Hook掉了要害罩门:


我冷笑一声按下F5启动frida


Navicat Premium 16.1.9激活([MacOS逆向]激活成功教程Navicat Premium 16.1.7: 基于lldb动态调试配合静态注入+FridaHook)

霎时间之间Navicat惨叫一声,当场殒命。

“灭你如灭蝼蚁!”

最后将
//switchMethod(getMethodStrByCls(@”AppStoreReceiptValidation”,@”validate”), getMethod([InlineInjectPlugin class], @selector(validate)));取消注释,替换原始函数,编译后完美启动Navicat。

阿妈不准我说藏话,但是如果你需要鼓励,那么–我测你码。

由于使用的方法为Method Navicat Premium 16.1.9激活 Swizzing,并没有用偏移地址做hook,所以只要Navicat不改函数名称不删除符号表,这个hook代码将一直通杀后续版本。
二进制参考github:
https://github.com/QiuChenly/MyMacsAppCrack

2024最新激活全家桶教程,稳定运行到2099年,请移步至置顶文章:https://sigusoft.com/99576.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。 文章由激活谷谷主-小谷整理,转载请注明出处:https://sigusoft.com/195083.html

(0)
上一篇 2024年 8月 18日 下午2:10
下一篇 2024年 8月 18日

相关推荐

关注微信