iOS逆向工程(七):使用Theos逆向項(xiàng)目

使用Theos逆向項(xiàng)目

一浸须、Theos是什么?
  1. Theos是一套跨平臺(tái)的開(kāi)發(fā)工具琉闪,用于在不使用Xcode的情況下開(kāi)發(fā)迹炼、部署iOS插件,大多數(shù)插件開(kāi)發(fā)人員都使用Theos颠毙。

  2. Theos工具套件包含一些重要組件

    • NIC組件斯入,是一套項(xiàng)目模板系統(tǒng),提供了各式各樣的模板蛀蜜,用這些模板可以快速開(kāi)始項(xiàng)目

    • Make構(gòu)建系統(tǒng)刻两,由GNU Make驅(qū)動(dòng)的強(qiáng)大構(gòu)建系統(tǒng),能夠直接創(chuàng)建.deb軟件包滴某,并在Cydia中分發(fā)

    • Logos指令庫(kù)磅摹,提供了逆向的語(yǔ)法,允許使用一組預(yù)處理指令實(shí)現(xiàn)Hook

  3. 配置好Theos后霎奢,就可以使用Theos中的tweak模板户誓,快速創(chuàng)建逆向工程,并使用Logos語(yǔ)法修改別人App的一些行為 幕侠,例如:微信自動(dòng)搶紅包帝美、騰訊視頻去廣告等等,最后使用make構(gòu)建系統(tǒng)編譯晤硕、打包悼潭、分發(fā)庇忌。

  4. Theos目錄結(jié)構(gòu):https://github.com/theos/theos/wiki/Structure

  5. Theos環(huán)境變量和目錄:http://iphonedevwiki.net/index.php/Theos

二、Theos逆向的原理
  1. 使用tweak模板把咱們寫(xiě)的逆向代碼安裝到手機(jī)的原理:首先會(huì)把咱們編寫(xiě)的逆向代碼女责,編譯成dylib動(dòng)態(tài)庫(kù)漆枚,然后與plist文件一起,打包成deb文件抵知,然后通過(guò)手機(jī)的Cydia墙基,安裝到手機(jī)上 ,如下圖所示:

    tweak模板

  2. 改變App行為的原理:手機(jī)打開(kāi)要逆向的目標(biāo)App后刷喜,會(huì)在內(nèi)存中載入這個(gè)App的可執(zhí)行文件残制,此時(shí),Cydia會(huì)檢測(cè)plist文件中的BundleID是否和目標(biāo)App的一致掖疮,如果一致初茶,就會(huì)把咱們寫(xiě)的dylib動(dòng)態(tài)庫(kù)載入內(nèi)存,在調(diào)用目標(biāo)App的代碼時(shí)浊闪,會(huì)把消息轉(zhuǎn)發(fā)到咱們寫(xiě)的動(dòng)態(tài)庫(kù)中恼布,實(shí)現(xiàn)hook,如下圖所說(shuō):

    改變App行為的原理.png

三搁宾、如何配置Theos折汞?
1. 安裝簽名工具ldid
  • 先確保安裝了brew,安裝命令如下:
$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
  • 利用brew安裝ldid盖腿,安裝命令如下:
$ brew install ldid
2. 修改環(huán)境變量
  • 編輯用戶的配置文件:
$ vim ~/.bash_profile
  • .bash_profile文件后面加入以下兩行:
 export THEOS=~/theos
 export PATH=$THEOS/bin:$PATH
  • .bash_profile配置的環(huán)境變量立即生效爽待,命令如下:
$ source ~/.bash_profile
3. 下載Theos
  • 建議在~/.theos目錄下載代碼,也就是剛才配置的環(huán)境變量$THEOS翩腐,命令如下:
 $ git clone --recursive https://github.com/theos/theos.git $THEOS
4. 新建tweak項(xiàng)目
  • cd到一個(gè)存放項(xiàng)目代碼的文件夾鸟款,例如桌面:
