閑著沒事看看iOS逆向工程這書做個筆記以備查詢

工具 class-dump 用來提取已經砸過殼的 app 的頭文件

下載地址 http://stevenygard.com/projects/class-dump

下載完將 dmg 里面的 class-dump 復制到 osx 的 /usr/bin/ 目錄下,然后打開 Terminal 執行命令 sudo chmod -R 777? /usr/bin/class-dump 賦予其執行權限

工具 theos ?

安裝 theos 必須先安裝 Xcode 與 Command Line Tools,一般安裝 Xcode 會附帶Command Line Tools . 如果安裝多個 Xcode 需要指定一個 Xcode 給 Theos 默認使用.命令: sudo Xcode-select ?-s /Applications/Xcode.app/Contents/Developer

?下載 Theos

在 Terminal 輸入命令 export THEOS=/opt/theos ?然后輸入 sudo ?git clone git://github.com/DHowett/theos.git $THEOS

?上面這個是原版下載地址,不過作者已經很久沒有更新了.下面這個是別開發者更新的新版sudo git clone --recursive https://github.com/theos/theos.git /opt/theos

配置 ldid 用來簽名的工具

下載地址http://joedj.net/ldid 下載后把他放到/opt/theos/bin/ 目錄下,然后執行命令 sudo chmod -R 777 /opt/theos/bin/ldid 賦予權限

配置 CydiaSubstrate?

執行命令sudo /opt/theos/bin/bootstrap.sh substrate?

然后手機上的 Cydia 搜索 CydiaSubstrate 然后安裝,然后找到/Library/Frameworks/CydiaSubstrate.framework/CydiaSubstrate 拷貝到 osx 中將其重新命名為 libsubstrate.dylib? 后放到 /opt/theos/lib/libsubstrate.dylib 中 替換掉里面的文件

配置 dpkg-deb

https://github.com/theos/dm.pl 下載重命名dpkg-deb 后放到/opt/theos/bin/目錄下,執行sudo chmod -R 777? /usr/bin/dpkg-deb 賦予權限.

配置 Theos NIC temolates內置了5種 theos 工程模板,還可以從https://giahub.com/DHowett/theos-nic-templates/archive/master.zip 下載后解壓,復制5個 tar 文件到/opt/theos/templates/iphone/ 目錄下

theos 創建工程在Terminal執行/opt/theos/bin/nic.pl

然后選擇需要創建的工程類型輸入一系列工程信息后,打開工程目錄里面的 Makefile 輸入配置信息

THEOS_DEVICE_IP = 192.168.31.230 手機的 ip

ARCHS = armv7 arm64

TARGET = iPhone:latest:8.0 或 TARGET = iPhone:8.1:8.0?

iPhone:8.1:8.0采用8.1SDK發布對象支持版iOS8.0及以上系統?

iPhone:latest:8.0采用 Xcode 附帶的最新版本 sdk 編譯

include $(THEOS)/makefiles/common.mk 固定格式不要修改

TWEAK_NAME = 工程名稱 不要修改

工程名稱_FILES = Tweak.xm 包含的源文件(不包括頭文件),多個以空格分隔

工程名稱_FRAMEWORKS = UIKit 需要導入的框架名稱多個與空格分隔

工程名稱_PRIVATE_FRAMEWORKS = private 框架名稱 導入私有框架,需要注意:PRIVATE_FRAMEWORKS是 AppStore 開發所不允許使用的它的內容每個 ios 版本之間會有差異,導入之前一定要確定導入的PRIVATE FRAMEWORKS 確實存在

include $(THEOS_MAKE_PATH)/tweak.mk?

after-install::

install.exec “killall -9 SpringBoard” 安裝后需要結束的后臺程序或重啟手機

工程名稱_LDFLAGS = -lx 連接 Mach-O 對象 -lx代表連接 libx.a 或 lib.dylib, 既給 x 加上 lib 的前綴,以及 .a 或 .dylib 的后綴.如果 x 是 y.o 的形式,則直接連接 y.o 不加任何前綴或后綴,例如要連接

libsqlite3.0.dylib libz.dylib 和 dylib.o 那么就可以寫成這樣 ?工程名稱_LDFLAGS = -lz -lsqlite3.0 -dylib1.o

一般情況如下:

THEOS_DEVICE_IP = 192.168.31.230

ARCHS = armv7 arm64

