前言
此文為逆向微信二進制文件,實現(xiàn)偽裝定位,查看附近的人的教程,手把手教你玩轉(zhuǎn)微信!學會之后再去逆向微信其他功能易如反掌。
在實踐之前,需要準備好一部越獄的手機,涉及到的開發(fā)工具有cycript,LLDB與debugserver,OpenSSH,IDA,Reveal,theos,CydiaSubstrate,dumpdecrypted,class-dump等,具體安裝過程請參考iOS應(yīng)用逆向工程(第2版)書籍。
當前微信版本號為6.5.18。
git地址 https://github.com/zhaochengxiang/iOSWeChatFakeLocation
需求
自定義用戶當前所在的位置,從而查看附近的人。
實現(xiàn)界面



對需求進行分析
1.查看附近的人。
我們在微信的附近的人界面,是怎么實現(xiàn)獲取附近的人功能的呢?我想的話,大家一定很容易就知道,微信肯定是通過用戶所在位置的經(jīng)緯度來判斷的,那我們?nèi)绻茉诟浇娜私缑妫业绞褂媒?jīng)緯度的函數(shù),在里面使用我們之前保存在本地的經(jīng)緯度等信息,我們的需求就能實現(xiàn)了。
2.自定義用戶當前所在的位置。
我們在微信的聊天界面中有個發(fā)送位置的界面,可以從界面中的地圖上選取地點,也可以搜索地點,點擊右上角的發(fā)送,即可發(fā)送選中的位置,那如果發(fā)送的數(shù)據(jù)里面能獲取到用戶的經(jīng)緯度等信息,再將這些信息保存在本地,我們的偽裝定位功能就能實現(xiàn)了。
3.如何跳轉(zhuǎn)到發(fā)送位置界面。
這里跳轉(zhuǎn),可以參考下從聊天界面跳轉(zhuǎn)到發(fā)送位置界面的實現(xiàn)過程。
OK,需求分析到此結(jié)束,是時候來看看具體的操作了。
找到附近的人界面使用經(jīng)緯度的函數(shù)
1.通過Reveal以及cycript,找到微信附近的人界面。
微信進入附近的人界面,連接Reveal,可以發(fā)現(xiàn)這個界面使用了一個名為MMTableView的控件。接下來我們通過這個控件,來一步一步找到附近的人界面的ViewController。
使用USB連接到iOS,具體操作請參考iOS應(yīng)用逆向工程(第二版)中usbmuxd的介紹。
接下來使用cycript來找到這個ViewController。

我們在終端搜索MMTableView,找到這個類的地址。通過這個地址找到ViewController。

找到PeopleNearByListViewController,設(shè)置它的右側(cè)導(dǎo)航控件為空,發(fā)現(xiàn)界面沒反應(yīng),這個PeopleNearByListViewController可能不是我們要找的目標,通過PeopleNearByListViewController繼續(xù)往上找。

找到SeePeopleNearbyViewController,設(shè)置它的右側(cè)導(dǎo)航控件為空,發(fā)現(xiàn)界面右上角控件消失,可以肯定,這個SeePeopleNearbyViewController就是我們要找的。
我們打開SeePeopleNearbyViewController.h文件,大致瀏覽一下,發(fā)現(xiàn)該類未找到使用用戶地址相關(guān)的接口,但是在里面發(fā)現(xiàn)了SeePeopleNearByLogicController類,微信通常將ViewController中使用的邏輯放在LogicController中進行處理,看一下SeePeopleNearByLogicController.h文件,能夠看到很多與地址有關(guān)的數(shù)據(jù)以及接口,這個類并不復(fù)雜,我相信大家很快就能確定- (void)onRetrieveLocationOK:(id)arg1這個接口,可能就是我們需要的接口,arg1可能就是用戶當前的經(jīng)緯度等信息。如果真是我們分析的這樣,讓我們直接在這里使用我們偽裝后的位置,就能達到我們的目的。
那怎么確定這個接口就是我們要找的呢?
有兩種方法,第一種方法是通過LLDB與debugserver。首先在IDA中打開微信的二進制文件,找到上述接口。

