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 共田君
持續更新中...