Soru:
IDAPython tarafından IDA'da bir yapı türüne çapraz referanslar nasıl alınır ve yapı türünün değişkenlerine yorumlar nasıl eklenir
Bingchang
2016-06-03 10:25:39 UTC
view on stackexchange narkive permalink

Yapı türlerinin değişkenlerine yorumlar (veritabanında bulunur) eklemek için idapython kullanarak bir IDA eklentisi yazıyorum. Bunu yapmak için, ilk olarak, IDA'daki "Yapı" alt görünümünde bulunabilen belirli bir yapı türüne (örn. Yapı BITMAPINFO) çapraz referansların listesini almam gerekiyor.

IDA'nın bu işlevi sürüm 6.2'den itibaren yapı adına fareyle sağ tıklayıp "Çapraz referansları listele" seçeneğini seçerek sağladığını biliyorum. Aşağıdakine benzer bir pencere açılacaktır:

example: xrefs to BITMAPINFO picture

Yukarıdaki resimdeki listenin her bir öğesi, global bir % yapı adı% türünde değişken (burada BITMAPINFO) bildirilir veya "yapı adı" türünde yerel bir değişkenin tanımlandığı bir konum. İlki,

example: global variable definition of type GUID gibidir (burada BITMAPINFO değil, GUID yazın).

İkincisi example: local variable definition of type BITMAPINFO Bu, IDA'nın tanımlanmış türüne göre yerel değişkenleri ilan ettiği konumdur.

Bu verileri IDAPython ile almanın bir yolu olup olmadığını merak ediyorum.

NOT: Bu farklı çapraz referanslardan yapı tipinin bir (ll) üyesine / üyelerine, aşağıda gösterildiği gibi yapı üyesi adına sağ tuşla tıklayarak elde edilebilir

example: XrefsTo GUID.DATA1

Burada sormadan önce şunu yapıyorum:

  #CODE 1ea = idc.LocByName (% structure name%) frm = [x.frm idautils.XrefsTo (ea)]  

için x için yukarıdaki kodu kullanarak% yapı adı% için çapraz referansların tüm listesine sahip olduğumu düşünüyorum. Ancak, listedeki birçok EA'nın '0xff0052c9' ( MaxEA 0x108f800 ) gibi etkisiz göründüğünü gördüm. Ancak sanırım kodum istenen sonucu aldı çünkü döndürülen listenin uzunluğu 1. resim olarak gösterilen listedeki öğe sayısına eşit. Ancak sonucu özellikle (görünüşte) etkisiz olanları açıklayamam. Ayrıca, aşağıdaki kodu kullanarak listedeki adreslere yorum eklediğimde

  #CODE 2for ea in xrefs_list: # tekrarlanabilirse verilen yapı türüne her çapraz referans:
# 'ea' idc.MakeRptCmt (ea, cmt) adresine tekrarlanabilir yorum 'cmt' ekleyin else: # 'ea' idc.MakeComm (ea, cmt) adresine yorum 'cmt' ekleyin  

Yalnızca idc.MinEA () ve idc.MaxEA () arasındaki etkili adreslere yorum eklediğimi fark ettim ve bu adresler, sorgulanan yapı türü 2. resimde gösterildiği gibi bildirildi.

