非越獄theos的Tweak創(chuàng)建的dylib安裝到iOS設備

非越獄環(huán)境下iOS版WeChat 逆向研究示例,dylibz(動態(tài)庫)注入、應用重簽名

基本原理

通過app啟動時調(diào)用我們注入的dylib,進行app hook,最終能夠執(zhí)行我們注入的dylib。

應用砸殼

App store里的應用都是加密的,沒辦法直接拿來使用,所以在做之前都需要一個砸殼的過程,而砸殼使用的工具是dumpdecrypted, 原理就是讓app預先加載一個dumpdecrypted.dylib,然后在程序運行時,將代碼動態(tài)解密,最后在內(nèi)存中dump出來整個程序。當然砸殼是需要在越獄環(huán)境下進行的,所以我直接從PP助手等各種xx助手里面下載越獄應用(不是正版應用),也就是所謂的脫過殼的應用。

注意: 有好多應用是只有部分架構(gòu)被解密,這時需要檢查從xx助手下載的越獄應用是否已解密,還有就是Watch App以及一些擴展依然加密了,所以最好還是確認一下,否則的話,就算hook成功,簽名成功,安裝成功,app還是會閃退。

查看越獄應用是否已經(jīng)解密的方式,以WeChat-6.5.18為例:
1.將xx助手中下載的WeChat-6.5.18.ipa包解壓,會得到一個相同的名稱的文件夾,然后進入該文件夾中->Payload->WeChat,右鍵WeChat->顯示包內(nèi)容,進入app包中
2.打開終端,并進入剛才解壓的WeChat-6.5.18文件夾中Payload文件夾中,執(zhí)行cd命令:
cd /Users/mofeini/Desktop/weChat/WeChat-6.5.18/Payload
3.通過終端,找到應用對應的二進制文件,查看該app包含哪些架構(gòu), 執(zhí)行file命令:
file WeChat.app/WeChat
結(jié)果:

WeChat.app/WeChat: Mach-O universal binary with 2 architectures: [arm_v7: Mach-O executable arm_v7] [arm64]
WeChat.app/WeChat (for architecture armv7):    Mach-O executable arm_v7
WeChat.app/WeChat (for architecture arm64):    Mach-O 64-bit executable arm64

從結(jié)果中可以看到WeChat.app包含兩個構(gòu)架: arm_v7arm64,關(guān)于架構(gòu)和設備之間的關(guān)系,可以查看iossupportmatrix。理論上只要把最老的架構(gòu)解密即可,因為新的cpu會兼容老的架構(gòu)。

  1. 通過終端命令otool 輸出app 的load commands,然后查看獲取的cryptid這個對應的value來判斷app是否被加密,1代表加密了,0代表解密,執(zhí)行otool -l (注意不是1哦)命令;
    otool -l WeChat.app/WeChat | grep -B 2 crypt
    結(jié)果:
         cmd LC_ENCRYPTION_INFO
     cmdsize 20
    cryptoff 16384
   cryptsize 48906240
        cryptid 0
--
         cmd LC_ENCRYPTION_INFO_64
      cmdsize 24
     cryptoff 16384
    cryptsize 52396032
        cryptid 0

從結(jié)果中可以看到cryptid對應的value都是0,可以確定此app已經(jīng)被解密了,第一個對應的是較老的armv7架構(gòu),后者則是arm64架構(gòu)

由于微信的項目中包含多個target: 包含WeChatWatchNative和WeChatShareExtensionNew。所以我們還需要按照上面的步驟,確認以下二進制文件(其中有兩個是Watch中的,一個是微信分享擴展):

WeChat.app/Watch/WeChatWatchNative.app/WeChatWatchNative
WeChat.app/Watch/WeChatWatchNative.app/PlugIns/WeChatWatchNativeExtension.appex/WeChatWatchNativeExtension
WeChat.app/PlugIns/WeChatShareExtensionNew.appex/WeChatShareExtensionNew

結(jié)果:
WeChatWatchNative 未獲取到信息
WeChatWatchNativeExtension cryptid 1
WeChatShareExtensionNew cryptid 0
注意: WeChatWatch還是加密的,會影響到下面步驟中的重簽名,最簡單的辦法就是,對對應ipa包解壓后,將里面的Watch文件夾刪除,再進行重新簽名

制作需要注入微信的dylib動態(tài)庫

