Örnek olay incelemesi * DX-Ball 1.07

DX-Ball'YU yeniden oluşturma
yürütülebilir dosyasından.

Amaç, 1996 Windows oyununun sürdürülebilir bir C versiyonudur. REA, acentenin orijinali, her seferinde bir işlevi incelemesine yardımcı olur.

Windows ı386 * C * REA

DXBALL.EXE işlevi 0x00406400, REA ile denetlenir. Tuğlaya çarpan bir arayan, 20 artı 30 kez tile_x sağlar. Talimatlar x'i yükleyin, 1.5625 ile çarpın, 500.0'ı çıkarın, pan_scale uygulayın ve bir tamsayı döndürün. Tutulan C, 3.205 durumda orijinal x86'ya karşı bağımsız olarak ve 63 baytla eşleşen VC4.0 derleyici tekrarı ile kontrol edilir.
REA talimatları, arayanları ve veri okumalarını sağlar; yeniden yapılandırma projesi sonucu uygular ve test eder. Açık şekil
55
tutulan C fonksiyonları
45,380
orijinal kodla karşılaştırmalar
33
eşleşen derlenmiş baytlara sahip işlevler

Proje kontrol noktası: 7 Ekim 2026. İlerleme defteri * Test kapsamı

Proje şu ana kadar

Kurtarılan kod, tahta ve kaynak işlemeyi, tuğla vuruşlarını, animasyonları, parçacıkları ve bonus üretimini kapsar. Mevcut yapılar, denetim yardımcı programları ve bir analiz kitaplığı sağlar. Oynanabilir oyun üzerindeki çalışmalar top ve kürek fiziği, güçlendirme kullanımı ve Windows entegrasyonu ile devam ediyor.

Sol / sağ ses konumunun hesaplanmasını bulma

Bir tuğla vurulduğunda, yatay konumu ses koduna geçirilir. Soruşturma, bu ekran koordinatının nasıl sola / sağa kaydırma değeri haline geldiğini kurtarmak için gerekliydi.

Kodlama aracınız

DX-Ball'NUN stereo ses konumlandırmasını nasıl hesapladığını bulmak için REA kullanın. Hesaplamayı açıklayın ve kodu gösterin.

Yerel yürütülebilir dosyanın bulunduğu kodlama aracınız için örnek bir komut istemi. Aşağıdaki araştırma, REA sorgularını ve cevabın arkasındaki kanıtları göstermektedir.

Aracı, işlevi incelemek, tuğlaya çarpan arayanını takip etmek ve yürütülebilir dosyadaki sabitleri okumak için REA kullandı. Bu sonuçlar, aşağıdaki C işlevini yazmak için gereken girdi ve aritmetiği sağladı.

0x406400 için ilk işlev sonucu0x406400, FUN_00406400 FUN_00406400(void) bildiren ve __ftol() öğesini çağıran sözde kodu içeriyordu. Talimat görünümü bir yığın girişi ve kayan nokta işlemleri gösterdi. Bu tutarsızlık, ajana araştırmaya devam etmesi için somut bir neden verdi.

İlk decompiler görünümü
REA sonuç * sözde kod alıntısı
longlong FUN_00406400(void)
{
  longlong lVar1;

  lVar1 = __ftol();
  return lVar1;
}

Çıktı bir dönüşüm çağrısı gösterir. Aşağıdaki talimatları okumak, o çağrıyı besleyen girdiyi ve hesaplamayı ortaya çıkarır.

REA aracılığıyla yanıtlanan üç soru

  1. Eksik girdiyi kurtar

    Ajan → REA * analyze_function
    {"procedure": "0x406400"}
    REA → ajan * talimat alıntısı
    0x406409: MOV EAX, dword ptr [EBP + 0x8]
    0x40640c: MOV dword ptr [EBP + -0xc], EAX
    0x40640f: FILD dword ptr [EBP + -0xc]

    İşlev sonucu, sahte kod ve arayanların yanı sıra talimatları içerir. Burada, [EBP+8] kod çözücü görünümünde eksik olan tamsayı girdisini gösterir.

  2. Girişi anlamak için arayanı takip edin

    Ajan → REA * analyze_function
    {"procedure": "0x411f40"}
    REA → temsilci * arayan alıntı
    0x411f5b: ADD EAX, 0x14
    0x411f5e: PUSH EAX
    0x411f5f: CALL 0x00406400

    REA bu arayanı ilk sonuçta tanımladı. Önceki talimatları tile_xtile_x'i 30'a ölçeklendirir; 20 eklemek tuğlanın ekran koordinatını verir, 20 + 30 × tile_x.

  3. Bellek adreslerinin arkasındaki değerleri okuyun

    Aracı → REA * iki read_bytes isteği
    {"address": "0x420068", "length": 16}
    {"address": "0x4210a0", "length": 8}
    REA bayt sonuçları * çiftler olarak deşifre edildi
    000000000000f93f → 1.5625
    0000000000407f40 → 500.0
    000000000000f03f → 1.0

    Döndürülen baytlar, iki aritmetik sabiti ve ilk kaydırma ölçeğini oluşturur. Aracı artık C ifadesi için gereken değerlere sahiptir.

REA'NUN bulgularından C'ye

Aşağıdaki beş adımı izleyin. Her seçim, orijinal talimatları ve bildirdikleri C satırlarını vurgular.

