iOS逆向工程——非越獄調試

其實iOS的逆向分析業界已經十分成熟了,網上也有許多有趣的嘗試(一步一步實現iOS微信自動搶紅包(非越獄)。本文著重于如何在非越獄機器上進行調試,出于學習及總結的目的,記錄于此。

本文以破解游戲夢幻西游為例,逐步講解整個調試流程。

->工具

完成整個過程需要準備以下幾個必要工具:

1、iOSOpenDev,用于允許在Xcode上創建Dylib工程;

2、yololib,用于為二進制文件注入Dylib;

3、class-dump,用于導出 decrypted 的二進制文件的頭文件;

4、CaptainHook,這是一個頭文件,引入工程后,我們可以通過宏快速地 Hook 任意方法;

5、一臺越獄機器,安裝 cycriptopenssh

非必要工具:

1、dumpdecrypted,用于為AppStore包的二進制文件破殼;

注:dumpdecrypted 之所以非必要,是因為一般情況下可以從越獄市場下到已經 decrypted 后的app!如果下到的包不是 decrypted 的,請自行百度 decrypted。

->定位

首先我們要解決的問題是,在哪里注入我們的調試入口。這個定位過程必須要有越獄機器的配合。我們會通過在越獄機器(已安裝應用)上運行 cycript 確定應用視圖層級。

在MAC命令行運行:

    ->ssh root@192.168.10.11 #你的越獄手機的IP,默認越獄機器密碼為 alpine->ps -e #關掉其它應用,從進程列表中找到應用對應的進程號,一般路徑帶了一串MD5值的就是了->cycript -p 2231 #進行cycript

當 cycript 運行后,就可以通過命令行運行objc代碼:

    cy#[[UIApplication sharedApplication].keyWindow recursiveDescription]

這里用到了私有方法 recursiveDescription ,會返回整個層級的描述。

<UIWindow: 0x15cd9de50; frame = (0 0; 667 375); autoresize = W+H; gestureRecognizers = <NSArray: 0x15e08c260>; layer = <UIWindowLayer: 0x15cd79f50>>| <CCEAGLView: 0x15e08d2a0; frame = (0 0; 667 375); autoresize = W+H; gestureRecognizers = <NSArray: 0x15cdc2290>; layer = <CAEAGLLayer: 0x15e08c8f0>>

到這,我們定位了主View對應的類,現在我們需要寫點代碼Hook這個類。

->編寫Dylib

通過 iOSOpenDev 創建一個Dylib工程,把主工程文件由.m 改為.mm,引入頭文件 CaptainHook.h,把主工程文件.mm替換為以下內容:

#import "CaptainHook.h"__attribute__((constructor)) static void entry() {[[BQInjectToolHelper sharedInstance] injectToolsToMY];
}static BQInjectToolsNavigationController *sharedMainNav = nil;CHDeclareClass(CCEAGLView);CHMethod(7, id, CCEAGLView, initWithFrame, CGRect, frame, pixelFormat, id, arg2, depthFormat, unsigned int, arg3, preserveBackbuffer, _Bool, arg4, sharegroup, id, arg5, multiSampling, _Bool, arg6, numberOfSamples, unsigned int, arg7)
{//調用原來的AsyncOnAddMsg:MsgWrap:方法id v = CHSuper(7, CCEAGLView, initWithFrame, frame, pixelFormat, arg2, depthFormat, arg3, preserveBackbuffer, arg4, sharegroup, arg5, multiSampling, arg6, numberOfSamples, arg7);if (sharedMainNav == nil) {BQInjectToolsMainViewController *mainVc = [[BQInjectToolsMainViewController alloc] init];BQInjectToolsNavigationController *mainNav = [[BQInjectToolsNavigationController alloc] initWithRootViewController:mainVc];sharedMainNav = mainNav;}[sharedMainNav injectToSuperView:v];BQLog(@"BQ Inject initWithFrame:pixelFormat:depthFormat:preserveBackbuffer:sharegroup:multiSampling:numberOfSamples: success!");return v;
}@implementation BQInjectToolHelper+ (BQInjectToolHelper *)sharedInstance
{static BQInjectToolHelper *sharedInsatnce = nil;static dispatch_once_t onceToken;dispatch_once(&onceToken, ^{sharedInsatnce = [[BQInjectToolHelper alloc] init];});return sharedInsatnce;
}- (void)injectToolsToMY
{CHLoadLateClass(CCEAGLView);CHClassHook(0, CCEAGLView, init);CHClassHook(1, CCEAGLView, initWithFrame);CHClassHook(2, CCEAGLView, initWithFrame, pixelFormat);CHClassHook(3, CCEAGLView, initWithFrame, pixelFormat, depthFormat);CHClassHook(7, CCEAGLView, initWithFrame, pixelFormat, depthFormat, preserveBackbuffer, sharegroup, multiSampling, numberOfSamples);BQLog(@"BQ Injected!");
}@end@implementation BQInjectToolsNavigationController- (void)injectToSuperView:(UIView *)view
{if (view == nil || self.view.superview == view) return;[self.view removeFromSuperview];self.view.frame = CGRectMake((view.frame.size.width - _injectToolsContentSize.width) / 2, -_injectToolsContentSize.height, _injectToolsContentSize.width, _injectToolsContentSize.height);[view addSubview:self.view];[self addGestureRecognizerToView:view];
}@end

