2012-01-23 67 views
5

我想了解如何在ARM彙編語言中實現IOS Objective-C消息調用。查看IDA反彙編輸出,我可以看到在調用__obj_msgsend之前將類和選擇器引用推入寄存器。這很有道理,但奇怪的是這些值有一個奇怪的偏移。ARM彙編(IOS)中的目標C選擇器的偏移量

selector ref = (selRef_arrayWithObject_ - 0x29B0) 
class ref = (classRef_NSArray - 0x29BC) 

在類REF的0x29BC值似乎是指向具有一定邏輯給它的__obj_msgsend之後的指令,但0x29B0選擇裁判指向隨機MOVT指令。更糟糕的是,這個偏移對於每個選擇器調用來說似乎都不同。

有沒有人知道這些偏移量來自哪裏?他們爲什麼不只是參考指令地址+ 8?

__text:00002998 E8 1F 01 E3     MOV    R1, #(selRef_arrayWithObject_ - 0x29B0) ; selRef_arrayWithObject_ 
__text:0000299C 05 20 A0 E1     MOV    R2, R5 
__text:000029A0 00 10 40 E3     MOVT   R1, #0 
__text:000029A4 01 50 A0 E3     MOV    R5, #1 
__text:000029A8 01 10 9F E7     LDR    R1, [PC,R1] ; selRef_arrayWithObject_ ; "arrayWithObject:" 
__text:000029AC 74 00 02 E3     MOV    R0, #(classRef_NSArray - 0x29BC) ; classRef_NSArray 
__text:000029B0 00 00 40 E3     MOVT   R0, #0 
__text:000029B4 00 00 9F E7     LDR    R0, [PC,R0] ;  _OBJC_CLASS_$_NSArray 
__text:000029B8 8C 05 00 EB     BL    _objc_msgSend 

更新:這裏是另一種情況:

__text:00002744 50 12 02 E3     MOV    R1, #(selRef_view - 0x2758) ; selRef_view 
__text:00002748 00 10 40 E3     MOVT   R1, #0 
__text:0000274C 00 50 A0 E1     MOV    R5, R0 
__text:00002750 01 10 9F E7     LDR    R1, [PC,R1] ; selRef_view ; "view" 


__objc_selrefs:000049A8 1A 39 00 00 selRef_view  DCD sel_view   ; DATA XREF:  __text:000025F8o 

感謝伊戈爾的解釋,我明白了其中0x2758是從哪裏來的,但數學已經不在這裏工作了: selRef_view - 0x2758 = 0x49A8 - 0x2758 = 0x2250。但是第一條指令中的數據是50 12,這意味着0x1250,0x1000會減少。有任何想法嗎???

+0

你說的抵消,但反彙編列表是從絕對地址。 – arul

回答

8

在ARM中,PC值指向前兩個指令槽,即,在ARM模式下+ 8。 + 4在拇指模式下。這就是「隨機」值來自哪裏。例如:

__text:000029A8 LDR R1, [PC,R1] 

由於我們處於ARM模式,PC值爲029A8 + 8 = 029B0。所以,這段代碼相當於r1 = *(int*)(r1+0x29B0)。 IDA向我們提示R1加載了值(selRef_arrayWithObject_ - 0x29B0),因此在簡化後我們得到r1 = *(int*)(selRef_arrayWithObject_),這可能解析爲字符串(選擇器)"arrayWithObject:"的地址。

+0

I.e.閱讀ARM彙編是一個痛苦的屁股。 :) – bbum

+0

除非你使用IDA;) –

+0

我明白了。我知道關於PC + 8,但我使用了錯誤的PC(:謝謝! – Locksleyu