利用LLDB對微信進行分析,而後利用分析的結果,再逐步講解如何Hook微信的登陸過程,截獲微信密碼。ios
在上一篇文章(APP重簽名)中,已經介紹瞭如何對APP重簽名,而且利用XCode將微信跑起來,既然到了這一步,就萬萬不能錯過強大的LLDB。這篇文章就講爲你們講解到如何利用LLDB對微信進行分析,而後利用分析的結果,再逐步講解如何Hook微信的登陸過程,截獲微信密碼。git
老規矩,片頭先給福利:點擊下載Demo:HookWeChat,此次有兩份代碼。因爲越獄版微信體積太大,受到github限制,因此並無將它傳到github,能夠在下方連接單獨下載github
文中所須要用到的工具和文件:
越獄版本微信7.0.2 提取碼: 2w87
MachOView 提取碼: n3hy
yololib 提取碼:e8qs
class-dump 提取碼:v5ku安全
接下來咱們會從一下幾部,讓微信脫下看似安全的外衣,裸露在你們面前。bash
什麼是Framework這裏就很少加敘述,我參考這個網站,很是詳細,看不懂你直接@我。點這裏:Framework最強講解微信
廢話很少說,接下來直接演示如何建立一個Framework,而且介紹跟我們Hook微信有關的基礎原理。架構
新建一個工程FrameworkDemo,新建一個Framework,取名FYHook app
在新建出來的FYHook文件夾中新建InjectCode(繼承NSObject)對象,而且新建代碼:工具
+ (void)load {
NSLog(@"來了,老弟😁");
}
複製代碼
直接運行,會發現來了,老弟😁
被輸出,證實用這種方法新建的Framework可以直接運行在咱們的項目中。 網站
根據上篇文章APP重簽名講到的,咱們可使用XCode將微信跑起來,那麼是否是將二者結合起來,就能夠將咱們的代碼注入進微信的APP呢?
根據APP重簽名中的結論,利用腳本能夠便捷重籤APP(由於咱們用的WeChat舉例,因此下面簡稱WeChat),那麼咱們在重籤腳本的工程中,直接建立一個Framework,能不能讓咱們Framework中的代碼在WeChat中運行?
很顯然,這是不行的(有興趣的能夠試一下)!爲何? 這個問題下面會回答,先把這個問題記在心中。
在咱們用XCode新建HYHook的時候,其實XCode幫咱們作了一部操做:建立HYHook時候,同時將HYHook連接到咱們的項目中(這是後期的XCode新增功能,早年的XCode這一步是須要咱們直接作的)
common
+
b
Build一下,會發如今已經Build出來的文件中的Frameworks下已經有FYHook了,已經已經代表FYHook被Copy咱們的ipa文件了。(如何看Build出來的文件?查看:
APP重簽名中Step 8 App重簽名)
可是FYHook在ipa文件中,並不表明着FYHook就能夠被咱們的可執行文件所執行,由於FYHook並無沒導報入咱們的可執行文件,只有在這個可行執行文件的
某一個地方
作好標記,告知可執行文件,在適當的時候須要加載外部的FYHook,纔可以正常運行。
而這個地方所說的可執行文件就是MachO
文件(具體什麼是MachO,這不是本片文章的重點內容,能夠持續關注筆者以後的文章,下一章詳細介紹這相當重要的MachO),咱們能夠利用工具MachOView來查看MachO中到底有什麼內容。
用MachOView打開FrameworkDemo的MachO,能夠看到以下圖
能夠看到其中的有個Load Commons組,這裏面就包括全部須要被動態加載的庫。也就是說,若是在Load Commons中沒有對應的FYHook,就不會加載FYHook。
在上圖中能夠看到FYHook已經被加入了Load Commons,而且圖右側也標記了FYHook所屬的目錄(和MachO文件同級的Frameworks下FYHook.framework中 ,FYHook.framework實際上是個文件夾,裏面的FYHook也是個MachO )
因此這裏就獲得了「爲何咱們直接將FYHook加入咱們的從重籤腳本工程,不能直接運行FYHook」的答案。 由於在在咱們Build出來的MachO文件中的Load Commons中沒有加入FYHook的路徑。因此沒法運行FYHook中的代碼。
那麼咱們直接將FYHook加入咱們Build出的MachO文件行嗎? 顯然也是不行的,由於咱們Build出的MachO文件始終會被原始包(WeChat)中的MachO給替換掉。咱們須要將FYHook加入原始包(WeChat)中的MachO中。
這裏咱們就須要用到終端命令行工具:yololib 提取碼:e8qs
將下載下來的yololib.zip解壓後獲得的yololib放在目錄/usr/local/bin下,這樣咱們在終端中就可使用yololib命令了
如下命令就是將FYHook注入WeChat的命令
// yololib 「MachO路徑」 「FYHook相對MachO的路徑」
yololib WeChat Frameworks/FYHook.framework/FYHook
複製代碼
新建工程,取名InjectFrameWork,過程可參照上一篇文章(APP重簽名) 最後獲得以下工程:
新建一個Framework文件,取名FYHook,在FYHook中新建文件InjectCode,在InjectCode加入以前提到的一樣的load代碼, 等到以下工程:
找到WeChat的MachO文件,打開終端,進入此目錄下 執行命令
// yololib 「MachO路徑」 「FYHook相對MachO的路徑」
yololib WeChat Frameworks/FYHook.framework/FYHook
複製代碼
zip -ry WeChat.ipa Payload
複製代碼
將新獲得的WeChat.ipa從新加入APP文件(這一步其實能夠只加入文件,而不用加入工程),刪除原來的Wechat7.0.2越獄.ipa。
common
+ R
運行代碼,會發現微信跑起來了,咱們的來了,老弟😁
也被輸出了!
以前分析了咱們建立了FYHook,可是沒有對MachO注入,獲得的答案是來了,老弟😁
不能被輸出,WeChat能跑起來。
那麼若是咱們對MachO注入FYHook,卻沒有建立對應的FYHook.framework,會怎麼樣呢?
這就留給你們思考,再去驗證了,有答案的同窗也能下方留言,並說出緣由哦。
XCode跑起微信以後,跳轉到登陸頁面,利用ViewDebug查看具體的詳細的UI
能夠看到,登陸按鈕是一個FixTitleColorButton對象,他的Target的名字存在地址0x280afaa40中,他的Action名字存在地址0x280afac00中。 用一樣的方法查看帳號密碼的輸入框,會發現他們都屬於一個對象,叫作WCUITextField利用LLDB查看登陸按鈕具體的Target和Action名稱
得知: 登陸按鈕處於WCAccountMainLoginViewController這個頁面之中 登陸按鈕的點擊方法叫作onNextclass-dump,是能夠把Objective-C運行時的聲明的信息導出來的工具。其實就是能夠導出.h文件。用class-dump能夠把未經加密的app的頭文件導出來。
點擊這下載命令行工具:class-dump 提取碼:v5ku 一樣的,將class-dump拷貝到Mac的目錄/usr/local/bin下,這樣咱們在終端中就可使用yololib命令了
運行命令將WeChat全部的頭文件導出來。
// class-dump -H 「app的MachO文件」 -o 「輸入的目錄」
class-dump -H WeChat -o /Users/dengbin/Code/GitHub/HookWeChat/InjectFrameWork/APP/WeChat-H
複製代碼
利用文本工具,例如Sublime查看WeChat的頭文件,找到前面發現的WCAccountMainLoginViewController
發現裏面確實有方法- (void)onNext;
,還有長得很像帳號輸入框,密碼輸入框的對象_textFieldUserNameItem
,_textFieldUserPwdItem
。
接下來就是找到密碼輸入框裏面的字符串了,能夠發現這兩個都是WCAccountTextFieldItem對象,全部咱們繼續在導出的文件裏面找到WCAccountTextFieldItem
在其中只發現一個tips對象m_labelTip,沒有發現對應的textfiled,可是能夠看到WCAccountTextFieldItem是繼承於WCBaseTextFieldItem的,因此繼續查找WCBaseTextFieldItem
從這就能夠看到一個m_textField對象,這是個WCUITextField對象,疑似咱們的目標textField,繼續查看WCUITextField
果真,這就是一個UITextField文件,那麼咱們就能夠經過text字段取出其string。
接下來在用LLDB試試看,驗證下咱們的猜測:
隨便在帳號欄輸入:qwerty
而後在密碼欄輸入:123456
po [(WCAccountMainLoginViewController *)0x1128bbc00 valueForKey:@"_textFieldUserPwdItem"]
po [(WCAccountTextFieldItem *)0x28328e880 valueForKey:@"m_textField"]
po [(WCUITextField *)0x112163a00 text]
複製代碼
其中第一個地址0x1128bbc00是在前兩部利用ViewDubg找到的。
能夠發現最後確實找到了咱們輸入的密碼123456
,證實咱們的分析是正確的。
接下來又是代碼Coding了。原理分析完,其實代碼就很簡單了,直接上代碼:
+ (void)load {
NSLog(@"來了,老弟😁");
Method onNext = class_getInstanceMethod(objc_getClass("WCAccountMainLoginViewController"), sel_registerName("onNext"));
//1.保存原始的IMP
old_onNext = method_getImplementation(onNext);
//2.SET
method_setImplementation(onNext, (IMP)my_next);
}
IMP (*old_onNext)(id self,SEL _cmd);
void my_next(id self,SEL _cmd){
// 獲取密碼
NSString *pwd = [[[self valueForKey:@"_textFieldUserPwdItem"] valueForKey:@"m_textField"] performSelector:@selector(text)];
NSString *accountTF = [[[self valueForKey:@"_textFieldUserNameItem"] valueForKey:@"m_textField"] performSelector:@selector(text)];
NSLog(@"密碼是!%@",pwd);
// 將密碼追加在帳號欄的後面
[[[self valueForKey:@"_textFieldUserNameItem"] valueForKey:@"m_textField"] performSelector:@selector(setText:) withObject:[NSString stringWithFormat:@"%@+%@",accountTF,pwd]];
//調用原來的方法
old_onNext(self,_cmd);
}
複製代碼
稍微解釋一下,在前面咱們發現登陸的響聲事件是onNext,全部咱們利用Objective-C的Runtime特性,對onNext進行方法替換,在響應原有的onNext以前,咱們加上咱們本身的方法,好比代碼中的,在帳號欄中直接輸入密碼。
運行後結果如圖:
我這用的是setIMP和getIMP的方式,對原方法進行HOOK,其實方法有多種:如:class_replaceMethod()
,method_exchangeImplementations()
,這裏只是舉一個例子供你們參考。
這篇文章的全部代碼均可以在這下載到:HookWeChat
此次只是簡單的微信的一個靜態頁面進行了初步接觸,雖然思路簡單,但這運用到的工具,倒是無數大神前輩們爲咱們鋪好的路,感謝!
MachO文件在本文中只是初略的說起,其實在咱們逆向過程當中MachO是一個相當重要的存在,如:
因此,在下篇文章,筆者將會對MachO文件進行詳細的講解。請持續關注,以爲有幫助的點個收藏,留言評估了哦。