TARGET = iPhone:latest:8.0

include $(THEOS)/makefiles/common.mk

TWEAK_NAME = 工程名稱

工程名稱_FILES = Tweak.xm

工程名稱_FRAMEWORKS = UIKit

include $(THEOS_MAKE_PATH)/tweak.mk

after-install::

install.exec “killall -9 SpringBoard”

默認源文件Tweak.xm "xm"中 x 代表支持 logos 語法 如果后綴單獨一個 x 說明源文件支持 logos 和 c 語法,如果是 xm 說明源文件支持 logos 和 c/c++ 語法?

最基本的 logos 語法

%hook %log %orig 這3個預處理指令作用 %hook 指定要 hook 的 class 必須與 %end 結尾

%hook 類名?

- (void)_menuButtonDown:(id)down

{

NSLog(@"button");

%orig;

}

%end

這段代碼的意思是 鉤住 (hook) SpringBoard 類里的_menuButtonDown函數,先將依據話寫入 syslog 在執行函數的原始操作.

%log 該指令在% hook 內部使用,將函數的類名,參數等信息寫入 syslog 例如%log([(<type>)<expr>,..])的格式追加其他打印信息,如下:

%hook SpringBoard

- (void)_menuButtonDown:(id)down

{

%log((NSString *)@"iOSRE", (NSString *)@"Debug");

%orig;

}

%end

%orig 該指令在 %hook 內部使用,執行被鉤住的 hook 的函數的原始代碼,如下:

%hook SpringBoard

- (void)_menuButtonDown:(id)down

{

NSLog(@"button");

%orig;

}

%end

如果去掉%orig,那么原始函數不會得到執行

還可以利用%orig更改原始函數的參數,例如

%hook SBLockScreenDateViewController

- (void)setCustomSubtitleText:(id)arg1 withColor:(id)arg2?