這里做了幾件事:

1、申明了CCEAGLView 類,并Hook了方法 -(id)initWithFrame:(struct CGRect)arg1 pixelFormat:(id)arg2 depthFormat:(unsigned int)arg3 preserveBackbuffer:(_Bool)arg4 sharegroup:(id)arg5 multiSampling:(_Bool)arg6 numberOfSamples:(unsigned int)arg7 方法;

2、在補始化CCEAGLView 時,為該View添加子View以及Pan手勢響應;

后續我們就可以通過手勢,呼出我們注入的頁面了。

這里有個小技巧,在cycript下,輸入 [[CCEAGLView alloc] init ,并按兩下 tab 鍵,cycript會為你聯想方法,你可以把方法列表里的方法全Hook了(事實上我就是這么做的)

編寫完代碼后運行,這里注意保證生成的dylib的目標架構包含(armv7&arm64)。

->注入

在命令行運行:

    ->yololib MY.app/MY libJDYTest.dylib #注意文件的相對路徑,dylib文件不能帶前置目錄

如果你的應用包含多個架構支持,那么yololib會分別為你的每一個架構注入dylib。運行后如下:

    Reading binary: libJDYTest.dylib2016-06-08 21:26:50.944 yololib[47766:1342053] FAT binary!2016-06-08 21:26:50.944 yololib[47766:1342053] Injecting to arch 92016-06-08 21:26:50.944 yololib[47766:1342053] Patching mach_header..2016-06-08 21:26:50.945 yololib[47766:1342053] Attaching dylib..2016-06-08 21:26:50.945 yololib[47766:1342053] Injecting to arch 112016-06-08 21:26:50.945 yololib[47766:1342053] Patching mach_header..2016-06-08 21:26:50.945 yololib[47766:1342053] Attaching dylib..2016-06-08 21:26:50.945 yololib[47766:1342053] Injecting to arch 02016-06-08 21:26:50.945 yololib[47766:1342053] 64bit arch wow2016-06-08 21:26:50.946 yololib[47766:1342053] dylib size wow 562016-06-08 21:26:50.946 yololib[47766:1342053] mach.ncmds 232016-06-08 21:26:50.946 yololib[47766:1342053] mach.ncmds 242016-06-08 21:26:50.946 yololib[47766:1342053] Patching mach_header..2016-06-08 21:26:50.946 yololib[47766:1342053] Attaching dylib..2016-06-08 21:26:50.946 yololib[47766:1342053] size 542016-06-08 21:26:50.946 yololib[47766:1342053] complete!

看到上面的提示就表示注入完成了。注入的地址是 @executable_path/libJDYTest.dylib ,因此最終要把dylib放到和app可執行文件相同的目錄下。

->重簽名

重簽名需要以下三個東西:

1、libJDYTest.dylib,這個是我們已經注入到二進制的動態庫;

2、配對的證書和.mobileprovision文件;

3、Entitlements.plist文件;

1我們已經生成。2的獲取方式如下:

1、從 https://developer.apple.com 申請開發者證書,證書名如下iPhone Developer: YourName (YYYYYYYYY),記下證書名YYYYYYYYY;

[2]、創建一個新應用工程,在工程 Build-Setting 中,把 Code signing 的Profile和證書指定為開發者證書;

[3]、運行起新工程,在Product里點app右鍵,找到app的目錄,在app目錄下有.mobileprovision文件(第三步其實可以不必做,這么做是為了保險起見);

Entitlement.pist 是用于申明應用權限的文件,會在簽名中使用到,3的獲取方式如下:

1、在 https://developer.apple.com 查找到證書的TeamID;

2、按如下模板生成 Entitlement.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>application-identifier</key><string>XXXXXXXXXX.as.your.wish.name</string><key>com.apple.developer.team-identifier</key><string>XXXXXXXXXX</string><key>get-task-allow</key><true/><key>keychain-access-groups</key><array><string>XXXXXXXXXX.as.your.wish.name</string></array>
</dict>
</plist>

以上文件準備好后,運行如下命令:

    ->cp libJDYTest.dylib MY.app/->cp embedded.mobileprovision MY.app/->rm -rf MY.app/_CodeSignature  # 如果你的應用有ext或都watch,需要對Watch和ext中的_CodeSignature同樣刪了,或者干脆把Watch和ext刪了->codesign -f -s YYYYYYYYY MY.app/libJDYTest.dylib->codesign -f -s YYYYYYYYY --entitlements Entitlements.plist MY.app->xcrun -sdk iphoneos PackageApplication -v MY.app -o $(pwd)/MYFinish.ipa

運行完后,MYFinish.ipa就是我們的最終成果,用itools裝到非越獄的iphone上吧。

這里簽名需要注意以下兩點:

1、簽名的開發者證書,在鑰匙串中的 屬性->信任->使用此證書時 ,必須要選擇<系統默認>否則簽名不成功;

2、Apple Worldwide Developer Relations CA - G2證書同上;

驗證是否正確答名成功使用以下命令:

    ->codesign -vvvvv MYFinish.app/libJDYTest.dylib MYFinish.app/libJDYTest.dylib: valid on diskMYFinish.app/libJDYTest.dylib: satisfies its Designated Requirement

->調試

MYFinish.ipa 安裝好后,后續重復以上步驟就可以在自己的面板上開發功能了。當然我們可以把上面的操作寫成腳本,并保存為 fastPack.sh,方便快速的簽名和打包,代碼如下。

## 1、move yololib to /usr/local/bin/ by your self;
## 2、copy app dylib mobileprovision plist to the same path with this shell;
## 3、the all name will not support any space;
##
##                                                                 ——Zhiqiang.bzq
##                                                                    2016.06.04## Functions ##
function makeFinishName() {# appname=$1# name=${appname%.*}# ext=${appname##*.}# finishname="${name}Finish.$ext"echo $1;
}function checkArgument() {if [ $# != 5 ]; thenecho "use like this : $0 appname.app libname.dylib embedded.mobileprovision entitlement.plist cername"exit 1fiappname=$1libname=$2profile=$3entitlement=$4echo "checking arguments..."if [ ! -d $appname ]; thenecho "app $appname no exist"exit 2fiif [ ! -f $libname ]; thenecho "dylib $libname no exist"exit 3fiif [ ! -f $profile ]; thenecho "profile $profile no exist"exit 4fiif [ ! -f $entitlement ]; thenecho "entitlement $entitlement no exist"exit 5fi
}function doCopy() {echo "copying file..."finishname=$(makeFinishName $1)# if [ -d $finishname ]; then#     rm -rf $finishname# fi# cp -rf $1 $finishnamecp $2 "${finishname}/"cp $3 "${finishname}/"
}function doInjectAtPath() {echo "injecting..."finishname=$(makeFinishName $1)name=${1%.*}yololib "${finishname}/${name}" "$2"
}function findExtFilesAtPath () {ext=$1path=$2result=$(find $2/. -name "*.$1")echo $result
}function removeCodeSignAtPath () {rm -rf "$1/_CodeSignature"
}function doCodeSign() {echo "code signning..."finishname=$(makeFinishName $1)removeCodeSignAtPath "${finishname}/_CodeSignature"# find appex extensionappeses=$(findExtFilesAtPath "appex" "${finishname}/")for appex in $appeses; doremoveCodeSignAtPath $appexcodesign -f -s $5 $appexdone# for sub appapps=$(findExtFilesAtPath "app" "${finishname}/")for app in $apps; doremoveCodeSignAtPath $appcodesign -f -s $5 $appdone# resign dylibdylibs=$(findExtFilesAtPath "dylib" "${finishname}/")for dylib in $dylibs; docodesign -f -s $5 $dylibdone# sign the whole app by entitlementcodesign -f -s $5 --entitlements $4 $finishname
}function doGenerateIPA() {echo "packing ipa..."finishname=$(makeFinishName $1)name=${finishname%.*}path=$(pwd)xcrun -sdk iphoneos PackageApplication -v $finishname -o ${path}/${name}.ipa
}function main() {checkArgument $*doCopy $*doInjectAtPath $*doCodeSign $*# doGenerateIPA $*echo "done!"
}## Script ##
main $*

但這樣遠遠不夠,至少無法快速的進行斷點調試。打開我們之前為了獲取.mobileprofile文件創建的工程,添加新的Target,并改為MY(和目標可執行文件名相同即可)。

在MY的Build Phases中添加Run Script,Run Script添加如下腳本:

    lib_path="${BUILT_PRODUCTS_DIR}/lib${TARGET_NAME}.dylib"local_workspace="/Users/zhiqiangbao/Desktop/HackMH"rm -rf "${BUILT_PRODUCTS_DIR}/MY.app"cp -rf "${local_workspace}/MY.app" "${BUILT_PRODUCTS_DIR}/"chmod 777 "${BUILT_PRODUCTS_DIR}/MY.app/MY" #注意,這一步必須cp -rf "${local_workspace}/embedded.mobileprovision" "${BUILT_PRODUCTS_DIR}/"cp -rf "${local_workspace}/Entitlements.plist" "${BUILT_PRODUCTS_DIR}/"cp -rf "${local_workspace}/fastPack.sh" "${BUILT_PRODUCTS_DIR}/"cd $BUILT_PRODUCTS_DIR./fastPack.sh MY.app libJDYTest.dylib embedded.mobileprovision     Entitlements.plist "XXXXXXXX"cd -

這里做了個小trick,在Xcode為新工程生成完app后,我們用自己簽名過的app替換了它。所以最終被安裝上手機的是被我們cracked的應用。

CMD+R運行工程試試,哈哈,大功告成。PS:游戲內的原生Log也可以看哦。

附圖:

ResultDebug
log
HackMY

另附上開發工具dylib的git地址,別忘了改Run Script中的地址信息哦!

夢幻西游開發工具:git@gitlab.alibaba-inc.com:zhiqiang.bzq/MY_Cracked.git

用以下命令初始化:

    ->git submodule init->git submodule update

如有不正之處,歡迎指正~!^ ^

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/284454.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/284454.shtml
英文地址,請注明出處:http://en.pswp.cn/news/284454.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

[轉]2022 Flutter 宣布發布 Windows 正式版

原文鏈接&#xff1a; https://medium.com/flutter/announcing-flutter-for-windows-6979d0d01fed 自從推出 Flutter 以來&#xff0c;我們一直專注于為漂亮的定制應用提供跨平臺解決方案&#xff0c;這些應用被編譯為機器代碼并充分利用設備的底層圖形硬件功能。 今天這一愿景…

電腦經常彈出“不支持的硬件”解決辦法

電腦經常彈出“不支持的硬件”解決辦法。 通過微軟官方查證,這是由于以上處理器需要最新的Windows10系統才會這樣子的,而大多出現該提示的都安裝了Win7或是Win8.1系統。 來至微軟官方的說明 此錯誤出現的原因是各代新處理器要求最新Windows版本以獲得支持。 例如,Windows 1…

使用 Web API 上傳和下載多個文件

原文作者&#xff1a;Jay Krishna Reddy原文鏈接&#xff1a;https://www.c-sharpcorner.com/article/upload-and-download-multiple-files-using-web-api/翻譯&#xff1a;沙漠盡頭的狼&#xff08;谷歌翻譯加持&#xff0c;文中版本使用.NET 6升級&#xff09;---正文開始---…

詳解T-SQL的聯接機制

T-SQL的聯接分三種類型&#xff1a; 交叉聯接 ( cross join ) 內部聯接 (inner join) 外部聯接 (outer join) 每種聯接在邏輯上經歷不同的階段&#xff0c;分為笛卡爾乘積、篩選、添加外部行&#xff0c;如圖&#xff1a; 聯接類型 階段 交叉聯接 笛卡兒乘積 內部聯接…

Android FrameWork學習(一)Android 7 0系統源碼下載 編譯

最近計劃著研究下 Android 7.0 的系統源碼&#xff0c;之前也沒做過什么記錄&#xff0c;這次正好將學習的內容記錄下來&#xff0c;方便以后復習鞏固。 既然要學習我們的系統源碼&#xff0c;那我們第一步要做的就是下載源碼并進行編譯了。 #硬件環境要求 ###1. 編譯環境 按照…

【MapGIS精品教程】002:GDB本地數據庫的使用

本文主要內容為MapGISGDB本地數據庫的使用&#xff0c;包括&#xff1a;GDB企業管理器的認識、GDB本地數據庫的創建方法、GDB本地數據庫的備份和恢復。 1. GDB企業管理器的認識 GDB是地理數據的資源管理器&#xff0c;主要對空間數據進行有序組織與管理。 GDB數據管理包括&…

RabbitMQ學習3----運行和管理RabbitMQ

1.服務為管理 Erlang天生就是為了讓應用程序無需知道對方是否存在同一臺機器上即可互相通信。 Erlang節點&#xff1a;Erlang虛擬機的每個實例。多個Erlang應用程序可以運行在同一個節點之上。節點之間可以進行本地通信&#xff08;不管他們是運行在同一臺服務器之上&#xff0…

各代移動網絡性能

摘自《中國元宇宙白皮書》 下載整書完整版https://www.aliyundrive.com/s/gXQvRLM22kD

EFCore高級Saas系統下單DbContext如何支持不同數據庫的遷移

前言隨著系統的不斷開發和迭代默認的efcore功能十分強大&#xff0c;但是隨著Saas系統的引進efcore基于表字段的多租戶模式已經非常完美了&#xff0c;但是基于數據庫的多租戶也是可以用的&#xff0c;但是也存在缺點&#xff0c;缺點就是沒有辦法支持不同數據庫&#xff0c;mi…

poj 1679: The Unique MST【次小生成樹】

題目鏈接 參考博客 希望注釋足夠清楚。。歡迎指出不足~ #include<cstdio> #include<cstring> #include<algorithm> using namespace std;const int maxn110; const int INF0x3f3f3f3f;int n,m; int mp[maxn][maxn]; int maxlen[maxn][maxn]; //maxlen…

51. Python 數據處理(2)

1.Python 修改excel文件import xlrd import xlutils.copy excelr xlrd.open_workbook("hello.xlsx") excelw xlutils.copy.copy(excelr) sheet1 excelw.get_sheet(0) sheet1.write(3, 5, "xlutils.copy test test") excelw.save("hello.xlsx"…

人工智能十大流行算法

導讀&#xff1a;本文為有志于成為數據科學家或對此感興趣的讀者們介紹最流行的機器學習算法。 作者&#xff1a;Fahim ul Haq 譯者&#xff1a;劉志勇&#xff0c;策劃&#xff1a;趙鈺瑩 來源&#xff1a;InfoQ&#xff08;ID&#xff1a;infoqchina&#xff09; 機器學習是…

Win7+Win10雙系統安裝全攻略

安裝雙系統,不僅能給你非凡的體驗,還可以滿足工作中因系統版本,兼容性,處理器等原因帶來的不便。本文講解Win7+Win10雙系統安裝全攻略,親測可用。 1. 硬盤分區 本文講解利用固態硬盤+機械硬盤的分區方式。 固態硬盤:為了絕對提高系統運行的速度,將固態硬盤作為雙系統的…

[矩形并-掃描線-線段樹]Picture

最近在補數學和幾何&#xff0c;沒啥好寫的&#xff0c;因為已經決定每天至少寫一篇了&#xff0c;今天隨便拿個題水水。 題目大意&#xff1a;給你N個邊平行于坐標軸的矩形&#xff0c;求它們并的周長。(N<5000) 思路&#xff1a;這個數據范圍瞎暴力就過了&#xff0c;但我…

聊聊研發團隊中的“人”

大家好&#xff0c;我是Z哥。漢字博大精深&#xff0c;很多時候我們可以通過拆字來更形象地理解一個詞的含義。比如“團隊”這個詞的兩個字"團"和“隊”單獨看也都是表示一種由多人組成的組織。再做一下拆字就是“口”“才”和“耳”“人”。前者表示一個人才如果沒有…

[轉]【分布式系統】唯一ID生成策略總結

文章目錄 全局唯一id介紹 全局唯一id特點:常見全局唯一id生成策略 1、數據庫自增長序列或字段生成id 2、UUID 3、Redis生成ID 4、zookeeper生成ID 5、Twitter的snowflake算法全局唯一id介紹 系統唯一id是我們在設計階段常常遇到的問題。在復雜的分布式系統中&#…

shell在一個大文件找出想要的一段字符串操作技巧

昨天端午&#xff0c;晚上的時候接了一個電話&#xff0c;我朋友的公司&#xff0c;數據庫被兩個工作沒多久的phper給弄壞了&#xff0c;具體就是把一個字段值&#xff0c;給全表弄成一個了名字了&#xff0c;當然這個是可以配置了禁止全表更新數據庫,這下可急壞了&#xff0c;…

CentOS7安裝EPEL源

CentOS7安裝EPEL [lijiayuncentos-*** ~]$ yum install epel-release已加載插件&#xff1a;fastestmirror, langpacks您需要 root 權限執行此命令。[lijiayuncentos-*** ~]$ su密碼&#xff1a;[rootcentos-*** lijiayun]# yum install epel-release已加載插件&#xff1a;fas…

超全的開源Winform UI庫,滿足你的一切桌面開發需求!

本文有dotnet9站長整理 網址&#xff1a;https://dotnet9.com/本站曾介紹過一款Winform開源控件庫HZHControls&#xff0c;Winform在大家心中的地位還是挺高的&#xff0c;今天小編再分享一款新鮮出爐的 Winform UI庫——SunnyUI&#xff0c;一起跟 Dotnet9 往下看吧。項目名稱…

告別國外 IDE,阿里 螞蟻自研 IDE 研發框架 OpenSumi 正式開源

經歷近 3 年時間&#xff0c;在阿里集團及螞蟻集團共建小組的努力下&#xff0c;OpenSumi 作為國內首個強定制性、高性能&#xff0c;兼容 VS Code 插件體系的 IDE 研發框架&#xff0c;今天正式對外開源。 一 OpenSumi 是什么&#xff1f; OpenSumi 是一款面向垂直領域&#…