Soru:
IDA PRO Yapıları Negatif ofsetin tanımlanması -4-8 ofset onarım asm Hex-Rays
SSpoke
2013-12-31 08:29:56 UTC
view on stackexchange narkive permalink

IDA PRO'daki yapıları Hex-Rays eklentisinde (C decompiler) düzgün şekilde görünmeleri için nasıl düzeltirim.

Şuna benzer soru: (Ancak çözüm benim için çalışmıyor)
IDA'da negatif ofset ile yapı mümkündür

Hemen hemen ne oldu, çok iyi bir program derlemem ve hemen çalışıyor, ondan sonra birçok değişiklik yaptım ve şimdi çalışıyor daha kötüsü eski sürümden daha kötü, eski sürüme geri dönmek için neyi yanlış yaptığımı anlamaya çalışıyorum (kaynak kodunu şimdi kaybettiğim için). (Ayrıca, her iki sürüm arasında değişmeyen, C ++ ile yazılmış orijinal kod parçasının altına da ekledim).

Yapının adresleri bir şekilde IDA PROSuch'da şu şekilde optimize edilmiştir

  * (_ BYTE *) (Gemi Kasası + 279) = 1; //Ships[i].used = true;  

gerçekten [10x4] = 40 + 255 = 295

  * (_ BYTE *) (Gemi Kasası + 295) = 1; //Ships[i].used = true;  

Yapı boyutunu buradan söyleyebilirsiniz ( shipStruct + = 296; )

Kullanılmayan yapı elemanlarının bir şekilde çıkarıldığını tahmin ediyorum (ama yapı boyutu neden geçerli?)
Montajın bir şekilde yanlış kaydırılmış gibi görünüyor (düzeltmek için uygun ofset deltalarını yapıya nasıl ekleyebilirim? this)?

Bu ipucunu denediğimde http://www.hexblog.com/?p=63 satırını seçtiğimde IDA PRO'nun tamamı donuyor mov edi, offset dword_10004C38 ve T'ye basın (IDA PRO 6.1)

structoffset

Yapımımı yanlış yapmışım gibi görünüyor?