$ cd ~/Desktop
$ nic.pl
  • 選擇模板[10.]iphone/tweak,如下圖所示:


    image.png
  • 填寫(xiě)項(xiàng)目信息

    • Project Name: 項(xiàng)目名稱茂卦,可以隨便寫(xiě)何什,例如:tweak_wechat
    • Package Name: 項(xiàng)目ID,可以隨便寫(xiě)等龙,例如:com.sp.wechat
    • Author/Maintainer Name: 作者处渣,直接敲回車,默認(rèn)就是Mac上的當(dāng)前用戶名
    • MobileSubstrate Bundle filter: 需要逆向的App的BundleID而咆,可以通過(guò)Cycript查看霍比,例如:微信的BundleID就是com.tencent.wechat
    • List of applications to terminate upon installcation幕袱,直接敲回車暴备,默認(rèn)即可
    • 之后就會(huì)生成一個(gè)文件夾,里面包含:control们豌、Makefile涯捻、Tweak.x浅妆、xxx.plist等文件,這些文件的具體作用障癌,后續(xù)會(huì)說(shuō)到
5. 編輯Makefile文件
  • 在Makefile中加入環(huán)境變量凌外,寫(xiě)清楚通過(guò)哪個(gè)IP和端口訪問(wèn)手機(jī),如下所示涛浙,由于會(huì)把接口轉(zhuǎn)發(fā)到本地的10010端口康辑,所以這里可以這樣寫(xiě):

    • THOS_DEVICE_IP 手機(jī)IP
    • THOS_DEVICE_PORT 要訪問(wèn)的端口號(hào)
    export THEOS_DEVICE_IP=127.0.0.1 
    export THEOS_DEVICE_PORT=10010
    
  • 如果不想每個(gè)項(xiàng)目的Makefile都編寫(xiě)IP和端口環(huán)境變量,也可以添加到用戶配置文件中轿亮,如下所示疮薇,編輯完成后,記得使用source ~/.bash_profile命令我注,讓配置生效

$ vim ~/.bash_profile

export THEOS=~/theos
export PATH=$THEOS/bin:$PATH 
export THEOS_DEVICE_IP=127.0.0.1 
export THEOS_DEVICE_PORT=10010

$ source ~/.bash_profile
6. 編寫(xiě)逆向代碼
  • 打開(kāi)Tweak.x文件按咒,編寫(xiě)自己的逆向代碼,如下所示但骨,%hook励七、%end屬于Logos語(yǔ)法
%hook FindFriendEntryViewController

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
    return %orig + 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    
    NSInteger totalSection = [self numberOfSectionsInTableView: tableView];

    if (section == totalSection - 1){
        return 2;
    }else{
        return %orig;
    }
}
%end
7. 編譯-打包-安裝
  • 編譯成dylib動(dòng)態(tài)庫(kù)
$ make
  • 把動(dòng)態(tài)庫(kù)打包成deb文件
$ make package
  • 安裝到手機(jī)
$ make install
8. 配置好Theos后,Theos的使用方法

配置好Theos后奔缠,Theos的使用只需三步

  • 在命令行中輸入nic.pl掠抬,選擇tweak模板,填寫(xiě)項(xiàng)目信息

  • 在Tweak.x中編寫(xiě)逆向代碼

  • 在命令行中輸入make編譯->make package打包->make install安裝到手機(jī)

  • 建議把Makefile中的IP和端口環(huán)境變量添坊,都加到~/bash_profile中剿另,這樣以后新建項(xiàng)目,都不用配置環(huán)境變量了

四贬蛙、配置Theos過(guò)程中可能遇到的問(wèn)題
  1. make package的錯(cuò)誤雨女,如下所示:


    make package的錯(cuò)誤.png

解決辦法:是因?yàn)榇虬鼔嚎s方式有問(wèn)題,改成gzip壓縮就可以

  • 修改dm.pl文件阳准,用#號(hào)注釋掉下面兩句:
$ vim $THEOS/vendor/dm.pl/dm.pl
#use IO::Compress::Lzma;
#use IO::Compress::Xz;
  • 修改deb.mk文件第6行的壓縮方式為gzip氛堕,如下所示:
$ vim $THEOS/makefiles/package/deb.mk 
_THEOS_PLATFORM_DPKG_DEB_COMPRESSION ?= gzip
    1. make出現(xiàn)錯(cuò)誤,如下所示:


      image.png

