在逆向過程當中,咱們使用了不少快捷工具,例如***Clutch***、class-dump等等,這些工具都是在終端執行。而這些工具的本質其實就是Mach-O類型的可執行文件,若是想要開發屬於咱們本身的命令行工具,應該怎麼作呢?xcode
在iOS開發中。咱們編譯一個項目,在生成的.app包中就能找到項目的可執行文件,經過這種方式生成的可執行文件能夠直接運行在iPhone上。因此,若是咱們要本身開發命令行工具,而且能在iPhone上使用,最簡單的方式就是使用xcode建立iOS項目。bash
給定一個iPhone上的可執行文件路徑,利用咱們本身開發的命令行工具,讀取可執行文件,而且判斷出可執行文件包含的架構類型,並打印。微信
上圖中FAT_MAGIC和FAT_CIGAM表明通用二進制文件類型,經過如下結構體能夠看出FAT_MAGIC和FAT_CIGAM是uint32_t類型架構
上圖是loader.h中定義的文件類型,其中MH_MAGIC和MH_CIGAM表明非64位的架構類型,也就是armv7或者armv7s類型的架構,MH_MAGIC_64和MH_CIGAM_64表明64位類型的架構,也就是arm64架構app
經過查看源碼能夠發現一個問題,上圖類型定義都有兩種,並且對應的值徹底相反。其實這就是大小端模式:
大端模式:數據的高字節保存到內存的低地址中,數據的低字節保存到內存的高地址中。
小端模式:數據的高字節保存到內存的高地址中,數據的低字節保存到內存的低地址中。
這就致使在讀取數據的時候能夠從高地址向低地址讀取,也能夠從低地址向高地址讀取,因此就存在上圖兩種定義工具
拿到了具體架構的定義,咱們就能夠拿到咱們所讀取到的Mach-O文件的前四個字節,與以上定義作對比,就能夠判斷當前Mach-O文件的具體架構模式ui
首先建立命令行項目,去除多餘文件以後,在***main.m***中添加以下代碼spa
#import <UIKit/UIKit.h>
#import <mach-o/loader.h>
#import <mach-o/fat.h>
int main(int argc, char * argv[]) {
@autoreleasepool {
NSString *path = @"/var/mobile/Containers/Bundle/Application/048B71C8-42E4-4EE0-8E50-EF262251DE17/WeChat.app/WeChat";
NSFileHandle *fileHandle = [NSFileHandle fileHandleForReadingAtPath:path];
NSUInteger len = sizeof(uint32_t);
//讀取uint32_t長度的字節數
NSData *data = [fileHandle readDataOfLength:len];
//將data數據存放到magicNumber中
uint32_t magicNumber;
[data getBytes:&magicNumber length:len];
if (magicNumber == FAT_MAGIC || magicNumber == FAT_CIGAM) {
printf("Universal Binary\n");
}else if (magicNumber == MH_MAGIC_64 || magicNumber == MH_CIGAM_64){
printf("64bit Binary\n");
}else if (magicNumber == MH_MAGIC || magicNumber == MH_CIGAM){
printf("32bit Binary\n");
}else{
printf("讀取失敗\n");
}
printf("magicNumber = 0x%x\n", magicNumber);
[fileHandle closeFile];
return 0;
}
}
複製代碼
chmod +x /usr/bin/TestCommand
複製代碼
增長完可執行權限以後,再次執行此命令,會在終端打印出如下信息命令行
508SC:~ root# TestCommand
64bit Binary
magicNumber = 0xfeedfacf
508SC:~ root#
複製代碼
能夠看出微信App的可執行文件是arm64架構的code
以前寫的命令行工具能夠獲取到指定了路徑的可執行文件的架構類型,可是這種方式不穩定,在大多數狀況下會獲取失敗。緣由是咱們沒有爲命令行工具增長足夠的權限。那麼如何爲可執行文件增長權限呢?
以前在安裝Theos的時候咱們安裝了ldid工具,能夠直接在命令行輸入==ldid==就能夠查看==ldid==的具體用法
ldid -e TestCommand > TestCommand.entitlements
複製代碼
在iOS中,權限信息通常存放到entitlements文件中
get-task-allow :YES
複製代碼
若是想要更多權限,能夠找一個具備不少權限的可執行文件,導出它的權限信息,而後將全部權限設置到咱們本身的==TestCommand.entitlements==文件中
ldid -STestCommand.entitlements TestCommand
複製代碼
-S 命令後要緊跟權限文件,不能有空格