Kod çözülmüş kod (yapıyı uygulamadan) şu şekilde görünür:

  if (playerListBaseAddress &&! IsBadReadPtr (playerListBaseAddress, 4u)) {shipStruct = (int) dword_10004C38; while (1) {playerPointer = (struct_v3 *) * ((_ DWORD *) playerListBaseAddress + maxPlayers); eğer (! playerPointer) bozulursa; eğer (IsBadReadPtr (playerPointer, 4u)) break; * (_ DWORD *) (shipStruct - 4) = playerPointer->ssXCoord;
* (_ DWORD *) shipStruct = playerPointer->ssYCoord; * (_ DWORD *) (shipStruct + 4) = playerPointer->ssXSpeed; * (_ DWORD *) (shipStruct + 8) = playerPointer->ssYSpeed; * (_ DWORD *) (shipStruct - 8) = playerPointer->ssFreq; * (_ DWORD *) (shipStruct + 20) = playerPointer->ssShipNum; if (playerPointer->ssPlayerName) strcpy_s ((char *) (shipStruct + 24), 0xFFu, &playerPointer->ssPlayerName); * (_ BYTE *) (Gemi Kasası + 279) = 1; eğer (v37 == playerPointer) kesilirse; Gemiler Yapısı + = 296; ++ maxPlayers; v37 = playerPointer; eğer (gemiler > = (imzalı int) &unk_10017310) bitirmeye git; } v34 = maxPlayers; eğer (maxPlayers < 255) {v4 = (int) ((char *) &unk_10004D4F + 296 * maxPlayers); {* (_ BYTE *) v4 = 0; v4 + = 296; } while (v4 < (imzalı int) &unk_10017427); }  

İşte orjinal kod (C ++ ile yazılmamış)

  double currentTimer = GetTimer (); double timeElapsed = currentTimer - lastTimer; int maxPlayers = 0; DWORD lastPlayerPtr = 0; if (playerListBaseAddress! = NULL &&! IsBadReadPtr ((void *) playerListBaseAddress, sizeof (ULONG_PTR))) {for (int i = 0; i < 255; i ++) {// oyuncuyu doldur liste. DWORD playerPtr = * (DWORD *) (playerListBaseAddress + (i * 4)); eğer (playerPtr! = NULL &&! IsBadReadPtr ((void *) playerPtr, sizeof (ULONG_PTR))) {Ships [i] .XCoordinate = * (DWORD *) (playerPtr + 0x4); Gemiler [i] .YCoordinate = * (DWORD *) (playerPtr + 0x8); Gemiler [i] .XSpeed ​​= * (uzun imzalı *) (playerPtr + 0x10); Gemiler [i] .YSpeed ​​= * (uzun imzalı *) (playerPtr + 0x14); Gemiler [i] .Freq = * (DWORD *) (playerPtr + 0x58); Gemiler [i] .ShipNum = * (BYTE *) (playerPtr + 0x5C)
//memcpy(&(Ships[i].Name), (void *) ((DWORD) playerPtr + 0x6D), 19); eğer (! * (BYTE *) (playerPtr + 0x6D) == NULL) strcpy_s (Gemiler [i] .Name, (char *) ((DWORD) playerPtr + 0x6D)); Gemiler [i] .used = true; eğer (lastPlayerPtr == playerPtr) finishList'e git; lastPlayerPtr = playerPtr; } else {finishList: maxPlayers = i; for (int j = i; j < 255; j ++) Gemiler [j] .used = false; kırmak; }}  

İşte öncesi ve sonrası (özel yapımı uygulayarak)
Özel yapıyı bir sürü Dizi (* anahtar) yaparak ve ardından uygun boyutları ayarlayarak yaptım. (Bunun IDA PRO'da bir yapı oluşturmanın doğru yolu olmadığını tahmin etmek?) struct
Önce:
before
Sonra:
after
ASM:
asm
Düzenleme İşlevi
edit function
Çift tıklanan yerel değişken
dbl click local variables

Iki yanıtlar:
Igor Skochinsky
2014-01-03 19:32:42 UTC
view on stackexchange narkive permalink

Bu özellik Hex-Rays 1.6'dan beri desteklenmektedir:

http://www.hexblog.com/?p=544

(bkz. bölüm 3. CONTAINING_RECORD makro)

Jason Geffner
2013-12-31 08:39:00 UTC
view on stackexchange narkive permalink

Yukarıdan ...

Derlenmiş:

  * (_ DWORD *) (shipStruct - 4) = playerPointer->ssXCoord; * (_DWORD *) shipStruct = playerPointer->ssYCoord; ...  

Orijinal:

  Gemiler [i] .XCoordinate = * (DWORD *) (playerPtr + 0x4); Gemiler [i] .YCoordinate = * (DWORD *) (playerPtr + 0x8); ...  

Bu parçacıklara göre Yığın değişkenlerinizdeki yapı 8 bayt kapalı gibi. Bizimle bu fonksiyon için yığın değişken listesini paylaşabilir misiniz? (Yığın görünümünü açmak için derlemedeki yerel değişkenlerden birine çift tıklayın.)

Bunun hakkında konuşmak? http://i.stack.imgur.com/2rANk.png burada: http://i.stack.imgur.com/9vKkW.png
Bu `db'leri silme riskini almalı mıyım? ; undefined` yukarıda? ve IDA analizi bunu nasıl alt üst etti. 12 bayt kapalı görünüyor (Tüm işlevler hatasız btw derleme)
Tamam, "0x68" den "0x5C" ye değiştirdim, şimdi tüm tanımsızlar gitti "var_5C" den başlıyor ve her şey aynı görünüyor, yığın değişkenlerine tıklandığında artık tanımsız değişken yok.
"ShipStruct" yerel bir değişken mi yoksa global bir değişken mi?
Pekala, "shipStruct", "(int) dword_10004C38" den yerel olarak bildirildi; bu, bellekte küresel bir konum gibi görünüyor ve sanırım bir şekilde ofset yapısını temsil etmesi gerekiyor. "shipStruct", ona verdiğim isim, gerçekten "ShipStruct" a dönüştürülmesi gerekiyor. Bunu struct * `shipStruct = (ShipStruct *) dword_10004C38; yapısına dönüştürdüğümde böyle oluyor
Global bir yapıya sadece yerel bir gösterici olsa bile, işlev için yığın değişkeni listesinde olmaması garip. Doğru işlevin yığın listesi için ekran görüntüsünü gönderdiğinizden emin misiniz?
Evet, Yerel Yığın Değişkenlerinde olmadı. Hex-Rays'de kod çözme sırasında üretiliyor gibi görünüyor. 'edi`' ShipStruct * shipStruct; // edi@3` yapıya dönüştürüldükten sonra ve bu `int shipStruct gibi görünmeden önce; // edi@3`, Yığın sadece 13 göstermesine rağmen yaklaşık 48 yerel değişken üretir.
Dosyayı yeniden açtı ve şimdi herhangi bir düzenleme yapmadan bunu oluşturuyor. `v1 = (işaretli int) dword_10004C38;` `imzalı int v1; // edi@3` (hala yerel yığın değişkeni listesinde değil)


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...