解決辦法:是因?yàn)榘惭b了多個(gè)Xcode野蝇,導(dǎo)致的路徑錯(cuò)誤讼稚,需要指定一下Xcode

 $ sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer/
    1. make出現(xiàn)以下錯(cuò)誤:


      image.png

解決辦法:因?yàn)橹耙呀?jīng)編譯過(guò),有緩存導(dǎo)致的绕沈,clean一下即可

$ make clean
五锐想、Logos語(yǔ)法
    1. 寫(xiě)逆向代碼時(shí)常用的Logos語(yǔ)法
    • %hook、%end:hook一個(gè)類的開(kāi)始和結(jié)束乍狐,中間包括的所有方法赠摇,默認(rèn)是hook狀態(tài)

    • %log:在方法中,加入此關(guān)鍵詞,就會(huì)自動(dòng)打印方法名藕帜、方法參數(shù)烫罩,會(huì)在系統(tǒng)日志中顯示出來(lái),在Xcode->Window->Devices And Simulators->Open Console->選擇自己的手機(jī)洽故,即可查看贝攒,如下圖所示:

      image.png

      image.png

    • HBDebugLog:跟NSLog類似,一般用來(lái)輸出返回值的时甚,會(huì)自動(dòng)生成隘弊,不用管

    • %new:添加一個(gè)新的方法,寫(xiě)在某個(gè)方法的上面荒适,代表這個(gè)方法是新增的长捧,而不是hook的

    • %c(className):生成一個(gè)Class對(duì)象,例如:%c(NSObject)吻贿,就相當(dāng)于NSClassFromString()串结、object_getClass()

    • %org:方法原來(lái)的代碼邏輯,在方法里加上此關(guān)鍵詞舅列,就代表實(shí)現(xiàn)了此方法的原來(lái)的代碼邏輯

    • %ctor:構(gòu)造方法肌割,加載咱們的動(dòng)態(tài)庫(kù)時(shí)自動(dòng)調(diào)用

    • %dtor:析構(gòu)方法,在程序退出時(shí)自動(dòng)調(diào)用

    • logify.pl:可以將一個(gè)頭文件快速轉(zhuǎn)換成已經(jīng)包含打印信息的xm文件帐要,命令如下:

    logify.pl xx.h > xx.xm
    
    1. 使用logify.pl生成的xm文件把敞,很多時(shí)候編譯是通不過(guò)的,需要進(jìn)行以下處理:
    • 刪掉__weak
    • 刪掉inout
    • 刪掉協(xié)議或者聲明協(xié)議榨惠,例如:@protocol BaseMsgContentDelgate;
    • 聲明類名奋早,例如:@class MMRichTextCoverView;
    • 刪掉以.開(kāi)頭的方法,例如:- (void).cxx_destruct { %log; %orig; }
    • HBLogDebug(@" = 0x%x", (unsigned int)r);刪除或者是替換為HBLogDebug(@" = 0x%@", r);
    • 當(dāng)參數(shù)里面帶上協(xié)議時(shí)赠橙,需要把協(xié)議刪掉耽装,例如:
      - (void)setM_backgroundThreadDelegate:( id <BaseMsgContentInBackgroundThreadDelgate> )m_backgroundThreadDelegate { %log; %orig; },把<BaseMsgContentInBackgroundThreadDelgate>刪掉即可期揪。