制作dylib動態(tài)庫的兩種方式: iOSOpenDevtheos
由于iOSOpenDev總是安裝失敗,所以這里使用theos

  • 使用終端命令,安裝配置theos,將其Cloning into '/opt/theos'...
    安裝ldid:brew install dpkg ldid ,在Theos開發(fā)插件中,iOS文件的簽名是使用ldid工具來完成的,也就是說ldid取代了Xcode自帶的Codesign;當出現(xiàn)Updating Homebrew...耐心等待即可;
    配置$THEOS: export THEOS=/opt/theos 等號后面是theos文件所在路徑
    Theos安裝:sudo git clone --recursive https://github.com/theos/theos.git $THEOS,Theos一般是安裝在/opt/目錄下的,Cloning完成后,可cd到/opt目錄下查看;
    Cloning完成Theos后,要修改一下文件的權(quán)限:sudo chown -R $(id -u):$(id -g) /opt/theos
    配置環(huán)境變量: 在終端執(zhí)行open ~/.bash_profile打開此文件,在后面加入:
export PATH=/opt/theos/bin:$PATH
export THEOS=/opt/theos

出現(xiàn)的問題: 當執(zhí)行brew install dpkg ldid提示

/usr/local/Homebrew/Library/Homebrew/brew.rb:12:in `<main>': Homebrew must be run under Ruby 2.3! (RuntimeError)

解決:重新執(zhí)行brew install dpkg ldid

創(chuàng)建tweak

使用theos來創(chuàng)建工程,創(chuàng)建工程也是比較簡單的,就是調(diào)用我們theos目錄中bin下的nic.pl命令。在執(zhí)行nic.pl命令后,會讓你選擇新建工程的模板,目前theos中內(nèi)置的是12套模板。當然我們此處創(chuàng)建的是tweak類型的工程,所有我們選擇11

  • 新建工程,執(zhí)行終端命令:
    nic.pl
    然后,終端會顯示12套模板,并提示Choose a Template (required):,我們輸入11回車
    接下來會提示項目名Project Name (required):,輸入項目名wechatplugin,回車
    該 deb 包的名字:Package Name [com.yourcompany.wechatplugin]: 輸入com.ossey.WeChatPlugin回車
    作者Author/Maintainer Name [Swae]: 輸入你的名
    tweak 作用對象的 bundle identifier(比如微信為com.tencent.xin):[iphone/tweak] MobileSubstrate Bundle filter [com.apple.springboard]: 輸入com.tencent.xin回車
    tweak 安裝完成后需要重啟的應用名[iphone/tweak] List of applications to terminate upon installation (space-separated, '-' for none) [SpringBoard],(比如微信為WeChat)

tweak項目中文件介紹

  • 安裝完成后進入cd wechatplugin/, 執(zhí)行ls -l, 可以看到里面有四個文件:
    完成后會看到四個文件(make 后將生成 .theos 、obj 文件夾).
    Makefile WeChatPlugin.plist Tweak.xm control

  • 對Makefile文件進行修改
    Makefile : 工程用到的文件、框架、庫等信息。
    該文件過于簡單,還需要添加一些信息。如
    指定處理器架構(gòu)ARCHS = armv7 arm64
    指定SDK版本TARGET = iphone:latest:8.0
    導入所需的framework等等。
    修改后的Makefile文件:

ARCHS = armv7 arm64
TARGET = iphone:latest:8.0

include $(THEOS)/makefiles/common.mk

TWEAK_NAME = WeChatPlugin
WeChatPlugin_FILES = Tweak.xm

include $(THEOS_MAKE_PATH)/tweak.mk

after-install::
    install.exec "killall -9 WeChat"

  • WeChatPlugin.plist: 該文件中的 Bundles : 指定 bundle 為 tweak 的作用對象。也可添加多個 bundle, 指定多個為 tweak 作用對象。

  • control: 該 tweak 所需的基本信息

  • Tweak.xm: 主要是用來編寫hook代碼,它支持Logos和c/c++,可以讓我們不用去寫一些 runtime 方法
    .x 文件支持Logos語法,.xm 文件支持Logos和C/C++語法

Logos 常用語法:
%hook: 指定需要hook的類,以%end結(jié)尾
%orig%hook內(nèi)部使用,執(zhí)行hook住方法的原代碼
%new: 在%hook內(nèi)部使用,給class添加新方法,與class_addMethod相同; 在Category中添加方法的區(qū)別: Category為編譯時添加,class_addMethod為d動態(tài)添加
warm: 添加的方法需要在@interface中聲明
%c:獲取一個類,等同于objc_getClass、NSClassFromString

定制Tweak.xm

  • 以微信中的設置頁面為例: NewSettingViewController是微信的設置頁面,我們hook它的viewDidAppear:方法
%hook NewSettingViewController

- (void)viewDidAppear:(BOOL)animated {
    %orig;
    [self helloWorld];
}

%new
- (void)helloWorld {
    UIAlertController *alc = [UIAlertController alertControllerWithTitle:@"hello world" message:nil preferredStyle:UIAlertControllerStyleActionSheet];
    [alc addAction:[UIAlertAction actionWithTitle:@"ok" style:UIAlertActionStyleDefault handler:NULL]];
    [alc addAction:[UIAlertAction actionWithTitle:@"cancel" style:UIAlertActionStyleCancel handler:NULL]];
    [self presentViewController:alc animated:YES completion:NULL];
}

%end
  • 編寫代碼完成后,使用make package命令對其進行編譯,注意:執(zhí)行命令前先cd到項目文件夾
    如果是在之前編寫的基礎上行修改,則需要重新編譯, 需要先使用make clean,清理make, make package生成的文件
    執(zhí)行完成后,會在項目多兩個文件夾:.theosobj,那么在.theos->obj->debug中有一個WeChatPlugin.dylib就是我們生成的dylib動態(tài)庫;

修改生成的.dylib動態(tài)庫中的依賴

  • 通過 otool -L命令查看生成的.dylib文件
    結(jié)果中的一段/Library/Frameworks/CydiaSubstrate.framework/CydiaSubstrate (offset 24)
    可以看到這里還有對CydiaSubstrate的依賴,這是不行的 , 這個是theos在越獄機上特有的, 在非越獄機上需要更改此依賴
  • 修改依賴,將libsubstrate.dylib文件(該文件應該在/opt/thoes/lib/目錄下),拷貝到與你生成的的.dylib一個目錄下,通過下面的指令修改依賴,
    cd /Users/mofeini/Desktop/weChat/Project/wechatplugin/.theos/obj/debug
    install_name_tool -change /Library/Frameworks/CydiaSubstrate.framework/CydiaSubstrate @loader_path/libsubstrate.dylib WeChatPlugin.dylib
    然后重新查看WeChatPlugin.dylib,會發(fā)現(xiàn)依賴已經(jīng)修改成@loader_path/libsubstrate.dylib (offset 24)

重新簽名自制的.dylib 和libsubstrate.dylib(很重要)

我們需要把生成的dylib和libsubstrate.dylib文件copy到WeChat.app中,然后用codesign開始簽名

codesign -f -s 'iPhone Developer: Xiaoyuan Yang (29H47J82NP)' (自己的證書名)

添加可執(zhí)行文件的依賴動態(tài)注入

此處用到是insert_dylib,先從gitHUb下載insert_dylib,編譯后將 insert_dylib 放到/usr/local/bin目錄中(不放到此目錄中需要使用./insert_dylib,放在目錄中后只需要使用insert_dylib);
再將自制的dylib和libsubstrate.dylib拷貝到WeChat.app包中,執(zhí)行以下命令:

cd /Users/mofeini/Desktop/weChat/WeChat-6.5.18/Payload/WeChat.app/
insert_dylib @executable_path/WeChatPlugin.dylib WeChat

以下為執(zhí)行步驟

localhost:debug apple$ insert_dylib @executable_path/wechatplugin.dylib /Users/mofeini/Desktop/weChat/WeChat.app/WeChat
Binary is a fat binary with 2 archs.
LC_CODE_SIGNATURE load command found. Remove it? [y/n] n
LC_CODE_SIGNATURE load command found. Remove it? [y/n] n
Added LC_LOAD_DYLIB to all archs in /Users/mofeini/Desktop/weChat/WeChat.app/WeChat_patched

會生成一個WeChat_patched 這個就是修改了依賴關(guān)系的二進制文件,

注意替換

注意: 別忘了之前將 自制的.dylib libsubstrate.dylib 拷貝進WeChat.app
如果WeChat_patched在WeChat.app中,還要將WeChat_patched拷貝進WeChat.app中 替換原來的WeChat, 把WeChat_patched的名字改回來WeChat

應用重簽名

將脫殼后的app進行重簽名,我使用的是上面步驟中從pp助手下載的越獄版本的微信,如果使用加密的App重簽名成功安到設備上也會閃退。
應用重簽名的方法,我使用了ios-app-signer

以下是一些錯誤解決

使用以下命令編譯時候

make package

第一次會報以下錯誤

> Making stage for tweak ioswechat…
dpkg-deb: error: obsolete compression type 'lzma'; use xz instead

Type dpkg-deb --help for help about manipulating *.deb files;
Type dpkg --help for help about installing and deinstalling packages.
make: *** [internal-package] Error 2

查找了一些資料后發(fā)現(xiàn),這個錯誤是dpkg引起的,隨著版本的升級,打包格式發(fā)生了變化

dpkg-deb: error: obsolete compression type 'lzma'; use xz instead

解決方案是按以下路徑找到該文件修改其內(nèi)容

/opt/theos/makefiles/package/deb.mk

找到第六行

_THEOS_PLATFORM_DPKG_DEB_COMPRESSION ?= lzma

將其改為

_THEOS_PLATFORM_DPKG_DEB_COMPRESSION ?= xz
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容