Root-Me: GB – Walkthrough-ul crackme-ului Basic GameBoy

  • 1 minute de citit
  • 2 exemple de cod
  • 4 imagini

Disponibil și în English

Salut,

În acest articol voi descrie cum am rezolvat provocarea GB – Basic GameBoy crackme de pe Root-Me.

Înainte de a citi acest articol ar trebui să încerci să rezolvi provocarea pe cont propriu. Începe prin a citi sau a parcurge rapid manualul CPU-ului GameBoy, apoi descarcă un emulator precum mGba și joacă-te cu ROM-ul. Pentru a dezasambla ROM-ul am folosit Ghidra și mgbdis.


După ce am citit manualul CPU-ului GameBoy, am deschis fișierul în Ghidra și am găsit aceste șiruri interesante:

Dacă emulezi ROM-ul cu mGba și apeși tasta Left, urmată de tasta Enter, pe ecran va apărea mesajul „Left”. Deocamdată pot presupune că șirurile au legătură cu acest mesaj.

Ghidra nu cunoaște structura ROM-ului GameBoy, iar eu nici atât, așa că am încercat să dezasamblez ROM-ul cu ajutorul unui dezasamblor specializat pentru GameBoy:

➜  mgbdis git:(master) ✗ ./mgbdis.py crack_rom.gb Loading "crack_rom.gb"...ROM MD5 hash: 51ff0d38b93107c38a753d9b0ee1576cGenerating labels...Generating disassembly..Disassembly generated in "/home/denis/Downloads/mgbdis/disassembly"

Deschizând rezultatul dezasamblorului și căutând 0459 (adresa șirului Nope), am găsit cod care îl referențiază la adresa 0415.

M-am întors în Ghidra și am dezasamblat blocul de la 0415 apăsând tasta D.

Se pare că acesta este blocul care verifică unele valori din RAM și afișează flag-ul dacă valorile sunt corecte.

Prima comparație se face pentru tasta Left. Se încarcă valoarea de la adresa RAM 0xc0b0 în registrul A.

Registrul A este apoi comparat cu 0x32, iar există un salt condiționat către NopeBlock. JP NZ,NN ;sare dacă Z este resetat

                             LAB_ram_03c0                           ram:03c0 11 b0 c0        LD         DE,0xc0b0        ram:03c3 1a              LD         A,(DE=>DAT_ram_c0b0)        ram:03c4 4f              LD         C,A        ram:03c5 fe 32           CP         0x32        ram:03c7 c2 15 04        JP         NZ,NopeBlock        ram:03ca 18 03           JR         LAB_ram_03cf        ram:03cc c3 15 04        JP         NopeBlock

CP este o scădere din A care nu actualizează A, ci doar flag-urile pe care le-ar seta/reseta dacă scăderea ar fi chiar efectuată. Dacă A == N, atunci flag-ul Z este setat.

Deci, dacă A = 0x32, atunci Z este setat, iar saltul către NopeBlock se face doar dacă Z este resetat. Pare simplu. Pentru a trece verificarea, valoarea de la 0xc0b0 trebuie să fie 0x32.

Dacă ne uităm la vizualizarea memoriei în emulatorul mGba, locația 0xc0b0 are valoarea 0x39. Dacă apăsăm tasta Left, valoarea scade.

Ca să obții flag-ul trebuie să rezolvi pentru tastele Up, Down și Right.

Mulțumesc pentru lectură! <3