六掉奄、tweak工程的一些技巧
    1. 多文件的時(shí)候,建議新建一個(gè)src文件夾凤薛,用來(lái)存放xm代碼姓建,這樣做的話,就需要在Makefile文件中缤苫,修改WeChatTest_FILES = $(wildcard src/*.xm)速兔,把參數(shù)改成通配符;如果有多個(gè)類型的文件活玲,就繼續(xù)追加即可涣狗,例如:
      WeChatTest_FILES = $(wildcard src/*.xm) $(wildcard src/*.x)
    1. 如果工程里面需要額外的圖片的話帜矾,可以把圖片放在項(xiàng)目的layout文件夾中,layout相當(dāng)于手機(jī)的Device根路徑屑柔;當(dāng)把圖片放在/layout/Library/Caches/項(xiàng)目名下面時(shí),插件安裝到手機(jī)后珍剑,圖片會(huì)自動(dòng)存放在手機(jī)的/Device/Library/Caches/項(xiàng)目名路徑中
七掸宛、給微信增加自動(dòng)搶紅包功能
    1. 首先分析需求,在微信的發(fā)現(xiàn)界面招拙,增加兩行UI唧瘾,自動(dòng)搶紅包和退出微信,并實(shí)現(xiàn)功能(這里先繪制UI别凤,功能實(shí)現(xiàn)在動(dòng)態(tài)調(diào)試?yán)锩嬷v)
    1. 使用Reveal觀察微信的發(fā)現(xiàn)界面饰序,拿到發(fā)現(xiàn)界面的類名FindFriendEntryViewController
    1. 對(duì)微信脫殼,并且用class-dump導(dǎo)出微信的頭文件规哪,找到FindFriendEntryViewController.h文件求豫,認(rèn)真分析,發(fā)現(xiàn)里面實(shí)現(xiàn)了tableView的幾個(gè)代理方法:
      FindFriendEntryViewController文件
    1. nic.pl選擇tweak模板诉稍,填寫(xiě)項(xiàng)目信息創(chuàng)建tweak項(xiàng)目蝠嘉,在Tweak.x中編寫(xiě)自己的逆向代碼,逆向代碼主要還是OC代碼杯巨,部分關(guān)鍵詞用到了Logos語(yǔ)法蚤告,例如:%hook %end代表替換微信中這些方法的實(shí)現(xiàn);%new代表這個(gè)方法是新增的服爷;%org代表這個(gè)方法的原有實(shí)現(xiàn)杜恰。如下所示:
#define SP_Defaults [NSUserDefaults standardUserDefaults]
#define SP_AutoKey @"sp_auto_key"
#define SP_File(path) @"/Library/PreferenceLoader/Preferences/SP_WeChat/" #path

@interface FindFriendEntryViewController

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView;

@end

%hook FindFriendEntryViewController

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
    return %orig + 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    
    NSInteger totalSection = [self numberOfSectionsInTableView: tableView];

    if (section == totalSection - 1){
        return 2;
    }else{
        return %orig;
    }
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    NSInteger totalSection = [self numberOfSectionsInTableView: tableView];

    if ([indexPath section] != totalSection - 1){
        return %orig;
    }

    NSString *cellID = ([indexPath row] == 0) ? @"sp_autoCellID" : @"sp_exitWXID"; 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID];
    if (cell == nil){
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellID];
        cell.backgroundColor = [UIColor whiteColor];
        cell.imageView.image = [UIImage imageWithContentsOfFile:SP_File(skull.png)];
    }
    if ([indexPath row] == 0){
        //搶紅包
        cell.textLabel.text = @"自動(dòng)搶紅包";
        UISwitch *switchView = [[UISwitch alloc] init];
        switchView.on = [SP_Defaults boolForKey:SP_AutoKey];
        cell.accessoryView = switchView;
        [switchView addTarget:self action:@selector(sp_autoRed:) forControlEvents:UIControlEventValueChanged];

    }else if ([indexPath row] == 1){
        //退出微信
        cell.textLabel.text = @"退出微信";
    }
    return cell;
}

- (double)tableView:(id)tableView heightForRowAtIndexPath:(id)indexPath{
    if ([indexPath section] != [self numberOfSectionsInTableView:tableView] - 1) {
        return %orig;
    }

    return 56;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    if ([indexPath section] != [self numberOfSectionsInTableView:tableView] - 1) {
        %orig;
        return;
    }

    [tableView deselectRowAtIndexPath:indexPath animated:YES];
    if ([indexPath row] == 0){
        //自動(dòng)搶紅包
    }else if ([indexPath row] == 1){
        // 終止進(jìn)程
        exit(0);
        // abort();
    }
}

%new
- (void)sp_autoRed:(UISwitch *)switchView{
    [SP_Defaults setBool:switchView.on forKey:SP_AutoKey];
    [SP_Defaults synchronize];
}
    1. 編譯、打包仍源、安裝到手機(jī)心褐,在手機(jī)的微信中,查看修改的成果
$ cd到tweak項(xiàng)目的目錄下
$ make clean && make page debug=0 && make install
    1. 如果想卸載插件笼踩,可以在Cydia的【已安裝】里找到咱們寫(xiě)的插件檬寂,點(diǎn)擊卸載即可。(或者在手機(jī)的Device/Libiary/MobileSubstrate/DynamicLibiaries中找到咱們自己寫(xiě)的 plist戳表、dylib文件桶至,刪除即可)
八、逆向工程總結(jié)
    1. 使用Theos的tweak模板匾旭,創(chuàng)建逆向工程之前镣屹,我們需要先對(duì)要逆向的App,進(jìn)行界面分析和代碼分析价涝,找到類名女蜈、方法名、成員變量等信息后,在用Logos語(yǔ)法和OC語(yǔ)法編寫(xiě)我們的逆向代碼
    1. 界面分析伪窖,建議RevealCycripy一起配合使用逸寓,用Reveal查看界面,找到內(nèi)存地址覆山,然后用Cycripy做進(jìn)一步的分析竹伸,例如:找到某個(gè)視圖的下一個(gè)響應(yīng)者,#0x16166e2b0.nextResponder
    1. 代碼分析簇宽,脫殼后使用class-dump工具導(dǎo)出頭文件勋篓,用界面分析得到的類名,找到這個(gè)類的方法名魏割、成員變量等信息譬嚣,然后用我們開(kāi)發(fā)時(shí)一些經(jīng)驗(yàn)進(jìn)行分析
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市钞它,隨后出現(xiàn)的幾起案子拜银,更是在濱河造成了極大的恐慌,老刑警劉巖遭垛,帶你破解...
    沈念sama閱讀 206,968評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件盐股,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡耻卡,警方通過(guò)查閱死者的電腦和手機(jī)疯汁,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)卵酪,“玉大人幌蚊,你說(shuō)我怎么就攤上這事±?ǎ” “怎么了溢豆?”我有些...
    開(kāi)封第一講書(shū)人閱讀 153,220評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)瘸羡。 經(jīng)常有香客問(wèn)我漩仙,道長(zhǎng),這世上最難降的妖魔是什么犹赖? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,416評(píng)論 1 279
  • 正文 為了忘掉前任队他,我火速辦了婚禮,結(jié)果婚禮上峻村,老公的妹妹穿的比我還像新娘麸折。我一直安慰自己,他們只是感情好粘昨,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布垢啼。 她就那樣靜靜地躺著窜锯,像睡著了一般。 火紅的嫁衣襯著肌膚如雪芭析。 梳的紋絲不亂的頭發(fā)上锚扎,一...
    開(kāi)封第一講書(shū)人閱讀 49,144評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音馁启,去河邊找鬼驾孔。 笑死,一個(gè)胖子當(dāng)著我的面吹牛进统,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播浪听,決...
    沈念sama閱讀 38,432評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼螟碎,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了迹栓?” 一聲冷哼從身側(cè)響起掉分,我...
    開(kāi)封第一講書(shū)人閱讀 37,088評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎克伊,沒(méi)想到半個(gè)月后酥郭,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,586評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡愿吹,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,028評(píng)論 2 325
  • 正文 我和宋清朗相戀三年不从,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片犁跪。...
    茶點(diǎn)故事閱讀 38,137評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡椿息,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出坷衍,到底是詐尸還是另有隱情寝优,我是刑警寧澤,帶...
    沈念sama閱讀 33,783評(píng)論 4 324
  • 正文 年R本政府宣布枫耳,位于F島的核電站乏矾,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏迁杨。R本人自食惡果不足惜钻心,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,343評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望铅协。 院中可真熱鬧扔役,春花似錦、人聲如沸警医。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,333評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至侈玄,卻和暖如春婉刀,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背序仙。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,559評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工突颊, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人潘悼。 一個(gè)月前我還...
    沈念sama閱讀 45,595評(píng)論 2 355
  • 正文 我出身青樓律秃,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親治唤。 傳聞我的和親對(duì)象是個(gè)殘疾皇子棒动,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,901評(píng)論 2 345

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