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)
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?)
Önce:
Sonra:
ASM:
Düzenleme İşlevi
Çift tıklanan yerel değişken