符號所在模塊的ASLR偏移為0x1016e8250

偏移前符號基地址為0x2c000
偏移后符號基地址為 0x1016e8250+ 0x2c000=0x101714250

設(shè)置斷點,重新進入附近的人界面。

輸出arg1的值。

可以看到,這是用戶當前的經(jīng)緯度信息。
第二種方法是通過Tweek,直接hook上述接口,打印arg1參數(shù)即可,這種比較簡單,在這里就不做介紹了。
在發(fā)送位置界面截獲經(jīng)緯度等信息
1.通過Reveal以及cycript,找到發(fā)送位置的界面。這里就就具體介紹了,參考上面的過程。相信大家很快就能找到MMPickLocationViewController。那右上角的發(fā)送按鈕是如何設(shè)置的呢?右上角的按鈕一般是UIBarButtonItem通過initWithTitle:(NSString *)title style:(UIBarButtonItemStyle)style target:(id)target action:(SEL)action來初始化,如果我們找到了設(shè)置按鈕的地方,也就找到了事件響應(yīng)的地方,里面一定有我們所需要的位置的經(jīng)緯度等信息。帶著問題,我們看看MMPickLocationViewController.h,發(fā)現(xiàn)未找到與右上角相關(guān)的接口信息,但是我們發(fā)現(xiàn)了MMPickLocationViewControllerDelegate,我們看看代理中的方法,發(fā)現(xiàn)了- (UIBarButtonItem *)onGetRightBarButton,原來是在上層界面中進行的設(shè)置。在微信頭文件搜索MMPickLocationViewControllerDelegate,能找到BaseMsgContentLogicController.h,該類是用來處理聊天界面中的邏輯,使用IDA看看BaseMsgContentLogicController中onGetRightBarButton的具體實現(xiàn)。

分析匯編,能判斷出發(fā)送按鈕的響應(yīng)函數(shù)為onFinishSelectedLocation,使用IDA分析這個函數(shù)實現(xiàn)。

上面只截取了部分信息。分析匯編,首先[m_pickLocationViewController DismissMyselfAnimated:YES] 來返回聊天界面,接著使用[m_pickLocationViewController getCurrentPOIInfo]獲取POIInfo信息,最后調(diào)用[m_pickLocationViewController reportOnDone]徹底釋放發(fā)送位置界面。打開POIInfo.h,能很快發(fā)現(xiàn)@property(nonatomic) struct CLLocationCoordinate2D coordinate,這就是我們要找的位置信息,將它保存在本地即可。
如何跳轉(zhuǎn)到發(fā)送位置界面
這里我們參考聊天界面跳轉(zhuǎn)到發(fā)送位置界面的過程,如果能找到相關(guān)函數(shù),分析里面的實現(xiàn),那我們這個問題就能得到解決。
那我們打開聊天界面的邏輯控制器BaseMsgContentLogicController,觀察該頭文件,發(fā)現(xiàn)兩個可疑的接口:
- (void)ViewLocation:(id)arg1;
- (void)SelectLocation:(_Bool)arg;
首先通過IDA來分析ViewLocation實現(xiàn)。

分析匯編,很容易知道,這是個彈出提示,用來提示是發(fā)送位置還是共享實時位置。
接著來分析SelectLocation實現(xiàn)。



分析匯編,首先MMPickLocationViewController通過- (id)initWithScene:(unsigned int)arg1 OnlyUseUserLocation:(_Bool)arg2來進行初始化,然后[[MMUINavigationController alloc] initWithRootViewController: m_pickLocationViewController]來初始化NavigationController,這里假設(shè)該NavigationController命名為nc,最后使用[self PresentModalViewController:nc animated:YES]來進行跳轉(zhuǎn)。
(initWithScene:OnlyUseUserLocation:的參數(shù)請參考之前介紹的調(diào)適方法來獲取值,這里就不重復(fù)介紹了)。
OK,分析完畢,開始寫tweek吧。
后期我將繼續(xù)微信的一些小插件開發(fā),請關(guān)注一下我,謝謝!
如果覺得我的文章不錯,請我喝杯熱茶吧
