5

IOSのObjective-Cメッセージ呼び出しがARMアセンブリ言語でどのように実装されているかを理解しようとしています。IDA分解出力を見ると、__ obj_msgsendが呼び出される前に、クラスとセレクターの参照がレジスターにプッシュされていることがわかります。これは完全に理にかなっていますが、奇妙なことに、これらの値には奇妙なオフセットがあります。

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

クラスrefの0x29BC値は、特定のロジックを持つ__obj_msgsendの後の命令を指しているようですが、0x29B0セレクターrefはランダムな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

Igorの説明のおかげで、0x2758がどこから来たのかはわかりますが、ここでは計算がうまくいきません:selRef_view-0x2758 = 0x49A8-0x2758=0x2250。しかし、最初の命令のデータは50 12であり、これは0x1250に変換され、私が期待するよりも0x1000少なくなります。何か案は???

4

1 に答える 1

8

ARMでは、PC値は2つの命令スロットの前方を指します。+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:"

于 2012-01-23T17:16:25.387 に答える