Sorularım:

  1. Yukarıdaki kodum (KOD 1) hepsini almak için doğru mu bir yapı türüne çapraz referanslar? Öyleyse, görünüşte etkisiz olan bu adresler nasıl açıklanır (0xFF000000'ün üstünde)
  2. Yapı türünün genel örneklerine yapılan referanslar dışında diğer çapraz referans adreslerine yorumlar nasıl eklenir?
Görünüşe göre bu referanslar yığın değişken referansları. Cevabımı eşleşecek şekilde güncelledim.
Iki yanıtlar:
tmr232
2016-06-04 19:25:15 UTC
view on stackexchange narkive permalink

Yığın Değişken Referansları

Gösterdiğiniz dış referanslar, yığın değişkenlerinden gelen dış referanslardır. Bahsettiğiniz gibi, yapıya dış referansları almaya çalışırken iki tür sonuç alırsınız:

  1. Veri bölümündeki yapı örnekleri olan geçerli adresler
  2. 0xFF000000 ve yapının yığın değişkeni olarak kullanıldığı yukarıdaki adresler.

IDA'da bir işlev için yığın değişkenleri, her yığınla birlikte dahili olarak bir yapı olarak temsil edilir. değişken bu yapının bir üyesidir.

idaman struc_t * ida_export get_frame (const func_t * pfn);

Dokümanlar bağlantısı

Bunu bildiğimizde, garip dış referansların üye kimlikleri (ki bunlar) olduğu sonucuna varabiliriz. İçeren yapıların adlarını almak için fullname = idaapi.get_member_fullname (mid) kullanıyoruz ve $ F4014B0.var_14 gibi bir şey alıyoruz. $ F4014B0 0xF4014B0 adresindeki fonksiyon için yığın çerçeve yapısının netnode adıdır.

  import idcimport idaapiimport idautilssid = idc.GetStrucIdByName ('my-struct-name') idautils.XrefsTo (sid) içinde xref için: eğer 0xFF000000 > xref.frm: # Yapı, veri yazdırma olarak kullanılır '0x {: X}' den veri xref. format (xref.frm) aksi takdirde: # Yapı olarak kullanılır bir yığın değişkeni. mid = xref.frm fullname = idaapi.get_member_fullname (mid) function_ea = int (tam ad [2:]. split ('.') [0], 0x10) print '0x {: X}' den Yığın xref '. format (function_ea )  

Xref'leri üye Değişkenlere alma

(Bu, benim ilk cevabım olduğu ve değerli bilgiler içerdiği için burada.)

Çözüme gerçekten yaklaştınız. Kodunuz size sid 'i verir, böylece yalnızca yapının kendisine referanslar alırsınız. İhtiyacınız olan şey, farklı üyelere referanslar ve bu mid kullanılarak yapılabilir. Tam nitelikli üye adları kullanarak alabilirsiniz. Bununla birlikte, her yapının çok sayıda üyesi olduğundan, bunları numaralandırmak genellikle daha iyi bir seçimdir.

  import idcimport idautilsdef get_member_ids (sid): offset = 0 while offset! = 0xFFFFFFFF: mid = idc. Mid! = -1 ise GetMemberId (sid, offset): get mid offset = idc.GetStrucNextOff (sid, offset) def get_member_xrefs (struc_name): sid = idc.GetStrucIdByName (struc_name) get_member_ids (sid) içinde mid için: xref için idautils.XrefsTo (mid): verim xref.frm # Ve kullanım: xref için get_member_xrefs ('my-struct-name'): print '0x {: X}'. format (xref)  

yorumdaki soruyu yanıtlamak için düzenleyin

Ağ Düğümleri Üzerine Bir Bit

Bu sonraki kısım IDA dahilileriyle ilgili, bu yüzden burada işaretsiz olabilirim. Ben temel SDK dokümanları hakkındaki bilgilerim buraya bakın

Kodumda görülebileceği gibi, etkili adreslerde kullanılmak üzere belgelenen birçok API ( ea s ) diğer IDA ilkelleri üzerinde de - yapı kimlikleri, üye kimlikleri - hiçbir fark olmaksızın çalışır.

Dahili olarak, IDA'daki nesneler ağ düğümlerine eşlenir. IDA'daki satırlar doğrusal olarak netnode numaralarına eşlenirken, diğer nesneler 0xFF000000 ile başlayan sayılarla eşlenir. Adresler ve yapı kimlikleri farklı bir anlamsal anlama sahip olabilirken, her ikisi de ağ düğümü numaralarıdır. IDA'nın API'lerinde bu, aynı şekilde ele alındıkları anlamına gelir.

Umarım bu, işleri daha net hale getirir.

Cevabınız için teşekkürler. Kod dönüşünüz, her yapı üyesine yönelik çapraz referansların birleşim listesidir; bu, bir yapı üyesinin adına sağ tuşla tıklanarak da elde edilebilir. Bu,% yapı adı% için çapraz referanslar listesinden farklı ve benim istediğim sonuç değil. Soruma yeni bilgiler ekledim. Ayrıca SID ve MID'nin EA olarak kullanılabileceğini öğrenmeye başladım. Bunu nasıl açıklayacağımı bana söyleyebilir misin?
@Bingchang, MID ve SID hakkındaki sorunuza yanıt vermek için yanıtı düzenledim. Henüz ana soruya bir cevabım yok. Yanlış anlaşılmayı anlıyorum.
Cevabınız gerçekten harika. Yanıtladığınız gibi, bu (görünüşte) etkisiz adresler, yığın değişkenlerine referanslardır ve her yığın değişkeni, bir işlevin yığın çerçevesini dahili olarak temsil eden bir yapının üyesidir. Sorumu çözdüm ve sorumu çözümümü içerecek şekilde güncelledim. Ayrıca, IDA'nın iç çalışanlarına kapıyı açarsınız.
@Bingchang Yardımcı olmaktan mutluluk duyarım. Sorunuzun artık başlıkla eşleşmediğine dikkat edin. Anlaşılır olması için 2 ayrı soruya bölmek isteyebilirsiniz ve böylece gelecekte insanlar konuya daha kolay bakabilir.
tavsiye ettiğiniz gibi, sorumu yeniden düzenledim ve 2 soruya böldüm. Ancak uygun olup olmadığından veya yeni bir soru açmam gerekip gerekmediğinden emin değilim.
Bingchang
2016-06-06 13:36:00 UTC
view on stackexchange narkive permalink

Soruyu ve cevabı birbirinden ayırarak işleri daha net hale getirmek için, esas olarak @ tmr232'nin cevabına göre kendi çözümümü ekledim.

1. soru için, @ tmr232'nin yanıtladığı gibi ) etkisiz adresler, yığın değişkenlerine yapılan başvurulardır. IDA'nın dahili öğelerinde, her yığın değişkeni, bir işlevin yığın çerçevesini temsil eden bir yapının üyesi olarak ele alınır. Sorudaki KOD 1 , genel örneklere ve yerel yığın örneklerine çapraz referanslar dahil olmak üzere tüm çapraz referansları bir yapı türüne döndürebilir.

Için 2. soru, yerel yığın örneklerine referanslara eklenecek yorumlar, bu referanslar bir yapının üyeleri olarak ele alınarak eklenebilir.

Kod:

  def add_struct_cmt (struct_name, cmt, tekrarlanabilir): # ea'yı yapı adına göre bulun, burada ea sid = idc.LocByName (% yapı adı%) ile aynıdır eğer sid == idaapi.BADADDR: return # tüm çapraz referansları al ' sid 'global # struct örneklerine referanslar ve yerel yığın değişkenlerine referanslar dahil frm = [x.frm for x in idautils.XrefsTo (sid)] for ea in ea in frm: if ea > idc.MaxEA (): # yığın değişkenlerine referanslar # IDA 6.8 ve üstü: 'ea' kullanarak 'member_t' alma mptr = idaapi.get_member_by_id (ea) # IDA 6.8: 'mpt kullanarak üye yorumu ayarlama r 'indeksi olarak idaapi.set_member_cmt (mptr, cmt, tekrarlanabilir) # IDA 6.9:' mptr 'liste türüdür # idaapi.set_member_cmt (mptr [0], cmt, tekrarlanabilir) başka: # tekrarlanabilirse global yapı örneklerine referanslar : # tekrarlanabilir açıklama kimliği eklec.MakeRptCmt (ea, cmt) else: # tekrarlanamayan açıklama kimliği eklec.MakeCmt (ea, cmt)  
NOT: 1. API * get_member_by_id *, IDA 6.6'da mevcut değildir, ancak bu, * sid = idaapi.get_member_struc (idaapi.get_member_fullname (mid)) * gibi diğer API'ler tarafından atlanabilir ve ardından üyelerini numaralandırabilir
NOT: IDA 6.8'de, * idaapi.get_member_by_id * 'member_t *' türünde bir proxy döndürür, ancak IDA 6.9'da döndürdüğü şey bir listedir ve 'member_t *' türündeki proxy 1. öğedir.


Bu Soru-Cevap, otomatik olarak İngilizce dilinden çevrilmiştir.Orijinal içerik, dağıtıldığı cc by-sa 3.0 lisansı için teşekkür ettiğimiz stackexchange'ta mevcuttur.
Loading...