---
title: 'Αντίστροφη μηχανική του DX-Ball: Στερεοφωνική θέση του ήχου — REA'
url: https://rea.tools/el/showcase/dx-ball/
---

[Αρχική](https://rea.tools/el/) / [Μελέτες](https://rea.tools/el/showcase/) / DX-Ball

Μελέτη · DX-Ball 1.07

# Ανακατασκευή του DX-Ball από το εκτελέσιμό του.

Στόχος είναι μια συντηρήσιμη έκδοση σε C του παιχνιδιού για Windows του 1996. Με το REA, ο βοηθός εξετάζει το πρωτότυπο, μία συνάρτηση κάθε φορά.

Windows i386 · C · REA

![Η συνάρτηση 0x00406400 του DXBALL.EXE εξετάζεται με το REA. Ένας καλών για τα χτυπήματα τούβλων παρέχει 20 συν 30 επί tile_x. Οι εντολές φορτώνουν το x, πολλαπλασιάζουν επί 1.5625, αφαιρούν 500.0, εφαρμόζουν το pan_scale και επιστρέφουν έναν ακέραιο. Ο συντηρούμενος κώδικας C ελέγχεται ανεξάρτητα έναντι του αρχικού κώδικα x86 σε 3,205 περιπτώσεις και με αναπαραγωγή μεταγλώττισης VC4.0 που ταιριάζει σε 63 byte.](https://rea.tools/assets/localized/el/figures/dx-ball-sound-pan-investigation.svg)

Μία συνάρτηση, από το εκτελέσιμο σε ελεγμένο κώδικα C. Το REA παρέχει τις εντολές, τους καλούντες και τις αναγνώσεις δεδομένων· το έργο ανακατασκευής υλοποιεί και δοκιμάζει το αποτέλεσμα. [Ανοίξτε το σχήμα](https://rea.tools/assets/localized/el/figures/dx-ball-sound-pan-investigation.svg)

55
:   συντηρούμενες συναρτήσεις C

45,380
:   συγκρίσεις με τον αρχικό κώδικα

33
:   συναρτήσεις με ίδια μεταγλωττισμένα byte

Ορόσημο του έργου: 7 Οκτωβρίου 2026. [Καταγραφή προόδου](https://github.com/N0zoM1z0/dx-ball/blob/a55dca27ec0a07018c1b2c95ae2be027f7d8c3c4/docs/PROGRESS.md) · [Κάλυψη δοκιμών](https://github.com/N0zoM1z0/dx-ball/blob/a55dca27ec0a07018c1b2c95ae2be027f7d8c3c4/docs/ORACLES.md)

## Το έργο μέχρι σήμερα

Ο ανακτημένος κώδικας καλύπτει τον χειρισμό της πίστας και των πόρων, τα χτυπήματα τούβλων, τα κινούμενα γραφικά, τα σωματίδια και την παραγωγή μπόνους. Οι τρέχουσες μεταγλωττίσεις παρέχουν βοηθητικά εργαλεία εξέτασης και μια βιβλιοθήκη ανάλυσης. Η ανάπτυξη μιας έκδοσης που μπορεί να παιχτεί συνεχίζεται με τη φυσική της μπάλας και της ρακέτας, τον χειρισμό ενισχύσεων και την ενσωμάτωση στα Windows.

## Εύρεση του υπολογισμού της στερεοφωνικής θέσης του ήχου

Όταν χτυπιέται ένα τούβλο, η οριζόντια θέση του περνά στον κώδικα ήχου. Η διερεύνηση έπρεπε να ανακτήσει πώς αυτή η συντεταγμένη οθόνης γίνεται τιμή στερεοφωνικής τοποθέτησης αριστερά/δεξιά.

Ο βοηθός προγραμματισμού σας

Χρησιμοποιήστε το REA για να βρείτε πώς το DX-Ball υπολογίζει τη στερεοφωνική θέση του ήχου. Εξηγήστε τον υπολογισμό και δείξτε τον κώδικα.

Παράδειγμα προτροπής για τον βοηθό προγραμματισμού σας, με το εκτελέσιμο διαθέσιμο τοπικά. Η παρακάτω διερεύνηση δείχνει τα ερωτήματα στο REA και τα στοιχεία πίσω από την απάντηση.

Ο βοηθός χρησιμοποίησε το REA για να εξετάσει τη συνάρτηση, να ακολουθήσει τον καλούντα της για τα χτυπήματα τούβλων και να διαβάσει τις σταθερές από το εκτελέσιμο. Αυτά τα αποτελέσματα παρείχαν την είσοδο και την αριθμητική που χρειάζονταν για τη συγγραφή της παρακάτω συνάρτησης C.

Το πρώτο αποτέλεσμα συνάρτησης για την `0x406400` περιλάμβανε ψευδοκώδικα που δήλωνε `FUN_00406400(void)` και καλούσε την `__ftol()`. Η προβολή εντολών του έδειχνε είσοδο στη στοίβα και πράξεις κινητής υποδιαστολής. Αυτή η διαφορά έδωσε στον βοηθό έναν συγκεκριμένο λόγο να συνεχίσει τη διερεύνηση.

Η πρώτη προβολή του απομεταγλωττιστή

Αποτέλεσμα REA · απόσπασμα ψευδοκώδικα

```
longlong FUN_00406400(void)
{
  longlong lVar1;

  lVar1 = __ftol();
  return lVar1;
}
```

Η έξοδος δείχνει μια κλήση μετατροπής. Η ανάγνωση των παρακάτω εντολών αποκαλύπτει την είσοδο και τον υπολογισμό που τροφοδοτεί αυτή την κλήση.

### Τρεις ερωτήσεις που απαντήθηκαν μέσω του REA

1. #### Ανακτήστε την είσοδο που λείπει

   Βοηθός → REA · `analyze_function`

   ```
   {"procedure": "0x406400"}
   ```

   REA → βοηθός · απόσπασμα εντολών

   ```
   0x406409: MOV EAX, dword ptr [EBP + 0x8]
   0x40640c: MOV dword ptr [EBP + -0xc], EAX
   0x40640f: FILD dword ptr [EBP + -0xc]
   ```

   Το αποτέλεσμα συνάρτησης περιλαμβάνει εντολές μαζί με ψευδοκώδικα και καλούντες. Εδώ, το `[EBP+8]` αποκαλύπτει την ακέραια είσοδο που λείπει από την προβολή του απομεταγλωττιστή.
2. #### Ακολουθήστε τον καλούντα για να κατανοήσετε την είσοδο

   Βοηθός → REA · `analyze_function`

   ```
   {"procedure": "0x411f40"}
   ```

   REA → βοηθός · απόσπασμα καλούντος

   ```
   0x411f5b: ADD EAX, 0x14
   0x411f5e: PUSH EAX
   0x411f5f: CALL 0x00406400
   ```

   Το REA εντόπισε αυτόν τον καλούντα στο πρώτο αποτέλεσμα. Οι προηγούμενες εντολές του πολλαπλασιάζουν το `tile_x` επί 30· η πρόσθεση του 20 δίνει τη συντεταγμένη οθόνης του τούβλου, `20 + 30 × tile_x`.
3. #### Διαβάστε τις τιμές πίσω από τις διευθύνσεις μνήμης

   Βοηθός → REA · δύο αιτήματα `read_bytes`

   ```
   {"address": "0x420068", "length": 16}
   {"address": "0x4210a0", "length": 8}
   ```

   Αποτελέσματα byte του REA · αποκωδικοποιημένα ως αριθμοί διπλής ακρίβειας

   ```
   000000000000f93f → 1.5625
   0000000000407f40 → 500.0
   000000000000f03f → 1.0
   ```

   Τα επιστρεφόμενα byte τεκμηριώνουν τις δύο αριθμητικές σταθερές και την αρχική κλίμακα στερεοφωνικής θέσης. Ο βοηθός έχει πλέον τις τιμές που χρειάζονται για την έκφραση C.

### Από τα ευρήματα του REA σε C

Ακολουθήστε τα πέντε παρακάτω βήματα. Κάθε επιλογή επισημαίνει τις αρχικές εντολές και τις γραμμές C που βασίστηκαν σε αυτές.

Αρχικός κώδικας x86 · απόσπασμα

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

Ανακατασκευασμένος κώδικας 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 · Διαβάστε την είσοδο.** Η προβολή εντολών στο αποτέλεσμα συνάρτησης του REA διαβάζει το `[EBP+8]` και χρησιμοποιεί τη `FILD` για να φορτώσει τον ακέραιο. Η παρακολούθηση του καλούντος μέσω του REA τεκμηριώνει ότι η παράμετρος C `x` είναι συντεταγμένη οθόνης.

**02 · Πολλαπλασιάστε επί 1.5625.** Η `FMUL` διαβάζει τον αριθμό διπλής ακρίβειας στη `0x420068`. Τα byte που επιστρέφει η `read_bytes` του REA αποκωδικοποιούνται σε `1.5625`· ο κώδικας C χρησιμοποιεί την ίδια σταθερά.

**03 · Αφαιρέστε 500.0.** Η `FSUB` διαβάζει τον αριθμό διπλής ακρίβειας στη `0x420070`. Το αποτέλεσμα byte του REA αποκωδικοποιείται σε `500.0`, μετατοπίζοντας το κέντρο του υπολογισμού στη συντεταγμένη οθόνης `320`.

**04 · Εφαρμόστε την αποθηκευμένη κλίμακα.** Η δεύτερη `FMUL` διαβάζει τη `0x4210a0`. Αυτή η καθολική μεταβλητή ονομάζεται `dxball_pan_scale` στον συντηρούμενο πηγαίο κώδικα. Η δεύτερη ανάγνωση byte του REA τεκμηριώνει την αρχική τιμή της, `1.0`.

**05 · Επιστρέψτε έναν ακέραιο.** Η κλήση στη `0x406430` φτάνει στην `__ftol`, που εντοπίστηκε στα αποτελέσματα καλούμενων συναρτήσεων του REA. Ο κώδικας C μετατρέπει το αποτέλεσμα σε `DxBallInt`· οι συγκρίσεις με τον αρχικό κώδικα x86 ελέγχουν την επιστρεφόμενη τιμή.

Το απόσπασμα assembly επιλέγει τις εντολές εισόδου, αριθμητικής και επιστροφής. Η πλήρης καταγραφή παρακάτω περιλαμβάνει επίσης τις ενδιάμεσες αποθηκεύσεις, την προετοιμασία και τον καθαρισμό της συνάρτησης.

Πλήρης κώδικας assembly και υποστηρικτικά στοιχεία

Αποτέλεσμα REA · 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
```

### Τι παρέχει ο καλών

Η συνάρτηση χτυπήματος τούβλου στη `0x411f40` πολλαπλασιάζει τη συντεταγμένη πλακιδίου της επί 30, προσθέτει 20 και έπειτα την ωθεί στη στοίβα πριν από την κλήση:

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

### Τι τεκμηριώνουν οι αναγνώσεις δεδομένων

Αναγνώσεις byte του REA, αποκωδικοποιημένες ως αριθμοί διπλής ακρίβειας little-endian

| Διεύθυνση | Τιμή | Χρήση |
| --- | --- | --- |
| `0x420068` | `1.5625` | Πρώτος πολλαπλασιασμός |
| `0x420070` | `500.0` | Αφαίρεση |
| `0x4210a0` | `1.0` αρχικά | Αποθηκευμένη κλίμακα στερεοφωνικής θέσης |

Καταγράφηκε με REA 4.1.0 για τον στόχο DX-Ball 1.07 που ταυτοποιείται με συγκεκριμένο κατακερματισμό. Οι συνδεδεμένες σημειώσεις διερεύνησης διατηρούν τα αναγνωριστικά Evidence.

[Συντηρούμενος πηγαίος κώδικας](https://github.com/N0zoM1z0/dx-ball/blob/a55dca27ec0a07018c1b2c95ae2be027f7d8c3c4/src/gameplay.c#L41) · [Σημειώσεις διερεύνησης και αναφορές στοιχείων](https://github.com/N0zoM1z0/dx-ball/blob/a55dca27ec0a07018c1b2c95ae2be027f7d8c3c4/docs/GAMEPLAY_OWNER.md)

## Έλεγχος της ανακτημένης συνάρτησης

Η ανακτημένη συνάρτηση περνά δύο ελέγχους: οι επιστρεφόμενες τιμές της συμφωνούν με το πρωτότυπο και τα μεταγλωττισμένα byte της συμφωνούν με το εκτελέσιμο.

### 3,205 περιπτώσεις συμπεριφοράς

Οι δοκιμές εκτελούν την αρχική συνάρτηση x86 και συγκρίνουν την επιστρεφόμενη τιμή της με τον συντηρούμενο κώδικα C. Καλύπτουν κάθε ακέραια θέση από 0 έως 640 σε πέντε κλίμακες στερεοφωνικής θέσης: 0, 0.5, 1, 20 και −1.

### 63 ίδια byte

Η συνάρτηση C μεταγλωττίζεται με τη συγκεκριμένη αλυσίδα εργαλείων VC4.0. Η αναπαραγωγή της μεταγλώττισης ταιριάζει με ολόκληρη τη συνάρτηση μετά την εφαρμογή των ελεγμένων μετεγκαταστάσεων και τον έλεγχο των αναφερόμενων σταθερών.

Με κλίμακα 1, ο ανακτημένος υπολογισμός επιστρέφει −500 στο αριστερό άκρο, 0 στο κέντρο και 500 στο δεξί άκρο. Το επόμενο μέρος της εργασίας στον ήχο είναι η ενσωμάτωση αυτής της τιμής στο υποσύστημα ήχου του παιχνιδιού.

[Διαβάστε τις λεπτομέρειες αναπαραγωγής της μεταγλώττισης](https://github.com/N0zoM1z0/dx-ball/blob/a55dca27ec0a07018c1b2c95ae2be027f7d8c3c4/docs/BUILD_MATCHING.md)

## Συνεχίστε τη διερεύνηση

Η ίδια προσέγγιση χρησιμοποιείται για ενημερώσεις σωματιδίων, ουρές εκρήξεων και δημιουργία μπόνους: εξέταση των σχετικών συναρτήσεων, ανάκτηση της κατάστασης και των εξαρτήσεών τους και έπειτα σύγκριση της υλοποίησης με το πρωτότυπο.

Για να εξετάσετε μόνοι σας τη συνάρτηση στερεοφωνικής θέσης του ήχου, ακολουθήστε τις οδηγίες εγκατάστασης του έργου DX-Ball και παρέχετε τον αντίστοιχο αρχικό στόχο του. Έπειτα εκτελέστε:

Στο τοπικό αντίγραφο του αποθετηρίου DX-Ball

```
scripts/rea function original/DXBALL.EXE 0x00406400 \
  --snapshot .analysis/rea/dxball.snapshot.json --json
```

- [Αποθετήριο DX-Ball](https://github.com/N0zoM1z0/dx-ball)Τρέχων πηγαίος κώδικας, πρόοδος και τοπική εγκατάσταση.
- [Ροή ανάλυσης REA](https://rea.tools/guides/native/)Ακολουθήστε τον υπολογισμό και έπειτα χρησιμοποιήστε την ίδια προσέγγιση με το δικό σας δυαδικό αρχείο.
- [Σωματίδια και παραγωγή μπόνους](https://github.com/N0zoM1z0/dx-ball/blob/a55dca27ec0a07018c1b2c95ae2be027f7d8c3c4/docs/ENTITIES_OWNER.md)Μια μεγαλύτερη διερεύνηση της κατάστασης, των ουρών και των εγγραφών pixel.

[Ξεκινήστε με τον δικό σας στόχο](https://rea.tools/get-started/)
