2012-01-23 1 views
5

Я пытаюсь понять, как вызовы сообщений Object-C IOS реализованы на языке ассемблера ARM. Глядя на вывод дизассемблирования IDA, я вижу ссылки класса и селектора, помещенные в регистры, до вызова __obj_msgsend. Это имеет смысл, но странно, что есть странное смещение этих значений.Смещение для объективных селекторов C в сборке ARM (IOS)

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

Значение 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 

Update: Вот еще один случай:

__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 значение ПК указывает на два слота для инструкций вперед, т. Е. + 8 в режиме ARM и. + 4 в режиме Thumb. Вот откуда берутся «случайные» значения. Например:

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

Поскольку мы находимся в режиме ARM, значение ПК 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

Я вижу. Я знал о ПК + 8, но я использовал неправильный компьютер (: Спасибо! – Locksleyu