手把手教你如何破解付費(fèi)MacApp

目錄截圖.png Typora的自帶內(nèi)容目錄截圖

復(fù)雜方案解決結(jié)果--->破解版?zhèn)魉烷T

前提準(zhǔn)備

  • Hopper Disassembler(X,G,Esc,Space...,度娘/谷歌,后面簡稱Hopper

  • Xcode(App Store)

  • frida(前置條件配置好 python環(huán)境雇锡,下載好pip逛钻,隨后用pip下載,具體度娘/谷歌找攻略即可)

  • 匯編指令基礎(chǔ)掌握(je,jne,jmp,jle,mov,call,ret,nop,xor,lea,rax,rdi,rsi,rcx....)

  • lldb指令基礎(chǔ)掌握(bt, image lookup --address ,p, c...)

  • 終端操作(codesign *锰提,frida *)

  • 具備一定的編程思想

  • 基礎(chǔ)逆向工程思維基礎(chǔ)掌握(Executable,重簽,覆蓋entitlements)

小目標(biāo):學(xué)習(xí)下一些簡單匯編知識以及市面上的一些付費(fèi)App的付費(fèi)模塊的代碼思路然后順便逆向破解 PDF Expert

第一步

  • 目的---體驗(yàn)原裝PDF Expert 修改任意pdf文件后保存查看效果

1.1體驗(yàn)未破解版流程

image

第二步

在保存操作前是沒有提示升級到完整版這個(gè)彈窗的曙痘,所以我們在Xcode attach成功后可以嘗試增加個(gè)符號斷點(diǎn)windowWillLoad查看調(diào)用棧的關(guān)系

  • 目的---查看調(diào)用圖層間的調(diào)用關(guān)系,從而嘗試去定位到關(guān)鍵代碼欲账。

2.1 Xcode新建個(gè)工程

image

2.2 attach查看對應(yīng)圖層關(guān)系

2.2.1 Attach App
image

2.2.2 Debug View Hierarchy

image

查看圖層關(guān)系 在增加符號斷點(diǎn)windowWillLoad后在修改后的pdf界面觸發(fā)保存操作出現(xiàn)彈窗發(fā)現(xiàn)沒有停下斷點(diǎn)屡江,說明這條路行不通。

但是我們也獲取到了一個(gè)關(guān)鍵信息:最上面的控件名稱為 DMTrialController 赛不。

第三步

  • 目的---使用frida通過已知彈出升級框的類 DMTrialController ,查找出具體調(diào)用的方法堆棧

3.1 frida-trace 查看對應(yīng)方法調(diào)用關(guān)系

在終端上輸入 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輸出在點(diǎn)擊保存時(shí)觸發(fā)的方法為-[DMActivationController performActivationStepWithStep:0x66]

記錄下來回到第二步操作的2.4查看付費(fèi)彈窗堆棧信息罢洲。

3.2 增加符號斷點(diǎn)查看

image

再次保存操作后觸發(fā)斷點(diǎn)終端查看到嫌疑關(guān)鍵代碼如下

 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調(diào)用時(shí)的地址信息

 (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踢故。

4.1 科普使用Hooper

4.1.1 直接拽

image
image

4.1.2 稍等一會(huì)Hopper加載完成

4.1.3 追查付費(fèi)彈窗底細(xì)

加載完成后在界面左側(cè)輸入剛才Xcode Attach控件名 DMTrialController

image

分析搜索結(jié)果發(fā)現(xiàn)并沒有直接匹配的 DMTrialController 這玩意,猜想這個(gè)空間不是直接在主工程實(shí)現(xiàn)的惹苗,隨后看跟 DMTrialController 命名類似的DMTrialWelcomeStepController 看上圖可以找到文件路徑并且發(fā)現(xiàn)關(guān)鍵字DevMateKit殿较,其實(shí)早在Xcode Attach時(shí)查看圖層就可以發(fā)現(xiàn) 這個(gè)付費(fèi)彈窗的命名前綴是DMT 而主工程的命名前綴是PDF_Expert,很大概率付費(fèi)彈窗是用的第三方庫.

DevMateKit傳送門

4.1.4 簡單了解DevmateKit有哪些功能

這個(gè)就不在這介紹了,通過傳送門下載的demo大概了解到DevMateKit是做一些付費(fèi)彈窗桩蓉,舉報(bào)彈窗淋纲,kevlar代碼混淆。

4.2 逐個(gè)排查可疑地址

4.2.1 地址A:0x0000000000029a7cHopper 信息分析

image

image

根據(jù)Hopper分析結(jié)果看出可疑地址A主要是在做一些繪制UI操作院究,我們主要目的是要改掉App中一個(gè)憑證字段信息類似 isActiva , isRegis 之類的字眼洽瞬。排除掉可疑地址A。

4.2.2 地址B:0x00000001003ff263Hopper 信息分析
image

發(fā)現(xiàn)定位到的地址操作符是test业汰,這個(gè)有著重大嫌疑伙窃,大概率是此地址去做是否注冊判斷。我們繼續(xù)去排查可疑地址C样漆。

4.2.3 地址C:0x00000001003dbe37Hopper 信息分析

image

由分析結(jié)果得知可疑地址C主要是做saveDocument:操作,并且看上圖左邊紅色框可以得知這一頓操作沒有做一些test或者是cmp或者是提前ret之類的操作为障,基本也可以排除掉可疑地址C。

4.3 主要調(diào)查重點(diǎn)嫌疑地址

4.3.1 重新查看可疑地址B:0x00000001003ff263的hopper數(shù)據(jù)放祟,切換至控制流圖(Control Flow Graph)

備注:快捷鍵 Space

image

查看上圖分析一處邏輯判斷為 al0x1test運(yùn)算鳍怨,但是此處邏輯地址為loc_1003ff259是由loc_1003ff11e的尾部的je跳轉(zhuǎn)過來的。

je的來源是上一層的al0x1test運(yùn)算,再往上看可以知道al是通過call sub_1003b21b0的返回值賦值的跪妥。

4.3.2 解析第一層夢境function sub_1003b21b0

雙擊進(jìn)入 sub_1003b21b0的function實(shí)現(xiàn)的控制流圖鞋喇。進(jìn)入目標(biāo)func的控制流圖后發(fā)現(xiàn)是個(gè)蠻龐大的函數(shù),縮放一下頁面看到整個(gè)流程圖如下

image

分析上圖控制流圖結(jié)構(gòu)骗奖,猜想如果是已購買用戶的判斷邏輯應(yīng)該是一條清晰的流程也就是右側(cè)箭頭所指的通道确徙。

接著著重看如何才可以走到陽光大道上

image

分析上圖控制流圖重點(diǎn)是通過cmp r13b, 0x3je loc_1003b22cd醒串,翻譯過來也就是判斷r13b是不是0x3如果是0x3就去陽光大道,那么我們現(xiàn)在就想辦法把r13b變成0x3

image

繼續(xù)往上看得知r13beax懟過來的鄙皇,而eax是通過function sub_100382d70 返回的芜赌。

那么現(xiàn)在關(guān)鍵就是這個(gè)sub_100382d70

4.3.3 解析第二層夢境function sub_100382d70

雙擊進(jìn)入sub_100382d70的function。

image

分析下第二層夢境的大概實(shí)現(xiàn)伴逸,首先第一眼嫌疑最大的是_O7RH3WAr7wAQMdz5Xv這個(gè)是被call的function是被混淆過的缠沈,其次通過這個(gè)_O7RH3WAr7wAQMdz5Xv 返回的al最后是跟0x1test

那么現(xiàn)在冷靜下思考有以下兩個(gè)解決思路

  • 簡單方案-直接改sub_100382d70提前返回0x3然后去走陽光大道(如果忘記了為何要返回0x3,可以復(fù)習(xí)下4.3.2章節(jié))

  • 復(fù)雜方案-修改_O7RH3WAr7wAQMdz5Xv 內(nèi)部實(shí)現(xiàn)错蝴,繼續(xù)深究洲愤,改最根部判斷。

第五步

  • 目的---使用Hooper修改關(guān)鍵匯編運(yùn)算邏輯顷锰。

5.1 簡單方案解法嘗試

5.1.1 修改sub_100382d70實(shí)現(xiàn)

根據(jù)上述操作我們得知sub_100382d70做了一串操作柬赐,先push,后mov后push…官紫,我們現(xiàn)在其實(shí)只要返回個(gè)0x3即可肛宋,那直接選中sub_100382d70第一行修改,輸入mov rax,0x3 束世,點(diǎn)Assemble and Go Next,再繼續(xù)輸入ret,繼續(xù)Assemble and Go Next酝陈。

image

修改后的結(jié)果如下,隨后保存新的Executable文件

image

5.1.2 保存Executable文件

image

保存Executable文件時(shí)點(diǎn)Cancel

image

接下來就是驗(yàn)證簡單方案是否可行了毁涉,把剛生成的新Executable文件替換我們目標(biāo)App內(nèi)的舊Executable文件沉帮,具體操作如下

image

5.1.3 覆蓋entitlements文件

原版entitlements文件數(shù)據(jù)如下,隨后吧identifier對應(yīng)的那幾行干掉

 <?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> 

保存后覆蓋目標(biāo)App的entitlements文件

 codesign -f -s - --entitlements entitlementsFilePathPrefix/Entitlements.plist appPathPrefix/PDF\ Expert.app 

執(zhí)行完終端輸出提示/Applications/PDF Expert 3.app: replacing existing signature即表示完成替換

5.1.4 檢驗(yàn)簡單方案處理結(jié)果

隨后重新打開目標(biāo)App贫堰,首先檢查當(dāng)前App的是否注冊狀態(tài)如下圖

image

隨后嘗試修改任意pdf文件保存穆壕,保存成功!

5.2 復(fù)雜方案解決嘗試

5.2.1 _O7RH3WAr7wAQMdz5Xv的前世今生

早在上文4.1.4 簡單了解目標(biāo)App所用的到第三方庫kevlar能支持代碼混淆严嗜,我們先簡單看看_O7RH3WAr7wAQMdz5Xv的函數(shù)結(jié)構(gòu)大概如下

image

看不是很懂粱檀,我們切換至偽代碼視角看看

image

這里我們發(fā)現(xiàn)個(gè)關(guān)鍵字符串 kevlar,那基本可以認(rèn)定此處的混淆代碼的出處是DevMateKit了。

DevMateKit提供的demo工程我們搜索kevlar

image

繼續(xù)懟進(jìn)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) 

發(fā)現(xiàn)好多混淆函數(shù)漫玄,簡單看注釋//! Checks if applicaion activated 理論上這個(gè)函數(shù)應(yīng)該是我們要找的最關(guān)鍵函數(shù)茄蚯。

  • 那么如何核實(shí)FOUNDATION_EXTERN BOOL DMKIsApplicationActivated(DMKevlarError *outKevlarError);就是我們要找的function呢?

現(xiàn)在手頭上有下載好的DevMateKit的demo工程睦优,那么直接run一個(gè).app文件出來丟到Hopper分析對比就可以了

image

上圖是run的CustomTrialExample這個(gè)target后的截圖渗常,此時(shí)記錄下可疑函數(shù)的混淆標(biāo)記為PfCuPgJSp5KVlvc8W1

隨后把這個(gè)CustomTrialExample.app丟到Hopper一頓分析后直接搜索混淆標(biāo)記PfCuPgJSp5KVlvc8W1

image

這下就基本上真相大白了,根據(jù)下圖對比得知

image

也就是我們基本核實(shí)

FOUNDATION_EXTERN BOOL DMKIsApplicationActivated(DMKevlarError *outKevlarError)

就是函數(shù)_O7RH3WAr7wAQMdz5Xv上輩子的初始形態(tài)了汗盘。

5.2.2 _O7RH3WAr7wAQMdz5Xv重寫

  • DMKIsApplicationActivated主要做了兩個(gè)事

    • 完整函數(shù)返回了BOOL

    • 傳入指針DMKevlarError *outKevlarError 內(nèi)部可能做修改

  • 我們要重寫成什么樣子皱碘?

    • 鑒于此function是要返回個(gè)是否已激活/付費(fèi),那嘗試下完整函數(shù)返回固定為0x1

    • 常規(guī)來說已激活/付費(fèi)的用戶調(diào)此function理論上不應(yīng)該有error存在,也就是我們需要把傳入指針對應(yīng)的地址的內(nèi)容變成0x0

那么改成下圖的樣子也就基本上沒啥毛病了

image

轉(zhuǎn)成偽代碼一看就懂了

int _O7RH3WAr7wAQMdz5Xv(int arg0) {
    rdi = arg0;
    if (rdi != 0x0) {
            *rdi = 0x0;
    }
    return 0x1;
}

那么我們就把我們重寫的目的都實(shí)現(xiàn)了隐孽,接下來就是見證奇跡的時(shí)刻了

5.2.3 檢驗(yàn)復(fù)雜方案處理結(jié)果

重寫 _O7RH3WAr7wAQMdz5Xv后和上文5.1.2 癌椿,5.1.3健蕊,5.1.4做法一致,最后驗(yàn)證出來結(jié)果也是一樣的可以保存成功踢俄!

總結(jié)

快捷鍵補(bǔ)充(windows/Mac)

hopper修改 alt+a / option+a

hopper保存 win+shift+e / cmd+shift+e

hopper尋址 g

hopper查引用 x

聲明:此文僅用于學(xué)習(xí)用途缩功,請勿用于非法用途。

轉(zhuǎn)載請注明出處都办。謝謝嫡锌!


逆向技術(shù)積累相關(guān)鏈接

破解<Cornerstone> by Chen華鋒 //本人逆向編程的引路人


YY Flutter技術(shù)積累相關(guān)鏈接

flutter多實(shí)例實(shí)戰(zhàn) by共田君

一行代碼教你解決FlutterPlatformViews內(nèi)存泄露 by
AShawn

手把手教你在Flutter項(xiàng)目優(yōu)雅的使用ORM數(shù)據(jù)庫 by
williamwen1986

flutter通用基礎(chǔ)庫flutter_luakit_plugin by
williamwen1986

github - flutter_luakit_plugin使用例子 by
williamwen1986

手把手教你編譯Flutter engine by 共田君

手把手教你解決 Flutter engine 內(nèi)存泄漏 by 共田君

github - 編譯產(chǎn)物下載 修復(fù)內(nèi)存泄漏后的flutter engine(可直接使用)by 共田君

github demo - 修復(fù)內(nèi)存泄漏后的flutter engine by 共田君

持續(xù)更新中...

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市琳钉,隨后出現(xiàn)的幾起案子势木,更是在濱河造成了極大的恐慌,老刑警劉巖歌懒,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件啦桌,死亡現(xiàn)場離奇詭異,居然都是意外死亡歼培,警方通過查閱死者的電腦和手機(jī)震蒋,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來躲庄,“玉大人,你說我怎么就攤上這事钾虐≡刖剑” “怎么了?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵效扫,是天一觀的道長倔监。 經(jīng)常有香客問我,道長菌仁,這世上最難降的妖魔是什么浩习? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮济丘,結(jié)果婚禮上谱秽,老公的妹妹穿的比我還像新娘。我一直安慰自己摹迷,他們只是感情好疟赊,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著峡碉,像睡著了一般近哟。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上鲫寄,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天吉执,我揣著相機(jī)與錄音疯淫,去河邊找鬼。 笑死戳玫,一個(gè)胖子當(dāng)著我的面吹牛熙掺,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播量九,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼适掰,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了荠列?” 一聲冷哼從身側(cè)響起类浪,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎肌似,沒想到半個(gè)月后费就,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡川队,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年力细,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片固额。...
    茶點(diǎn)故事閱讀 40,040評論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡眠蚂,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出斗躏,到底是詐尸還是另有隱情逝慧,我是刑警寧澤,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布啄糙,位于F島的核電站笛臣,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏隧饼。R本人自食惡果不足惜沈堡,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望燕雁。 院中可真熱鬧诞丽,春花似錦、人聲如沸贵白。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽禁荒。三九已至猬膨,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背勃痴。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工谒所, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人沛申。 一個(gè)月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓劣领,卻偏偏與公主長得像,于是被迫代替她去往敵國和親铁材。 傳聞我的和親對象是個(gè)殘疾皇子尖淘,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評論 2 355

推薦閱讀更多精彩內(nèi)容

  • Lua 5.1 參考手冊 by Roberto Ierusalimschy, Luiz Henrique de F...
    蘇黎九歌閱讀 13,803評論 0 38
  • 一.微講解 首先,明確濕地的概念著觉。在現(xiàn)行的人教版村生、中圖版、魯教版饼丘、湘教版四套高中地理教材中趁桃,只有湘教版必修三...
    一粒沙子在簡書閱讀 6,181評論 1 4
  • 挑戰(zhàn)自己這個(gè)事情, 21天本就是個(gè)挑戰(zhàn)肄鸽, 無論怎樣的挑戰(zhàn)卫病, 持續(xù)21天都是個(gè)痛苦的蛻變過程。 今天的任務(wù)是互推引粉...
    馬春穎閱讀 389評論 0 0