作者:
vvun91e0n
·
2015/06/05 9:56
author vvun91e0n
0x00 前言
閱讀學習國外nemo大牛《Modern Objective-C Exploitation Techniques》文章的內容,就想在最新的OS X版本上除錯出作者給出的程式碼。控制rip。我根據自己的除錯,修改了原程式,才除錯成功。對大牛原程式的部分程式碼的意圖和計算方法難免理解不足,歡迎留言與我交流學習。本文主要簡要介紹下對objective-c類的覆蓋到控制rip的技術。是目前OS X平臺下,比較主流的一種溢位利用方式。
0x01 64位彙編知識及lldb簡單除錯命令
彙編知識主要是在除錯的時候使用,在64位平臺下除錯必不可少的知識。對此熟悉的讀者可直接跳過。下面簡要介紹下64位彙編。
RIP的就是64位的指令暫存器。
通用64位暫存器
RAX RBX RCX RDX RBP RSI RDI RSP
R8 --- R15
可以使用
- EAX 訪問RAX的低32bits
- AX 訪問RAX的低16bits
- AL 訪問RAX的低8bist
- AH 訪問RAX低16bits的高8bits
OS X 64位的彙編呼叫約定,可以參考AMD64 Application Binary Interface
x86-64 Function Calling convention:
If the class is MEMORY, pass the argument on the stack.
If the class is INTEGER, the next available register of the sequence %rdi, %rsi, %rdx, %rcx, %r8 and %r9 is used.
可以看到和32位彙編的透過push壓棧來傳遞引數不同,函式的引數傳遞基本是透過暫存器來完成的。順序如上。 32位彙編透過int 0x80來進行系統呼叫,64位彙編是透過syscall來呼叫的。
lldb是蘋果公司推出的用以替代gdb的偵錯程式。隨xcode一起安裝。是進行動態除錯的利器。除錯時必不可少。下面簡要介紹下會用到的一些基礎命令:
在命令列輸入lldb,就會進入除錯工具
(lldb)
help會顯示所有的命令,需要詳細瞭解可以用輸入help + 命令查詢
file命令載入需要除錯的程式
(lldb) file /Users/vvun91e0n/Desktop/OC64exploit
Current executable set to '/Users/vvun91e0n/Desktop/OC64exploit' (x86_64).
breakpoint set用來設定斷點
(lldb) breakpoint set --name length
breakpoint list可以用來檢視所有斷點 breakpoint disable 關閉斷點 breakpoint enable 啟用斷點 ni 單步步不執行指令
run或r啟動程式進行除錯
register read 讀取現在所有暫存器的值 想讀取特定的幾個暫存器,寫在後面就行,使用簡化命令如
(lldb) re r rdi r10 rsi
rdi = 0x0000000100202fa0
r10 = 0x0000000000000001
rsi = 0x00007fff907bb509
memory read 可以讀取指定地址的記憶體資料,如下指定地址就是length字串。也可以使用gdb風格的x 0x00007fff907bb509命令來讀取記憶體資料。
(lldb) memory read 0x00007fff907bb509
0x7fff907bb509: 6c 65 6e 67 74 68 00 69 73 54 79 70 65 4e 6f 74 length.isTypeNot
0x7fff907bb519: 45 78 63 6c 75 73 69 76 65 3a 00 61 70 70 65 6e Exclusive:.appen
(lldb) x 0x00007fff907bb509
0x7fff907bb509: 6c 65 6e 67 74 68 00 69 73 54 79 70 65 4e 6f 74 length.isTypeNot
0x7fff907bb519: 45 78 63 6c 75 73 69 76 65 3a 00 61 70 70 65 6e Exclusive:.appen
continue 或者c 命令來繼續執行。 kill來結束程式。run來重新啟動。 其他如條件斷點,修改暫存器值等命令讀者可以使用help命令瞭解。
0x02 objective-c方法呼叫
你需要對objective-c語言有一定的基本的瞭解。特別是objc_msgSend函式的呼叫機制。可以參考:《The Objective-C Runtime: Understanding and Abusing》。這篇文章是nemo2009年發表在phrack上的。在32位系統基礎上講Objective-C Runtime溢位的文章。還是有閱讀價值的。特別是對後面64位溢位的理解。
下面簡要介紹下objective-c,先看看一個簡單的類實現和呼叫:
#!c
// Talker.h
#import <Foundation/Foundation.h>
@interface Talker : NSObject //定義一個類
- (void) say: (char *) str; //宣告一個say方法
@end
// Talker.m
#import "Talker.h"
@implementation Talker //類的相關方法實現
- (void) say: (char *) phrase
{
printf("%s\n",phrase);
}
@end
//main.m
#import "Talker.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
// insert code here...
Talker *talker = [[Talker alloc] init];//分配記憶體,初始化
[talker say: "Hello, World!"]; //呼叫say方法
}
return 0;
}
如上面程式碼所示,定義了一個Talker類,並在main函式中呼叫了say方法。 可以看出objective-c語言的方法呼叫語法為
[\