Hopper Disassembler
(X,G,Esc,Space...,度娘/谷歌,后面简称Hopper
)python
Xcode
(App Store)git
frida
(前置条件配置好 python环境,下载好pip,随后用pip下载,具体度娘/谷歌找攻略便可)github
汇编指令基础掌握
(je,jne,jmp,jle,mov,call,ret,nop,xor,lea,rax,rdi,rsi,rcx....)数据库
lldb指令基础掌握
(bt, image lookup --address ,p, c...)编程
终端操做
(codesign *,frida *)windows
具有必定的编程思想
sass
基础逆向工程思惟基础掌握
(Executable,重签,覆盖entitlements)bash
小目标:学习下一些简单汇编知识以及市面上的一些付费App的付费模块的代码思路而后顺便逆向破解 PDF Expert
app
在保存操做前是没有提示升级到完整版这个弹窗的,因此咱们在Xcode attach成功后能够尝试增长个符号断点windowWillLoad查看调用栈的关系ide
attach
查看对应图层关系查看图层关系 在增长符号断点windowWillLoad
后在修改后的pdf界面触发保存操做出现弹窗发现没有停下断点,说明这条路行不通。
可是咱们也获取到了一个关键信息:最上面的控件名称为 DMTrialController
。
frida
经过已知弹出升级框的类 DMTrialController
,查找出具体调用的方法堆栈在终端上输入 frida-trace -m "-[DMActivationController *]" PDF\ Expert
22103 ms -[DMTrialController trialObject]
23074 ms -[DMTrialController trialObject]
23074 ms -[DMActivationController performActivationStepWithStep:0x66]
23074 ms | -[DMActivationController isRunning]
23074 ms | -[DMActivationController setNextPerformStep:0x66]
23074 ms | -[DMActivationController updateStepControllerForCurrentStep]
23074 ms | | -[DMActivationController nextPerformStep]
23074 ms | | -[DMActivationController confirmedNextPerformStep:0x66] </pre>
复制代码
分析log输出在点击保存时触发的方法为-[DMActivationController performActivationStepWithStep:0x66]
记录下来回到第二步操做的2.4查看付费弹窗堆栈信息。
再次保存操做后触发断点终端查看到嫌疑关键代码以下
frame #1: 0x000000010227846c PDF Expert`___lldb_unnamed_symbol15828$PDF Expert + 380
frame #2: 0x00000001022c5263 PDF Expert`___lldb_unnamed_symbol16722$PDF Expert + 371
frame #3: 0x00000001022a1e37 PDF Expert`___lldb_unnamed_symbol16128$PDF Expert + 39
复制代码
随后 image寻址找到具体App调用时的地址信息
(lldb) image lookup --address 0x0000000103818a7c
Address: DevMateKit[0x0000000000029a7c] (DevMateKit.__TEXT.__text + 165540)
Summary: DevMateKit`-[DMActivationController performActivationStepWithStep:]
(lldb) image lookup --address 0x00000001022c5263
Address: PDF Expert[0x00000001003ff263] (PDF Expert.__TEXT.__text + 4180867)
Summary: PDF Expert`___lldb_unnamed_symbol16722$PDF Expert + 371
(lldb) image lookup --address 0x00000001022a1e37
Address: PDF Expert[0x00000001003dbe37] (PDF Expert.__TEXT.__text + 4036439)
Summary: PDF Expert`___lldb_unnamed_symbol16128$PDF Expert + 39</pre>
复制代码
获得可疑地址
A:0x0000000000029a7c
B:0x00000001003ff263
C:0x00000001003dbe37
Hooper
查看可疑地址A,B,C。Hooper
Hopper
加载完成加载完成后在界面左侧输入刚才Xcode Attach控件名 DMTrialController
分析搜索结果发现并无直接匹配的 DMTrialController
这玩意,猜测这个空间不是直接在主工程实现的,随后看跟 DMTrialController
命名相似的DMTrialWelcomeStepController
看上图能够找到文件路径而且发现关键字DevMateKit
,其实早在Xcode Attach时查看图层就能够发现 这个付费弹窗的命名前缀是DMT
而主工程的命名前缀是PDF_Expert
,很大几率付费弹窗是用的第三方库.
DevmateKit
有哪些功能这个就不在这介绍了,经过传送门下载的demo大概了解到DevMateKit
是作一些付费弹窗,举报弹窗,kevlar
代码混淆。
0x0000000000029a7c
Hopper 信息分析根据Hopper
分析结果看出可疑地址A主要是在作一些绘制UI操做,咱们主要目的是要改掉App中一个凭证字段信息相似 isActiva , isRegis 之类的字眼。排除掉可疑地址A。
0x00000001003ff263
Hopper 信息分析
发现定位到的地址操做符是test,这个有着重大嫌疑,大几率是此地址去作是否注册判断。咱们继续去排查可疑地址C。
0x00000001003dbe37
Hopper 信息分析由分析结果得知可疑地址C主要是作saveDocument:
操做,而且看上图左边红色框能够得知这一顿操做没有作一些test或者是cmp或者是提早ret之类的操做,基本也能够排除掉可疑地址C。
0x00000001003ff263
的hopper数据,切换至控制流图(Control Flow Graph
)备注:快捷键 Space
查看上图分析一处逻辑判断为 al
和 0x1
作test
运算,可是此处逻辑地址为loc_1003ff259
是由loc_1003ff11e
的尾部的je
跳转过来的。
而je
的来源是上一层的al
和0x1
作test
运算,再往上看能够知道al
是经过call sub_1003b21b0
的返回值赋值的。
sub_1003b21b0
双击进入 sub_1003b21b0
的function实现的控制流图。进入目标func的控制流图后发现是个蛮庞大的函数,缩放一下页面看到整个流程图以下
分析上图控制流图结构,猜测若是是已购买用户的判断逻辑应该是一条清晰的流程也就是右侧箭头所指的通道。
接着着重看如何才能够走到阳光大道上
分析上图控制流图重点是经过cmp r13b, 0x3
后 je loc_1003b22cd
,翻译过来也就是判断r13b
是否是0x3
若是是0x3
就去阳光大道,那么咱们如今就想办法把r13b
变成0x3
。
继续往上看得知r13b
是eax
怼过来的,而eax
是经过function sub_100382d70
返回的。
那么如今关键就是这个sub_100382d70
sub_100382d70
双击进入sub_100382d70
的function。
分析下第二层梦境的大概实现,首先第一眼嫌疑最大的是_O7RH3WAr7wAQMdz5Xv
这个是被call的function是被混淆过的,其次经过这个_O7RH3WAr7wAQMdz5Xv
返回的al
最后是跟0x1
作test
。
那么如今冷静下思考有如下两个解决思路
简单方案-直接改sub_100382d70
提早返回0x3
而后去走阳光大道(若是忘记了为什么要返回0x3
,能够复习下4.3.2章节)
复杂方案-修改_O7RH3WAr7wAQMdz5Xv
内部实现,继续深究,改最根部判断。
Hooper
修改关键汇编运算逻辑。sub_100382d70
实现根据上述操做咱们得知sub_100382d70
作了一串操做,先push,后mov后push…,咱们如今其实只要返回个0x3
便可,那直接选中sub_100382d70
第一行修改,输入mov rax,0x3
,点Assemble and Go Next
,再继续输入ret
,继续Assemble and Go Next
。
修改后的结果以下,随后保存新的Executable文件
保存Executable
文件时点Cancel
接下来就是验证简单方案是否可行了,把刚生成的新Executable文件替换咱们目标App内的旧Executable文件,具体操做以下
原版entitlements文件数据以下,随后吧identifier对应的那几行干掉
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.application-identifier</key>
<string>3L68KQB4HG.com.readdle.PDFExpert-Mac</string>
<key>com.apple.developer.team-identifier</key>
<string>3L68KQB4HG</string>
<key>com.apple.security.get-task-allow</key>
<true/>
</dict>
</plist>
复制代码
修改后
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.get-task-allow</key>
<true/>
</dict>
</plist>
复制代码
保存后覆盖目标App的entitlements文件
codesign -f -s - --entitlements entitlementsFilePathPrefix/Entitlements.plist appPathPrefix/PDF\ Expert.app
复制代码
执行完终端输出提示/Applications/PDF Expert 3.app: replacing existing signature
即表示完成替换
随后从新打开目标App,首先检查当前App的是否注册状态以下图
随后尝试修改任意pdf文件保存,保存成功!
_O7RH3WAr7wAQMdz5Xv
的前世此生早在上文4.1.4
简单了解目标App所用的到第三方库kevlar
能支持代码混淆,咱们先简单看看_O7RH3WAr7wAQMdz5Xv
的函数结构大概以下
看不是很懂,咱们切换至伪代码视角看看
这里咱们发现个关键字符串 kevlar
,那基本能够认定此处的混淆代码的出处是DevMateKit
了。
DevMateKit提供的demo工程咱们搜索kevlar
继续怼进DMKevlarApplication.h
看看代码
//! Function help with running timer for advanced check
#define DMKRunNewIntegrityCheckTimer DzVpwUg0VXKMIfCPA
FOUNDATION_EXTERN void DMKRunNewIntegrityCheckTimer(NSUInteger num, NSTimeInterval checkFrequency);
//! Checks if applicaion activated
#define DMKIsApplicationActivated PfCuPgJSp5KVlvc8W1
FOUNDATION_EXTERN BOOL DMKIsApplicationActivated(DMKevlarError *outKevlarError);
//! Returns user license info
#define DMKCopyLicenseUserInfo dReea3NiUFGwgD52YPa
FOUNDATION_EXTERN CFDictionaryRef DMKCopyLicenseUserInfo(void) CF_RETURNS_RETAINED;
//! Forces license validation request on DevMate server
#define DMKValidateLicense i2rRAQi8BfdE2G9geRSu
FOUNDATION_EXTERN void DMKValidateLicense(void (^completionHandler)(NSError *errorOrNil));
//! Deactivates application and invalidates license info
#define DMKInvalidateLicense kLLTbFMUP234v8xDp6Uck
FOUNDATION_EXTERN BOOL DMKInvalidateLicense(void);
/**
This category will extend functionality of NSApplication to be complies with Kevlar concept of protection.
Rigth now, some helper inteface have been declare there, because it is kind of complicated to load category.
*/
#define com_devmate_Kevlar YC2eXYjMnR
@interface NSApplication (com_devmate_Kevlar)
复制代码
发现好多混淆函数,简单看注释//! Checks if applicaion activated
理论上这个函数应该是咱们要找的最关键函数。
FOUNDATION_EXTERN BOOL DMKIsApplicationActivated(DMKevlarError *outKevlarError);
就是咱们要找的function呢?如今手头上有下载好的DevMateKit
的demo工程,那么直接run一个.app
文件出来丢到Hopper
分析对比就能够了
上图是run的CustomTrialExample这个target后的截图,此时记录下可疑函数的混淆标记为PfCuPgJSp5KVlvc8W1
随后把这个CustomTrialExample.app
丢到Hopper
一顿分析后直接搜索混淆标记PfCuPgJSp5KVlvc8W1
这下就基本上真相大白了,根据下图对比得知
也就是咱们基本核实
FOUNDATION_EXTERN BOOL DMKIsApplicationActivated(DMKevlarError *outKevlarError)
就是函数_O7RH3WAr7wAQMdz5Xv
上辈子的初始形态了。
_O7RH3WAr7wAQMdz5Xv
重写DMKIsApplicationActivated
主要作了两个事
完整函数返回了BOOL
传入指针DMKevlarError *outKevlarError
内部可能作修改
咱们要重写成什么样子?
鉴于此function是要返回个是否已激活/付费,那尝试下完整函数返回固定为0x1
常规来讲已激活/付费的用户调此function理论上不该该有error存在,也就是咱们须要把传入指针对应的地址的内容变成0x0
那么改为下图的样子也就基本上没啥毛病了
转成伪代码一看就懂了
int _O7RH3WAr7wAQMdz5Xv(int arg0) {
rdi = arg0;
if (rdi != 0x0) {
*rdi = 0x0;
}
return 0x1;
}
复制代码
那么咱们就把咱们重写的目的都实现了,接下来就是见证奇迹的时刻了
重写 _O7RH3WAr7wAQMdz5Xv
后和上文5.1.2
,5.1.3
,5.1.4
作法一致,最后验证出来结果也是同样的能够保存成功!
hopper修改 alt+a / option+a
hopper保存 win+shift+e / cmd+shift+e
hopper寻址 g
hopper查引用 x
破解 Cornerstone by Chen华锋 //本人逆向编程的引路人
一行代码教你解决FlutterPlatformViews内存泄露 by AShawn
手把手教你在Flutter项目优雅的使用ORM数据库 by williamwen1986
flutter通用基础库flutter_luakit_plugin by williamwen1986
github - flutter_luakit_plugin使用例子 by williamwen1986
手把手教你解决 Flutter engine 内存泄漏 by 共田君
github - 编译产物下载 修复内存泄漏后的flutter engine(可直接使用)by 共田君
github demo - 修复内存泄漏后的flutter engine by 共田君
持续更新中...