{

%orig(@"IOS 8 App reverse Engineering", arg2");

}

%end

這行代碼是把鎖屏日期顯示時間的地方修改成 這句話"IOS 8 App reverse Engineering"

除了 %hook %log %orig ?以外, Logos 常用的預處理指令還有 %group %ctor %new %c

%group該指令是將 %hook 分組,便于代碼管理及按條件初始化分組 必須以 %end 結束,一個%group的 %hook 會被隱式歸類到%group_ungrouped 中.%group的用法如下:

%group iOS7Hook

%hook iOS7Class

- (id)iOS7Method

{

id result = %orig;

NSLog(@"This class & method only exist in iOS7.");

return result;

}

%end

%end

%group iOS8Hook

%hook iOS8Class

- (id)iOS8Method

{

id result = %orig;

NSLog(@"This class & method only exist in iOS8.");

return result;

}

%end

%end

%hook SpringBoard

- (void)powerDown

{

%orig;

}

%end

這段代碼的意思是在%group iOS7Hook中鉤住 iOS7Class 的 iOS7Method函數, 在%group iOS8Hook中鉤住 iOS8Class 的 iOS8Method函數,然后在%group_ungrouped? 中鉤住SpringBoard類的powerDown函數,需要注意的是,%group必須配合%init使用才能生效

%init ?該指令用于初始化某個%group,必須在%hook或%ctor內調用,如果帶參數,則初始化制定的group,如果不帶參數,則初始化 ungrouped, 如下

#ifndef kCFCoreFoundationVersionNumber_iOS_8_0

#define kCFCoreFoundationVersionNumber_iOS_8_0 1140.10

#endif

%hook SpringBoard

- (void)applicationDidFinishLaunching:(id)application

{

%orig;

%init;

if (kCFCoreFoundationVersionNumber >=

kCFCoreFoundationVersionNumber_iOS_7_0 && kCFCoreFoundationVersionNumber < kCFCoreFoundationVersionNumber_iOS_8_0) %init(iOS7Hook);

if (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_8_0) %init(iOSHook);

}

%end

只有調用了%init ?對應的%group才起作用,切記!

%ctor 該指令是 tweak 的 constructor, 完成初始化工作,如果不顯式定義, Theos 會自動生成一個%ctor,并在其中調用%init(_ungrouped). 因此

%hook SpringBoard

- (void)reboot

{

NSLog(@"If rebooting doesn't work then I'm screwed.");

%orig;

}

%end

可以生效,因為 Theos 隱式定義了如下內容

%ctor

{

%init(_ungrouped);

}

%hook SpringBoard

- (void)reboot

{

NSLog(@"If rebooting doesn't work then I'm screwed.");

%orig;

}

%end

%ctor

{

}

這個%hook代碼無法生效,因為這里顯式定義了%ctor 卻沒有顯式調用%init,%group(_ungrouped)不起作用.%ctor 一般可以用來初始化%group, 以及進行 MSHookFunction 等操作,如下:

#ifndef kCFCoreFoundationVersionNumber_iOS_8_0

#define kCFCoreFoundationVersionNumber_iOS_8_0 1140.10

#endif

%ctor

{

%init;

if (kCFCoreFoundationVersionNumber >=

kCFCoreFoundationVersionNumber_iOS_7_0 && kCFCoreFoundationVersionNumber < kCFCoreFoundationVersionNumber_iOS_8_0) %init(iOS7Hook);

if (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_8_0) %init(iOSHook);

MSHookFunction((void *)&AudioServicesPlaySystemSound,(void *)&replaced_AudioServicesPlaySysTemSound,(void **)&original_AudioServicesPlaySystemSound);

}

注意,%ctor 不需要以%end結尾

%new 在 %hook 內部使用,給一個現有的 class 添加新函數,功能與 class_addMethod 相同.它的用法如下:

%hook SpringBoard

%new

- (void)namespaceNewMerhod

{

NSLog(@"We've added a new menthod to SpringBoard.");

}

%end

Objective-C 和 category 語法也可以給現有的 class 添加新函數,為什么要用%new呢?

因為 category 與 class_addMethod 的區別,前者是靜態的后者是動態的.那么在這種情況下,靜態和動態,尤其是當 class 來之某個可執行文件的時候.舉個例子,上面的代碼給 SpringBoard 類添加一個新方法,如果使用 cateGory, 代碼應該是下面這樣:

@interface SpringBoard (iOSRE)

- (void)namespaceNewMerhod;

@end

@implementation SpringBoard (iOSRE)

- (void)namespaceNewMerhod

{

NSLog(@"We've added a new menthod to SpringBoard.");

}

@end

如果嘗試編譯上面的代碼,會得到"error:cannot find initerface declaration for'SpringBoard'"的報錯信息,編譯器找不到SpringBoard雷的定義.可以構造一個SpringBoard的定義,騙過編譯器,如下:

@interface SpringBoard : NSObject

@end

@interface SpringBoard (iOSRE)

- (void)namespaceNewMerhod;

@end

@implementation SpringBoard (iOSRE)

- (void)namespaceNewMerhod

{

NSLog(@"We've added a new menthod to SpringBoard.");

}

@end

重新編譯,仍然會報錯,如下:

Undefined symbols for architecture armv7:"_OBJC_CLASS_S_SpringBoard",referenced from:l_OBJC_$_CATEGORY_SpringBoard_$_iOSRE in Tweak.xm.b1748661.o

ld: symbol(s) not found for architecture armv7

clang: error : linker command failed with exit code 1 (use -v to see invocation)

ld找不到"SpringBoard"的定義.一般來說, iOS 程序員在碰到這個錯誤時的第一反應是:"是不是忘記導入那個 "framework",但是轉念一想,SpringBoard 類是SpringBoard這個 App里面的一個類,而不是一個framework,要怎么導入?現在你是不是覺得%new 非常可愛了呢?

%c ?該指令的作用等同于 objc_getClass 或 NSClassFromString,既動態獲取一個類的定義,在% hook 或% ctor 內使用

logos指令還有很多 需要的可以直接google 或百度

control 文件記錄 deb 包的管理信息會打包到 deb 包里面.

工程文件中的. plist 文件

打開文件最外面是 dictionary? 只有一個名為 Filter 的建 Filter 下是一系列的 Array ,可以分為三類 Bundles 指定若干個 bundle 為 tweak 的作用對象 ,Classes 指定若干個 class 為 tweak 的作用對象. Executables 指定若干個可執行文件為 tweak 的作用對象,這三類 Array 可以混合使用

{

Filter = {Mode = Any;Bundles = ("com.apple.springboard",);Classes = (123,);Executables = (aaaaa,);};}

Filter有不同的類的 array 是需要添加一個Mode : Any 鍵值對.Filter下只有一個類時,不需要添加Mode : Any 鍵值對.

編輯+打包+安裝

make? 命令編譯工程 make package 命令編譯打包 make package install 編譯打包安裝

設置 authorized_keys 鑰匙 打開/Users/你的用戶名/.ssh/known_hosts 刪除對應的 iOSip 那一行

在 Terminal 中執行命令 ssh-keygen -t rsa? 回車 回車 如果存在提示是否重寫選擇 y 重寫 然后輸入連接 iphone 的密碼? 然后cp /Users/jiangyihui/.ssh/id_rsa.pub ~/authorized_keys會在用戶目錄下生成authorized_keys 接下來配置 iOS ,在 Terminal 中執行連接到ssh root@你的iosip 在執行命令ssh-keygen 一路回車,然后執行scp ~/authorized_keys root@IOSIP:/var/root/.ssh

make clean 工程清除命令

Theos 開發示例

在 Terminal 中執行命令 iphone/tweak 按提示輸入信息

然后編輯 Tweak.xm 文件

內容如下

%hook SpringBoard

- (void)applicationDidFinishLaunching:(id)application

{

%orig;

UIAlertView *[alert = [UIAlertView alloc] initWithTitle:@"你好!" message:"呵呵" delegate:self cancelButtonTitle:@"ok" otherButtonTitles:nil];

[alert show];

[alloc release];

}

%end

編輯 Makefile

THEOS_DEVICE_IP = 192.168.31.230

ARCHS = armv7 arm64

TARGET = iPhone:latest:8.0

include $(THEOS)/makefiles/common.mk

TWEAK_NAME = 工程名稱

工程名稱_FILES = Tweak.xm

工程名稱_FRAMEWORKS = UIKit

include $(THEOS_MAKE_PATH)/tweak.mk

after-install::

install.exec “killall -9 SpringBoard”

在 Terminal 中執行命令make package install

Reveal ui 調試工具 mac 上下載安裝

iOS cydia 里面安裝 Reveal loader

打開電腦上的Reveal 選中菜單Help下的 Show Reveal Library in Finder ?然后復制 libReveal.dylib ?到 iOS 的 /library/RHRevealLoader/ 文件夾中.沒有這個文件夾自己創建一下

在ios 設置中找到Reveal 打開里面逆向想要調試的 app 然后電腦上打開Reveal ios 中打開相應的 app 界面就會顯示在電腦中

ida (這里沒有找到 mac 可以用的 ida demo) 就只能按照書上的先簡單記錄一下

打開 ida 選中對應的 ARM

左側小部分 Functions 窗口 右邊是 Main 窗口

Functions window 顯示的是 函數或叫方法 ,雙擊一個函數 main window 會顯示它的函數體.在選中 Functions window 時點擊菜單欄身上的 Search? 會彈出子菜單 選擇Search 輸入要查找的內容,可以在所有函數里查找指定的字符串,十分方便,當要查找的內容出現在搓個函數名里面時還可以點擊Search again 來遍歷這些函數名.

Functions window中的函數與 class-dump 導出的內容吻合, ida 還將所有 subroutine 羅列出來class-dump 是做不到的,class-dump導出的都是函數名.subroutine的名稱只是一個代號,沒有明顯的含義,分析難度大, ios 的底層用c 和 c++實現的,編譯之后哦生成大都是subroutine,只能使用 ida 這樣的工具.想要深層次的挖掘 ios 必須掌握 ida 的用法.

Main window 有兩種顯示模式,分別是 Graph view 和 Text view 它們之間可以通過空格鍵切換.Graph view把程序用方塊的形式表現出來.各個分支之間執行順序用箭頭表示,當執行到滿足判斷條件分支的線是綠色的.否則是紅色的.當執行沒有分支時線是藍色的.當執行到某個方塊會判斷R0是否為0,如果 R0!=0 ,則滿足條件就會執行 BEN (Branch if not Equal to zero) 走綠線接著執行下面的方塊.否則走紅線執行紅線的方塊.此處是 IDA 的難點之一.

顏色指示欄,當選中一個符號時,相同的符號都會用黃色高亮顯示.方便跟蹤查看.符號高亮,雙擊符號可以查看它的實現,在任意符號上點擊鼠標右鍵,會彈出菜單.其中常用的功能有 jump to xref to operand... (快捷鍵 X) 點擊后出現的窗口羅列了這個文件中顯式引用這個符號的所有信息.選擇菜單中的Xrefs graph to...? 就會以圖塊和線顯示引用.如果引用過多那就會像一團亂麻.看不清.還有 Xrefs graph from... 則會顯示這個符號顯示引用的多有符號.多數情況下,找到一個感興趣的符號會進一步查找與這個符號相關的所有線索.一種笨方法是鼠標選中 Main window 時點擊菜單欄上的 Search 此時菜單然后選擇 text... 這時可以根據自己情況選擇搜索是否對大小寫敏感.搜索格式是不是正則表達式等.然后勾選Find all occurences 點擊 OK? ida會將文件中所有滿足搜索條件的符號列出來.供我們一一查看. Text view 一般配合 LLDB 進行動態調試. IDA 有個 Bug 會導致 Graph view 的末端顯示不全.比如一個 subroutine? 本來有100行指令 ,但是只顯示了80行.當對某個Graph view塊中的指令產生懷疑時,可以切換到 Text view 中看看Graph view是不是漏顯示了某些代碼.(由于書上的案例使用的是 ios8作為案例.我手上只有 ios9系統的 iphone 文件內部不一樣,這里無法分析.等手上ios8的 iphone 到時候在補上)

KennyTM 開發的 dyld_decache??

下載地址https://github.com/downloads/kennytm/Miscellaneous/dyld_decache[v0.1c].bz2

下載解壓后重新命名dyld_decache 然后賦予777權限 命令sudo chmod +x ?dyld_decache

該工具可以dyld_shared_cache_armv7s或dyld_shared_cache_arm64其中的二進制文件提取出來,這樣確保分析的文件來自本機,在使用 mac 工具分析同一目標時, osx 和 iOS 上分析得出的指令和地址是完全吻合的,避免出現驢唇對不上馬嘴的低級錯誤.使用dyld_decache之前要將/System/Library/Caches/com.apple.dyld/dyld_shared_cache_文件拷貝到 osx 中 (不能用 SCP ?命令拷貝)?

dyld_decache -o ?/存放路徑 ?/提取路徑/dyld_shared_cache_arm64

iOS 配置

打開 cydia 搜索Cydia Substrate 安裝

案例:用 Theos新建一個iphone/activator工程

代碼如下:

#import "RootViewController.h"

class CPPClass

{

public:

void CPPFunction(const char *);

};

void CPPClass::CPPFunction(const char *arg0)

{

NSLog(@"iOSRE: CPPFuction: %s", arg0);

}

extern "C" void CFunction(const char *arg0)

{

NSLog(@"iOSRE: CFunction: %s", arg0);

}

extern "C" void ShortCFunction(const char *arg0)

{

CPPClass cppClass;

cppClass.CPPFunction(arg0);

}

@implementation RootViewController

- (void)loadView

{

NSLog(@"- loadView -");

self.view = [[[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]] autorelease];

self.view.backgroundColor = [UIColor redColor];

}

- (void)viewDidLoad

{

[super viewDidLoad];

NSLog(@"- viewDidLoad -");

CPPClass cppClass;

cppClass.CPPFunction("This is a C++ function!");

CFunction("This is a C function!");

ShortCFunction("This is a short c function!");

}

@end

然后 make package install 安裝手機上

cycript 是一個方便的工具

?一些簡單操作

在 Terminal 中執行命令 ps -e 查看當前進程找到你需要的進程 id?

cycript -p 進程 id

還有一些簡單用法

UIApp.keyWindow.recursiveDescription().toString()

[#0x12fca3e00? nextResponder]

獲得某各類的對象choose(SBScreenShotter)

獲取APP所有window

cy# [UIApp windows]

獲取View的superView和subView

cy# [#0x15e8d2c0 subviews]

cy# [#0x12345678 superview]

可以用#address的方式來調用對象。 利用著幾個函數可以看所有view,可以用[#viewAddress setHidden:YES]函數,UI上消失的就是對應的view。

LLDB 和debugserver

debug server配置

通過命令復制到 osx 中scp root@192.168.31.230:/Developer/usr/bin/debugserver ~/debugserver

debugserver瘦身在 Terminal 中執行命令 lipo -thin arm64 ~/debugserver -output ~/debugserver 其中 arm64 對應你機器的型號

給debug server添加task_for_pid權限

下載http://iosre.com/ent.xml

在 Terminal 中執行命令 /opt/theos/bin/ldid -Sent.xml debugserver?

上面5秒內沒有完成用下面的方法?

下載 http://iosre.com/ent.plist?

在 Terminal 中執行命令codesign -s - -- entitlements ent.plist -f debugserver

拷貝回 iso 目錄中 scp ~/debugserver root@192.168.31.230:/usr/bin/debugserver

連接到 iOS 命令 ssh? root@192.168.31.230

授權 命令 chmod +x /usr/bin/debugserver

用debugserver啟動或附加進程

命令開啟進程等待連接 debugserver -x backboard *:1234 /Applications/MobileSMS.app/MobileSMS

命令 debugserver 192.168.31.230:1234 -a "MobileSMS" 會附加MobileSMS并開啟進程等待192.168.31.230的 LLDB 接入

如果執行錯誤說明 ios 上的 Developer目錄下缺少必要的調試數據.這種情況一般是因為沒有在 Xcode 連接過給設備. 在 Xcode 重新連接一次該設備

當退出debug server時,當前調試的進程也會一并退出.debugserver的配置結束.接下來的操作都是 LLDB 上完成的.

LLDB使用說明

在了解 LLDB 用法之前,需要對 LLDB 的一個 bug 有所了解: Xcode6所附帶的 LLDB 版本號320.x.xx 才 armv7和 armv7s 設備上有時候會混淆 arm 和 THUMB 指令,根本無法調試.

連接命令 process connect connect://192.168.31.230:1234 連接時間比較長需要3分鐘以上

USB如何連接的:

1.點擊下載usbmuxb,單獨保存python-client目錄下的tcprelay.py和usbmux.py兩個文件,把它們放到同一個目錄下;

2.本地端口轉發到遠程iOS端口

/Users/jiangyihui/code/tcprelay.py -t 22:2222

3.ssh到iOS設備

ssh root@localhost -p 2222

4.debugserver attach進程

debugserver *:1234 -a "SpringBoard"

5.將本地端口轉發到debugserver端口

/Users/snakeninny/Code/USBSSH/tcprelay.py -t 1234(debugserver端口):1234(本地端口)

6.lldb調試

lldb

process connect connect://localhost:1234

image list 與 GDB 中的 info shared 類似,用于列舉當前進程中的所有模塊image 每次進程啟動,同一進程的所有模塊在虛擬內存中的起始地址都會產生隨機偏移

舉例:進程 A 中有一個模塊 B , B 模塊的大小是100字節,進程 A 第一次啟動時,模塊 B 可能會被加載到虛擬內存的0x00到0X64.第二次啟動被加到0x10 到0X74.第三次啟動被加到0X60到0Xc4也就是說它的大小雖然沒有變,但是起始地址每次都在變,然而這個起始地址恰恰是接下來回頻繁用到的一個關鍵數據.

使用命令 image list-o-f ,待 LLDB 鏈接 debugserver 后輸入 image list-o-f 命令

image list -o -f

[? 0] 0x01645000 /System/Library/CoreServices/SpringBoard.app/SpringBoard(0x0000000023c4000)

[第一列序號] (模塊偏移地址簡稱 ASLR) 全路徑(模塊偏移后起始地址)?

計算方法?

偏移后基地址(0x023c4000) = (IDA)基地址 + ASLR偏移地址(0x01645000)

偏移后基地址(0x023c4000) - ASLR偏移地址(0x01645000) = 基地址(0X2260A000)


符號基地址?

符號在模塊中的地址 - 模塊第一條地址 = 符號模塊在中的相對地址

符號在模塊中的相對地址 + 模塊偏移后起始地址 = 符號基地址

NSLog的基地址 = NSLog 在 Foundation 中的相對地址 + Foundation 的基地址

NSLog 函數在 Foundation 中的相對位置, NSLog 函數地址指令 "SUB SP,SP,#0xc" ?左邊的那個0X2261AB94 ,代表 NSLog 在 Foundation 中的位置

NSLog 在 Foundation 中的地址(0X2261AB94) - Foundation基地址(0X2260A000) = NSLog 函數在 Foundation 中的相對地址 0X10B94

NSLog 的基地址 = NSLog 函數在 Foundation 中的相對地址 0X10B94 + Foundation偏移后基地址(0x023c4000) = NSLog 在 Foundation 中的地址(0X2261AB94)

偏移后模塊基地址 = 偏移前模塊基地址 + ASLR 偏移地址

偏移后符號基地址NSLog 在 Foundation 中的地址(0X2261AB94) = 偏移前符號基地址 + 符號所在模塊的 ASLR 偏移地址(Foundation ASLR)

偏移后指令基地址 = 偏移前指令基地址 + 指令所在模塊的 ASLR 偏移

符號的基地址 = 符號對應函數第一條指令的地址?

偏移前地址從 IDA 里面查看. ASLR 偏移從 LLDB 里面查看, 兩者相加就是偏移后基地址.

breakpoint ?與 CGB 中的 break 類似,用于設置斷點,在逆向中一般用到的 b function 或 br s -a address 以及 br s -a 'ASLROffset+address'

在函數的起始位置設置斷點,命令 b NSLog

在地址處設置斷點,命令br a -s 0xcccccc 或 br s -a '0x6+0x9'

注意在輸出中 Breakpoint X ?"x" 代表序號

因為在逆向中調試涉及多是匯編代碼,所以大多情況下都是在某一條匯編指令上下斷點,在函數上下斷點的情況很少.要在匯編指令上下斷點就要知道它的便宜后基地址,

還可以用"br dis", "br en", "br del" 來禁用,啟用,刪除斷點

禁用某個斷點命令 br dis 6

啟用所有斷點 br en 或啟用某個斷點 br en 6

刪除所有斷點 br del 刪除某個斷點 br del 6

指定在某個斷點得到觸發時執行預先設置的指令?

br com add 1

執行到這條指令后, LLDB 會要求我們設置一系列指令,以 DONE 結束.例如:

po [$r0 class]

p (char *)$r1

c

DONE

這里輸入了3條指令,1號斷點一旦觸發,就會順序執行.

br com add 一般用于自動觀察某個斷點被觸發時其上下文的變化.找到進一步的線索

print 它可以打印某處的值

p 命令打印

用 po 命令打印 oc 對象

用 p(char *) 強制轉換方式打印 C語言基本數據類型對象

但是 LLDB 解析有時候會出錯,注釋的符號不對.這種情況請以 IDA 靜態分析的符號為準

用x 命令打印一個地址存放的值

用 p/x 以十六進制方式打印 SP, 它是一個指針

x/10 打印指針指向的聯系10個字(word)的數據

nexti 與 stepi 的作用是執行下一條機器指令,它們最大的區別是前者不進入函數體.后者會進入函數體.它們分別以簡寫 ni 和 si ,是調試時使用最多的指令之一,

register write 命令用于給指定的寄存器賦值,從而對程序進行改動,觀察程序的執行過程有什么變化.用于改變 r0值 查看它跳轉到那個分支

LLDB 使用小提示

調試的二進制文件必須從 IOS 中提取.

IDA 分析的二進制文件必須與 LLDB 調試的二進制文件相同.這樣偏移前基地址, ASLR 偏移,偏移后基地址才能對應得上.從其他渠道(如 SDK,模擬器等)提取的文件一般不能用作動態調試.

LLDB 中簡化輸入

如果想重復一條指令,直接按回車就可以了.如果想查看以前執行過的指令,按方向鍵的向上和向下就可以了.

dumodecrypted 用于砸殼

http://www.lxweimin.com/p/039dfd040253

cycript調試常用命令

http://www.lxweimin.com/p/2bbe4b0b3950

暫時寫到這里等有時間的時候在繼續














x

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 8.第一個逆向程序 創建tweak工程? iOS /opt/theos/bin/nic.pl NIC 2.0 -...
    Flonger閱讀 2,978評論 0 1
  • 轉發自 2016-07-07何兆林騰訊Bugly 如果您有耐心看完這篇文章,您將懂得如何著手進行app的分析、追蹤...
    樹懶啊樹懶閱讀 10,701評論 5 63
  • 加油
    囚匠閱讀 207評論 0 0
  • 分塊交付測試時間 11.09 活動詳情首頁 靜態頁面 測試分屏體驗; 活動分享; 活動加入系統日歷提醒; 地圖定位...
    默默01閱讀 174評論 0 0
  • 圖片發自簡書App 小時候, 父親說:"孩子,今天我帶你來的這個地方它叫北京,而在你身后的正是偉大的毛爺爺……" ...
    喜歡你的文字閱讀 216評論 0 0