2012-01-23 12 views
5

objektif C seçicileri için Ofset. IDA sökme çıktısına baktığımda, __obj_msgsend çağrılmadan önce sınıfa giren sınıf ve selektör referanslarını görebiliyorum. Bu mükemmel bir anlam ifade ediyor ancak garip olan şey, bu değerlere tuhaf bir sapma var.KOL montajı (IOS) Ben IOS objektif-C mesajı aramalar ARM birleştirici dili nasıl uygulandığını anlamaya çalışıyorum

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

sınıf ref 0x29BC değeri ona belli bir mantığı vardır __obj_msgsend sonra talimat işaret ediyormuş gibi görünüyor, ama 0x29B0 seçici ref rastgele MOVT talimatına işaret ediyor. Ve daha da kötüsü yapmak için bu ofset her bir seçici çağrısında farklı görünmektedir. bu uzaklıklar nereden geldiğini

bilen var mı? Neden sadece talimatın + 8'inin adresine başvurmadılar?

__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 

Güncelleme: 0x2758 nereden geldiğini Igor'un açıklama

__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 

sayesinde, anlıyorum, ama matematik burada işe yaramaz: İşte başka durumdur selRef_view - 0x2758 = 0x49A8 - 0x2758 = 0x2250. Ancak, ilk komuttaki veriler, bekleyeceğim 0x1250, 0x1000'e karşılık gelen 50 12'dir. Herhangi bir fikir??? ARM olarak

+0

Offset dediniz, ancak sökme listesi mutlak adreslerden. – arul

cevap

8

PC değeri, öncesinde, yani iki kullanım alanlarını işaret eder. ARM modunda + 8 ve. Thumb modunda + 4. "Rastgele" değerlerin geldiği yer burasıdır. Örneğin: Biz ARM modunda olduğundan beri

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

PC değeri 029A8 + 8 = 029B0 olduğunu. Yani, bu kod r1 = *(int*)(r1+0x29B0)'a eşdeğerdir. IDA bize R1 değeri ile yüklenmiş olduğundan bir ipucu verir (selRef_arrayWithObject_ - 0x29B0), bu yüzden basitleştirme sonra büyük ihtimal dize (seçici) "arrayWithObject:" adresine giderir, hangi r1 = *(int*)(selRef_arrayWithObject_) olsun.

+0

I.e. ARM okuyucusunun okunması popoda bir acıdır. :) – bbum

+0

IDA kullanmadığınız sürece;) –

+0

Anladım. Ben PC + 8 hakkında biliyordum ama (yanlış PC kullanıyordu:!? Teşekkür – Locksleyu