2010-11-30 10 views
6

kullanırken kayıt değerlerini belirleme Bu nedenle, derlemeden bir Kontrol Akışı Grafiği oluşturmak için objdump yardımcı programını kullanmaya çalışıyorum ve bir sorunla karşılaşıyorum. Temel olarak, bir şube oluştuğunda ve hedef adres göreli olduğunda, bir sonraki temel bloğun nerede başladığını bilmiyorum. Net olup olmadığından emin değilim, bu yüzden bir örnek ekleyeceğim. Programımın objdump çıkışı üzerinden geçtiğini ve ilk temel bloğun başlangıç ​​adresini kaydettiğini söyle. Ardından, atlanacak uygun adrese işaret etmek için göreli adresleme kullanan bir atlama komutuna basar. İlk temel bloğumun sonunun şu anda gerçekleştiğini biliyorum, ancak bir sonraki temel bloğun başlangıcında doğru adresi almak için nasıl giderim? Herkesin sağlayabileceği herhangi bir rehberlik büyük bir memnuniyetle karşılanacak, ben en iyi x86 acemi değilim ve kafamı geçen hafta boyunca buna karşı çarpıyorum.objdump

cevap

4

Soruyu anladığımı varsayarsak, belki bu sizin başlayacaktır. Bağıl atlar pc tabanlı.

 
d: eb 04 jmp 13 

0xEB, 8 bitlik bir anında temel alınan göreli bir atlama için kullanılan opodtur. Talimatın adresi, objdump çıkışında, bu durumda d veya 0xD'dir. iki bayttır (x86 değişken uzunluktadır). size çıkış adresinin ne olduğunu, bu durumda jmp 13 olduğunu söyler. Böylece 13 ile başlayan objdump çıkışındaki çizgiyi aramak ve bir sonraki kolon kodunun başlangıcı bir kolondur.

Bu adresin nasıl hesaplandığını anlamak için. Komutu getirmeye başladığında bilgisayar 0xD seviyesindedir, iki bayt alır, bu yüzden bu komutu yürütmeye hazır olduğunda pc 0xD + 2 = 0xF'dir. Ofset 0x4 yani, 0xF + ​​0x4 = 0x13 hedef adres.

 
20: 75 ed jne f 

Aynı şey arkaya doğru gider. pc artı bayt sayısı = 0x20 + 2 = 0x22. 0xED, imzalı bir sayıdır ve bu nedenle 0xEFFFFFFF ... FFFFED'e kadar 0xED işareti uzatılır, ancak adres kayıtlarınız büyüktür. 0x22 + 0xFFFFFF ... FFFED ekleyin ve hedef adresi 0x0F olsun. Ayrıca 0xED, invert ve onu reddetmek için 1 ekleyebilirsiniz. ~ 0xED = 0x12, 0x12 + 1 = 0x13. Yani 0xED, 0x13 çıkar demektir. 0x22-0x13 = 0x0F.

Biraz daha var, her durumda size sadece objdump çıkışında arayabileceğiniz hedef adresi veriyor.

Bu değeri nasıl hesapladığını anlamak için. Aynı hikaye, 0x400A81'de opcode ile başlar, değişken uzunluktaki komut için bu durumda 6 bayt alır. Yani, PC'yi çalıştırmaya hazır olduğunuzda, 0x400A81 + 6 = 0x400A87. Ofset 0x107 olur, bu durumda koşul yerine getirilirse, hedef adres 0x400A87 + 0x107 = 0x400B8E'dir.

Bunlar daha büyük bir programdan değil, sıralı koddan değil, sadece izole edilmiş örneklerden oluşan bir koleksiyondan arındırılır.

 
    400a81: 0f 8f 07 01 00 00  jg  400b8e 
    400a8f: 0f 8f e6 00 00 00  jg  400b7b 
    400a9d: 0f 8f c5 00 00 00  jg  400b68 
    400aab: 0f 8f a4 00 00 00  jg  400b55 
    400ab9: 0f 8f 83 00 00 00  jg  400b42 
    401d76: 0f 8f 31 01 00 00  jg  401ead 
+0

Çok teşekkür ederim, bu benim sorunumun çoğunu temizliyor. Temel olarak, üzerinde çalıştığım objdump çıkışını tam olarak anlamıyorum gibi görünüyor. Nesne çıkışı hakkında daha fazla şey öğrenmek için iyi bir kaynak bilen var mı? – Sam

+0

Bazı çıktıları tekrar okuyorum ve bu kesinlikle çok açıklığa kavuşuyor. Yine de bunun gibi bir çizgiden emin değilim: 4020a6: \t ff 25 4c 8f 21 00 jmpq * 0x218f4c (% rip) # 61aff8 <_fini + 0x207840> Temelde tamamen objdump çıkışını tam olarak anlamadım gibi görünüyor ile çalışıyorum. Nesne çıkışı hakkında daha fazla şey öğrenmek için iyi bir kaynak bilen var mı? – Sam

+0

Ne aradığınızı söyleyebilirim x86 assembler'ı mutlaka objdump değil anlamaktır. Bu özel komutun op kodu bana atlamamaktadır (amaçlanan herhangi bir amaç yoktur), fakat sözdizimi, kayıt temelli bir şey olduğunu, hedef adresin çalışma zamanında% rip içeriğiyle ilgili olması gerektiği anlamına gelir. temelde tablo.Ve bu kodu yerine getirmediğinizden, sadece inceleme yaptığınız için% rip içeriğinin ne olduğu açık olmayabilir ve sonuç olarak hedef adresin ne olduğunu anlamayabilirsiniz. –

İlgili konular