2012-01-23 10 views
5

Sto cercando di capire in che modo le chiamate ai messaggi C oggettivo IOS sono implementate nel linguaggio assembly ARM. Osservando l'output di disassemblaggio di IDA posso vedere i riferimenti di classe e selettore inseriti nei registri prima che venga chiamato __obj_msgsend. Questo ha perfettamente senso ma la cosa strana è che c'è uno strano offset rispetto a questi valori.Offset per selettori C oggettivi nel gruppo ARM (IOS)

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

Il valore 0x29BC nel ref classe sembra essere rivolto all'istruzione dopo il __obj_msgsend che ha una certa logica, ma il selettore ref 0x29B0 sta indicando un'istruzione MOVT casuale. E per peggiorare le cose, questo offset sembra essere diverso per ogni invocazione del selettore.

Qualcuno sa da dove vengono questi offset? Perché non si fa semplicemente riferimento all'indirizzo delle istruzioni + 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 

Aggiornamento: Ecco un altro caso:

__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 

Grazie alla spiegazione di Igor, ho capito dove il 0x2758 provenienza, ma la matematica non funziona qui: selRef_view - 0x2758 = 0x49A8 - 0x2758 = 0x2250. Ma i dati nella prima istruzione sono 50 12, che si traduce in 0x1250, 0x1000 in meno che mi aspetterei. Qualche idea???

+0

Hai detto offset, ma l'elenco di disassemblaggio è da indirizzo assoluto. – arul

risposta

8

In ARM, il valore del PC indica due slot di istruzioni in avanti, vale a dire. + 8 in modalità ARM e. + 4 in modalità Thumb. Ecco da dove vengono i valori "casuali". Per esempio:

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

Dal momento che siamo in modalità di ARM, il valore del PC è 029A8 + 8 = 029B0. Quindi, questo codice è equivalente a r1 = *(int*)(r1+0x29B0). IDA ci dà un suggerimento che R1 è caricato con il valore (selRef_arrayWithObject_ - 0x29B0), quindi dopo la semplificazione otteniamo r1 = *(int*)(selRef_arrayWithObject_), che presumibilmente risolve l'indirizzo della stringa (selettore) "arrayWithObject:".

+0

I.e. leggere l'assemblaggio ARM è un dolore nel sedere. :) – bbum

+0

A meno che non si usi IDA;) –

+0

Vedo. Sapevo di PC + 8 ma stavo usando il PC sbagliato (: Grazie! – Locksleyu

Problemi correlati