gravatar

Reverse Engineering on Mac OS X

長久以來一直都是在 intel x86 的 dos/windows/xp 上面搞逆向工程, 但是對於 PowerPC 上的 mac os x 來說, 實在有點力不從心. 第一是因為沒有好的 tools, windows 上有很多 disassembler, SoftICE 等等, mac os x 上也有, 但是不多, 目前僅靠 gdb 而以 @_@. 再來是 PowerPC 的 RISC 架構讓人吃苦頭, 雖然 x86 的指令是 CISC, 但是其實對於人來看是比較輕鬆, 而且幾乎現在 compiler 不會產生太奇怪的 code 讓人很難看懂, 以 subroutine 來說, x86 的 compiler 作出來的大概都會類似這樣的 assembly code,

push param2
push param1
call 0xabcdefgh ; function address
add esp,n ; destroy the parameter stack

0xabcdefgh:
push ebp
mov ebp,esp
sub ebp,x ; reserve local variables
....
cmp blah, blah ; return?
jmp _end
...
mov eax,ret_value
_end:
ret
看過大部分的 compiler 產生 x86 執行檔的 function / subroutine 都是類似的 code, 因此很好知道某個 function 從哪邊開始, 哪邊結束, 他的 local variable 怎麼存. 即使在途中有 return 動作, 也都會 jump 到後面的 ret 才回去不會直接在整個 function block 中間直接很多 ret 的指令出現.
對於 RISC 來說, 當然它是簡單指令集, 對大部分的人來說都以為指令很簡單, 其實這是不太正確的. 應該對電腦來說指令架構很簡單, 但是對於人來看就很複雜. 比如說一個指令可能因為中間某個 bit field 的不同, 就有不同的 mnemonics, 但是對於人來看以及理解上其實相對複雜很多. 接著重點是在作 reverse engineering 時候, 使用 gdb 反組譯出來的 assembly code, 很難去切他們的 function blocks. RISC 不是使用 call 這種方法而是稱為 "branch & link", 學過 computer organization / architecture 應該都知道; 而從 function 回去的方式太多種了, 像是 bctr, bctrl, mtlr, mtflr 等等, 加上他們可能在 function block 中間就直接跳回去. 因此在切 function blocks 時候很難辨認出來哪邊到哪邊是個 function or subroutine.