Orijinal x86 * alıntı
0x406409: MOV EAX, dword ptr [EBP + 0x8]
0x40640c: MOV dword ptr [EBP + -0xc], EAX
0x40640f: FILD dword ptr [EBP + -0xc]
0x406415: FMUL double ptr [0x00420068]
0x40641e: FSUB double ptr [0x00420070]
0x406427: FMUL double ptr [0x004210a0]
0x406430: CALL 0x0041678c
0x40643e: RET
Yeniden inşa edilmiş C
DxBallInt dxball_screen_pan(DxBallInt x)
{
    double pan;
    pan = (double)x;
    pan = pan * 1.5625;
    pan = pan - 500.0;
    pan = pan * dxball_pan_scale;
    return (DxBallInt)pan;
}

01 * Girişi okuyun. Talimat görünümü REA işlev sonucu okur [EBP+8] ve kullanır FILD tamsayıyı yüklemek için. Arayanı REA aracılığıyla takip etmek, C parametresi x ekran koordinat anlamını belirler.

Derleme alıntısı giriş, aritmetik ve dönüş talimatlarını seçer. Aşağıdaki tam liste, araya giren depoları ve işlev kurulumunu ve temizlemeyi de içerir.

Tam montaj ve destekleyici kanıtlar
REA sonucu * 0x406400-0x40643e
0x406400: PUSH EBP
0x406401: MOV EBP, ESP
0x406403: SUB ESP, 0xc
0x406406: PUSH EBX
0x406407: PUSH ESI
0x406408: PUSH EDI
0x406409: MOV EAX, dword ptr [EBP + 0x8]
0x40640c: MOV dword ptr [EBP + -0xc], EAX
0x40640f: FILD dword ptr [EBP + -0xc]
0x406412: FST double ptr [EBP + -0x8]
0x406415: FMUL double ptr [0x00420068]
0x40641b: FST double ptr [EBP + -0x8]
0x40641e: FSUB double ptr [0x00420070]
0x406424: FST double ptr [EBP + -0x8]
0x406427: FMUL double ptr [0x004210a0]
0x40642d: FST double ptr [EBP + -0x8]
0x406430: CALL 0x0041678c
0x406435: JMP 0x0040643a
0x40643a: POP EDI
0x40643b: POP ESI
0x40643c: POP EBX
0x40643d: LEAVE
0x40643e: RET

Arayan ne sağlar

0x411f40 değerindeki tuğla çarpma işlevi0x411f40, döşeme koordinatını 30 ölçeklendirir, 20 ekler ve ardından çağrıdan önce iter:

0x411f50: MOV EAX, dword ptr [EBP + 0x8]
0x411f53: ADD EAX, EAX
0x411f55: LEA EAX, [EAX + EAX*0x2]
0x411f58: LEA EAX, [EAX + EAX*0x4]
0x411f5b: ADD EAX, 0x14
0x411f5e: PUSH EAX
0x411f5f: CALL 0x00406400
0x411f64: ADD ESP, 0x4

Verilerin okuduğu şey

REA bayt okur, küçük uçlu çiftler olarak çözülür
Adres Değer İçin kullanılır
0x420068 1.5625 İlk çarpma
0x420070 500.0 Çıkarma
0x4210a0 1.0 başlangıçta Saklanan pan ölçeği

Karma sabitlenmiş DX-Ball 1.07 hedefi için REA 4.1.0 ile kaydedildi. Bağlantılı soruşturma notları Kanıt Kimliklerini saklar.

Tutulan kaynak * Soruşturma notları ve kanıt referansları

Kurtarılan işlevi kontrol etme

Kurtarılan işlev iki denetimden geçer: dönüş değerleri orijinaliyle eşleşir ve derlenmiş baytları yürütülebilir dosyayla eşleşir.

3.205 davranış vakası

Testler orijinal x86 işlevini yürütür ve dönüş değerini tutulan C ile karşılaştırır. 0, 0,5, 1, 20 ve -1 olmak üzere beş kaydırma ölçeğinde 0'dan 640'a kadar olan her tamsayı konumunu kapsar.

63 eşleşen bayt

C işlevi, sabitlenmiş VC4.0 araç zinciri ile derlenir. Derleyici tekrarı, gözden geçirilen yer değiştirmeleri uyguladıktan ve başvurulan sabitleri kontrol ettikten sonra tam işlevle eşleşir.

1 Ölçeğinde, kurtarılan hesaplama sol kenarda -500, merkezde 0 ve sağ kenarda 500 döndürür. Ses çalışmasının bir sonraki kısmı, bu değeri oyunun ses arka ucuyla bütünleştirmektir.

Derleyici tekrar ayrıntılarını okuyun

Soruşturmaya devam et

Aynı yaklaşım parçacık güncellemeleri, patlama kuyrukları ve bonus üretimi için de kullanılıyor: ilgili işlevleri inceleyin, durumlarını ve bağımlılıklarını kurtarın, ardından uygulamayı orijinaliyle karşılaştırın.

Ses kaydırma işlevini kendiniz incelemek için DX-Ball projesinin kurulum talimatlarını izleyin ve eşleşen orijinal hedefini sağlayın. Sonra koş:

DX-Ball kasasında
scripts/rea function original/DXBALL.EXE 0x00406400 \
  --snapshot .analysis/rea/dxball.snapshot.json --json

Üst