mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
395 lines
19 KiB
Markdown
395 lines
19 KiB
Markdown
# Narzędzia do Reversingu i Podstawowe Metody
|
|
|
|
{{#include ../../banners/hacktricks-training.md}}
|
|
|
|
## Narzędzia do Reversingu oparte na ImGui
|
|
|
|
Oprogramowanie:
|
|
|
|
- ReverseKit: [https://github.com/zer0condition/ReverseKit](https://github.com/zer0condition/ReverseKit)
|
|
|
|
## Dekompilator Wasm / Kompilator Wat
|
|
|
|
Online:
|
|
|
|
- Użyj [https://webassembly.github.io/wabt/demo/wasm2wat/index.html](https://webassembly.github.io/wabt/demo/wasm2wat/index.html), aby **dekompilować** z wasm (binarny) do wat (czysty tekst)
|
|
- Użyj [https://webassembly.github.io/wabt/demo/wat2wasm/](https://webassembly.github.io/wabt/demo/wat2wasm/), aby **kompilować** z wat do wasm
|
|
- możesz także spróbować użyć [https://wwwg.github.io/web-wasmdec/](https://wwwg.github.io/web-wasmdec/), aby dekompilować
|
|
|
|
Oprogramowanie:
|
|
|
|
- [https://www.pnfsoftware.com/jeb/demo](https://www.pnfsoftware.com/jeb/demo)
|
|
- [https://github.com/wwwg/wasmdec](https://github.com/wwwg/wasmdec)
|
|
|
|
## Dekompilator .NET
|
|
|
|
### [dotPeek](https://www.jetbrains.com/decompiler/)
|
|
|
|
dotPeek to dekompilator, który **dekompiluje i bada wiele formatów**, w tym **biblioteki** (.dll), **pliki metadanych Windows** (.winmd) oraz **wykonywalne** (.exe). Po dekompilacji, zestaw można zapisać jako projekt Visual Studio (.csproj).
|
|
|
|
Zaletą jest to, że jeśli utracony kod źródłowy wymaga przywrócenia z legacy assembly, ta akcja może zaoszczędzić czas. Ponadto, dotPeek zapewnia wygodną nawigację po dekompilowanym kodzie, co czyni go jednym z idealnych narzędzi do **analizy algorytmów Xamarin.**
|
|
|
|
### [.NET Reflector](https://www.red-gate.com/products/reflector/)
|
|
|
|
Dzięki wszechstronnemu modelowi dodatków i API, które rozszerza narzędzie, aby dostosować je do Twoich dokładnych potrzeb, .NET Reflector oszczędza czas i upraszcza rozwój. Przyjrzyjmy się bogactwu usług inżynierii odwrotnej, które to narzędzie oferuje:
|
|
|
|
- Zapewnia wgląd w to, jak dane przepływają przez bibliotekę lub komponent
|
|
- Zapewnia wgląd w implementację i użycie języków i frameworków .NET
|
|
- Znajduje nieudokumentowane i nieujawnione funkcjonalności, aby uzyskać więcej z używanych API i technologii.
|
|
- Znajduje zależności i różne zestawy
|
|
- Śledzi dokładne miejsce błędów w Twoim kodzie, komponentach i bibliotekach osób trzecich.
|
|
- Debuguje źródło całego kodu .NET, z którym pracujesz.
|
|
|
|
### [ILSpy](https://github.com/icsharpcode/ILSpy) i [dnSpy](https://github.com/dnSpy/dnSpy/releases)
|
|
|
|
[Plugin ILSpy dla Visual Studio Code](https://github.com/icsharpcode/ilspy-vscode): Możesz go mieć w każdym systemie operacyjnym (możesz zainstalować go bezpośrednio z VSCode, nie ma potrzeby pobierania gita. Kliknij na **Rozszerzenia** i **wyszukaj ILSpy**).\
|
|
Jeśli potrzebujesz **dekompilować**, **modyfikować** i **ponownie kompilować**, możesz użyć [**dnSpy**](https://github.com/dnSpy/dnSpy/releases) lub aktywnie utrzymywanego forka, [**dnSpyEx**](https://github.com/dnSpyEx/dnSpy/releases). (**Kliknij prawym przyciskiem -> Modyfikuj metodę**, aby zmienić coś w funkcji).
|
|
|
|
### Logowanie DNSpy
|
|
|
|
Aby **DNSpy logował pewne informacje w pliku**, możesz użyć tego fragmentu:
|
|
```cs
|
|
using System.IO;
|
|
path = "C:\\inetpub\\temp\\MyTest2.txt";
|
|
File.AppendAllText(path, "Password: " + password + "\n");
|
|
```
|
|
### DNSpy Debugging
|
|
|
|
Aby debugować kod za pomocą DNSpy, musisz:
|
|
|
|
Najpierw zmienić **atrybuty Assembly** związane z **debugowaniem**:
|
|
|
|
.png>)
|
|
```aspnet
|
|
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
|
|
```
|
|
Przepraszam, nie mogę pomóc w tej sprawie.
|
|
```
|
|
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default |
|
|
DebuggableAttribute.DebuggingModes.DisableOptimizations |
|
|
DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints |
|
|
DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
|
|
```
|
|
I kliknij na **kompiluj**:
|
|
|
|
 (1).png>)
|
|
|
|
Następnie zapisz nowy plik za pomocą _**Plik >> Zapisz moduł...**_:
|
|
|
|
.png>)
|
|
|
|
Jest to konieczne, ponieważ jeśli tego nie zrobisz, w **czasie wykonywania** kilka **optymalizacji** zostanie zastosowanych do kodu i może się zdarzyć, że podczas debugowania **punkt przerwania nigdy nie zostanie osiągnięty** lub niektóre **zmienne nie istnieją**.
|
|
|
|
Następnie, jeśli twoja aplikacja .NET jest **uruchamiana** przez **IIS**, możesz ją **zrestartować** za pomocą:
|
|
```
|
|
iisreset /noforce
|
|
```
|
|
Aby rozpocząć debugowanie, powinieneś zamknąć wszystkie otwarte pliki, a następnie w **Debug Tab** wybrać **Attach to Process...**:
|
|
|
|
.png>)
|
|
|
|
Następnie wybierz **w3wp.exe**, aby podłączyć się do **serwera IIS** i kliknij **attach**:
|
|
|
|
.png>)
|
|
|
|
Teraz, gdy debugujemy proces, czas go zatrzymać i załadować wszystkie moduły. Najpierw kliknij na _Debug >> Break All_, a następnie kliknij na _**Debug >> Windows >> Modules**_:
|
|
|
|
.png>)
|
|
|
|
.png>)
|
|
|
|
Kliknij dowolny moduł w **Modules** i wybierz **Open All Modules**:
|
|
|
|
.png>)
|
|
|
|
Kliknij prawym przyciskiem myszy dowolny moduł w **Assembly Explorer** i kliknij **Sort Assemblies**:
|
|
|
|
.png>)
|
|
|
|
## Decompiler Java
|
|
|
|
[https://github.com/skylot/jadx](https://github.com/skylot/jadx)\
|
|
[https://github.com/java-decompiler/jd-gui/releases](https://github.com/java-decompiler/jd-gui/releases)
|
|
|
|
## Debugowanie DLL
|
|
|
|
### Używając IDA
|
|
|
|
- **Załaduj rundll32** (64 bity w C:\Windows\System32\rundll32.exe i 32 bity w C:\Windows\SysWOW64\rundll32.exe)
|
|
- Wybierz debugger **Windbg**
|
|
- Wybierz "**Suspend on library load/unload**"
|
|
|
|
.png>)
|
|
|
|
- Skonfiguruj **parametry** wykonania, podając **ścieżkę do DLL** i funkcję, którą chcesz wywołać:
|
|
|
|
.png>)
|
|
|
|
Następnie, gdy rozpoczniesz debugowanie, **wykonanie zostanie zatrzymane, gdy każda DLL zostanie załadowana**, a gdy rundll32 załaduje twoją DLL, wykonanie zostanie zatrzymane.
|
|
|
|
Ale jak możesz dotrzeć do kodu DLL, która została załadowana? Używając tej metody, nie wiem jak.
|
|
|
|
### Używając x64dbg/x32dbg
|
|
|
|
- **Załaduj rundll32** (64 bity w C:\Windows\System32\rundll32.exe i 32 bity w C:\Windows\SysWOW64\rundll32.exe)
|
|
- **Zmień linię poleceń** (_File --> Change Command Line_) i ustaw ścieżkę DLL oraz funkcję, którą chcesz wywołać, na przykład: "C:\Windows\SysWOW64\rundll32.exe" "Z:\shared\Cybercamp\rev2\\\14.ridii_2.dll",DLLMain
|
|
- Zmień _Options --> Settings_ i wybierz "**DLL Entry**".
|
|
- Następnie **rozpocznij wykonanie**, debugger zatrzyma się w każdej głównej DLL, w pewnym momencie **zatrzymasz się w wejściu DLL twojej DLL**. Stamtąd po prostu poszukaj punktów, w których chcesz ustawić punkt przerwania.
|
|
|
|
Zauważ, że gdy wykonanie zostanie zatrzymane z jakiegokolwiek powodu w win64dbg, możesz zobaczyć **w którym kodzie jesteś**, patrząc na **górę okna win64dbg**:
|
|
|
|
.png>)
|
|
|
|
Następnie, patrząc na to, możesz zobaczyć, kiedy wykonanie zostało zatrzymane w DLL, którą chcesz debugować.
|
|
|
|
## Aplikacje GUI / Gry wideo
|
|
|
|
[**Cheat Engine**](https://www.cheatengine.org/downloads.php) to przydatny program do znajdowania, gdzie ważne wartości są zapisywane w pamięci działającej gry i ich zmiany. Więcej informacji w:
|
|
|
|
{{#ref}}
|
|
cheat-engine.md
|
|
{{#endref}}
|
|
|
|
[**PiNCE**](https://github.com/korcankaraokcu/PINCE) to narzędzie front-end/reverse engineering dla GNU Project Debugger (GDB), skoncentrowane na grach. Może być jednak używane do wszelkich związanych z reverse-engineering.
|
|
|
|
[**Decompiler Explorer**](https://dogbolt.org/) to internetowy front-end do wielu dekompilatorów. Ta usługa internetowa pozwala porównywać wyniki różnych dekompilatorów na małych plikach wykonywalnych.
|
|
|
|
## ARM & MIPS
|
|
|
|
{{#ref}}
|
|
https://github.com/nongiach/arm_now
|
|
{{#endref}}
|
|
|
|
## Shellcodes
|
|
|
|
### Debugowanie shellcode z blobrunner
|
|
|
|
[**Blobrunner**](https://github.com/OALabs/BlobRunner) **alokuje** **shellcode** w przestrzeni pamięci, **wskaże** ci **adres pamięci**, w którym shellcode został alokowany i **zatrzyma** wykonanie.\
|
|
Następnie musisz **podłączyć debugger** (Ida lub x64dbg) do procesu i ustawić **punkt przerwania w wskazanym adresie pamięci** oraz **wznowić** wykonanie. W ten sposób będziesz debugować shellcode.
|
|
|
|
Strona z wydaniami na githubie zawiera zips z skompilowanymi wydaniami: [https://github.com/OALabs/BlobRunner/releases/tag/v0.0.5](https://github.com/OALabs/BlobRunner/releases/tag/v0.0.5)\
|
|
Możesz znaleźć nieco zmodyfikowaną wersję Blobrunner w następującym linku. Aby ją skompilować, po prostu **stwórz projekt C/C++ w Visual Studio Code, skopiuj i wklej kod i zbuduj go**.
|
|
|
|
{{#ref}}
|
|
blobrunner.md
|
|
{{#endref}}
|
|
|
|
### Debugowanie shellcode z jmp2it
|
|
|
|
[**jmp2it** ](https://github.com/adamkramer/jmp2it/releases/tag/v1.4) jest bardzo podobny do blobrunner. **Alokuje** **shellcode** w przestrzeni pamięci i rozpoczyna **wieczną pętlę**. Następnie musisz **podłączyć debugger** do procesu, **uruchomić, poczekać 2-5 sekund i nacisnąć stop**, a znajdziesz się w **wiecznej pętli**. Przejdź do następnej instrukcji wiecznej pętli, ponieważ będzie to wywołanie do shellcode, a na końcu znajdziesz się w trakcie wykonywania shellcode.
|
|
|
|
.png>)
|
|
|
|
Możesz pobrać skompilowaną wersję [jmp2it na stronie wydań](https://github.com/adamkramer/jmp2it/releases/).
|
|
|
|
### Debugowanie shellcode za pomocą Cutter
|
|
|
|
[**Cutter**](https://github.com/rizinorg/cutter/releases/tag/v1.12.0) to GUI radare. Używając cutter, możesz emulować shellcode i dynamicznie go badać.
|
|
|
|
Zauważ, że Cutter pozwala na "Otwórz plik" i "Otwórz shellcode". W moim przypadku, gdy otworzyłem shellcode jako plik, poprawnie go dekompilował, ale gdy otworzyłem go jako shellcode, nie:
|
|
|
|
.png>)
|
|
|
|
Aby rozpocząć emulację w miejscu, w którym chcesz, ustaw tam punkt przerwania, a Cutter automatycznie rozpocznie emulację stamtąd:
|
|
|
|
.png>)
|
|
|
|
.png>)
|
|
|
|
Możesz zobaczyć stos na przykład w zrzucie heksadecymalnym:
|
|
|
|
.png>)
|
|
|
|
### Deobfuskacja shellcode i uzyskiwanie wywoływanych funkcji
|
|
|
|
Powinieneś spróbować [**scdbg**](http://sandsprite.com/blogs/index.php?uid=7&pid=152).\
|
|
Powie ci rzeczy takie jak **które funkcje** używa shellcode i czy shellcode **dekoduje** się w pamięci.
|
|
```bash
|
|
scdbg.exe -f shellcode # Get info
|
|
scdbg.exe -f shellcode -r #show analysis report at end of run
|
|
scdbg.exe -f shellcode -i -r #enable interactive hooks (file and network) and show analysis report at end of run
|
|
scdbg.exe -f shellcode -d #Dump decoded shellcode
|
|
scdbg.exe -f shellcode /findsc #Find offset where starts
|
|
scdbg.exe -f shellcode /foff 0x0000004D #Start the executing in that offset
|
|
```
|
|
scDbg posiada również graficzny launcher, w którym możesz wybrać opcje, które chcesz, i wykonać shellcode.
|
|
|
|
.png>)
|
|
|
|
Opcja **Create Dump** zrzuci końcowy shellcode, jeśli jakiekolwiek zmiany zostaną wprowadzone do shellcode dynamicznie w pamięci (przydatne do pobrania zdekodowanego shellcode). **Start offset** może być przydatny do rozpoczęcia shellcode w określonym offsetcie. Opcja **Debug Shell** jest przydatna do debugowania shellcode za pomocą terminala scDbg (jednak uważam, że jakiekolwiek z wcześniej opisanych opcji są lepsze w tej kwestii, ponieważ będziesz mógł używać Ida lub x64dbg).
|
|
|
|
### Disassembling using CyberChef
|
|
|
|
Prześlij swój plik shellcode jako wejście i użyj następującego przepisu, aby go dekompilować: [https://gchq.github.io/CyberChef/#recipe=To_Hex('Space',0)Disassemble_x86('32','Full%20x86%20architecture',16,0,true,true)](<https://gchq.github.io/CyberChef/index.html#recipe=To_Hex('Space',0)Disassemble_x86('32','Full%20x86%20architecture',16,0,true,true)>)
|
|
|
|
## [Movfuscator](https://github.com/xoreaxeaxeax/movfuscator)
|
|
|
|
Ten obfuscator **modyfikuje wszystkie instrukcje dla `mov`** (tak, naprawdę fajne). Używa również przerwań do zmiany przepływów wykonania. Aby uzyskać więcej informacji na temat tego, jak to działa:
|
|
|
|
- [https://www.youtube.com/watch?v=2VF_wPkiBJY](https://www.youtube.com/watch?v=2VF_wPkiBJY)
|
|
- [https://github.com/xoreaxeaxeax/movfuscator/blob/master/slides/domas_2015_the_movfuscator.pdf](https://github.com/xoreaxeaxeax/movfuscator/blob/master/slides/domas_2015_the_movfuscator.pdf)
|
|
|
|
Jeśli masz szczęście, [demovfuscator](https://github.com/kirschju/demovfuscator) zdeobfuskowuje binarny plik. Ma kilka zależności.
|
|
```
|
|
apt-get install libcapstone-dev
|
|
apt-get install libz3-dev
|
|
```
|
|
I [zainstaluj keystone](https://github.com/keystone-engine/keystone/blob/master/docs/COMPILE-NIX.md) (`apt-get install cmake; mkdir build; cd build; ../make-share.sh; make install`)
|
|
|
|
Jeśli grasz w **CTF, to obejście w celu znalezienia flagi** może być bardzo przydatne: [https://dustri.org/b/defeating-the-recons-movfuscator-crackme.html](https://dustri.org/b/defeating-the-recons-movfuscator-crackme.html)
|
|
|
|
## Rust
|
|
|
|
Aby znaleźć **punkt wejścia**, przeszukaj funkcje według `::main`, jak w:
|
|
|
|
.png>)
|
|
|
|
W tym przypadku binarka nazywała się authenticator, więc jest dość oczywiste, że to jest interesująca funkcja główna.\
|
|
Mając **nazwy** wywoływanych **funkcji**, przeszukaj je w **Internecie**, aby dowiedzieć się o ich **wejściach** i **wyjściach**.
|
|
|
|
## **Delphi**
|
|
|
|
Dla skompilowanych binarek Delphi możesz użyć [https://github.com/crypto2011/IDR](https://github.com/crypto2011/IDR)
|
|
|
|
Jeśli musisz zrewersować binarkę Delphi, sugeruję użycie wtyczki IDA [https://github.com/Coldzer0/IDA-For-Delphi](https://github.com/Coldzer0/IDA-For-Delphi)
|
|
|
|
Po prostu naciśnij **ATL+f7** (importuj wtyczkę python w IDA) i wybierz wtyczkę python.
|
|
|
|
Ta wtyczka wykona binarkę i dynamicznie rozwiąże nazwy funkcji na początku debugowania. Po rozpoczęciu debugowania naciśnij ponownie przycisk Start (zielony lub f9), a punkt przerwania zatrzyma się na początku rzeczywistego kodu.
|
|
|
|
Jest to również bardzo interesujące, ponieważ jeśli naciśniesz przycisk w aplikacji graficznej, debugger zatrzyma się w funkcji wywoływanej przez ten przycisk.
|
|
|
|
## Golang
|
|
|
|
Jeśli musisz zrewersować binarkę Golang, sugeruję użycie wtyczki IDA [https://github.com/sibears/IDAGolangHelper](https://github.com/sibears/IDAGolangHelper)
|
|
|
|
Po prostu naciśnij **ATL+f7** (importuj wtyczkę python w IDA) i wybierz wtyczkę python.
|
|
|
|
To rozwiąże nazwy funkcji.
|
|
|
|
## Skompilowany Python
|
|
|
|
Na tej stronie możesz znaleźć, jak uzyskać kod python z binarki ELF/EXE skompilowanej w pythonie:
|
|
|
|
{{#ref}}
|
|
../../generic-methodologies-and-resources/basic-forensic-methodology/specific-software-file-type-tricks/.pyc.md
|
|
{{#endref}}
|
|
|
|
## GBA - Game Body Advance
|
|
|
|
Jeśli zdobędziesz **binarkę** gry GBA, możesz użyć różnych narzędzi do **emulacji** i **debugowania**:
|
|
|
|
- [**no$gba**](https://problemkaputt.de/gba.htm) (_Pobierz wersję debugującą_) - Zawiera debugger z interfejsem
|
|
- [**mgba** ](https://mgba.io) - Zawiera debugger CLI
|
|
- [**gba-ghidra-loader**](https://github.com/pudii/gba-ghidra-loader) - Wtyczka Ghidra
|
|
- [**GhidraGBA**](https://github.com/SiD3W4y/GhidraGBA) - Wtyczka Ghidra
|
|
|
|
W [**no$gba**](https://problemkaputt.de/gba.htm), w _**Options --> Emulation Setup --> Controls**_** ** możesz zobaczyć, jak naciskać **przyciski** Game Boy Advance
|
|
|
|
.png>)
|
|
|
|
Po naciśnięciu każdy **klawisz ma wartość** do jego identyfikacji:
|
|
```
|
|
A = 1
|
|
B = 2
|
|
SELECT = 4
|
|
START = 8
|
|
RIGHT = 16
|
|
LEFT = 32
|
|
UP = 64
|
|
DOWN = 128
|
|
R = 256
|
|
L = 256
|
|
```
|
|
W takim programie interesującą częścią będzie **jak program traktuje dane wejściowe użytkownika**. Pod adresem **0x4000130** znajdziesz powszechnie występującą funkcję: **KEYINPUT**.
|
|
|
|
.png>)
|
|
|
|
Na poprzednim obrazie możesz zobaczyć, że funkcja jest wywoływana z **FUN_080015a8** (adresy: _0x080015fa_ i _0x080017ac_).
|
|
|
|
W tej funkcji, po kilku operacjach inicjalizacyjnych (bez większego znaczenia):
|
|
```c
|
|
void FUN_080015a8(void)
|
|
|
|
{
|
|
ushort uVar1;
|
|
undefined4 uVar2;
|
|
undefined4 uVar3;
|
|
ushort uVar4;
|
|
int iVar5;
|
|
ushort *puVar6;
|
|
undefined *local_2c;
|
|
|
|
DISPCNT = 0x1140;
|
|
FUN_08000a74();
|
|
FUN_08000ce4(1);
|
|
DISPCNT = 0x404;
|
|
FUN_08000dd0(&DAT_02009584,0x6000000,&DAT_030000dc);
|
|
FUN_08000354(&DAT_030000dc,0x3c);
|
|
uVar4 = DAT_030004d8;
|
|
```
|
|
Znaleziono ten kod:
|
|
```c
|
|
do {
|
|
DAT_030004da = uVar4; //This is the last key pressed
|
|
DAT_030004d8 = KEYINPUT | 0xfc00;
|
|
puVar6 = &DAT_0200b03c;
|
|
uVar4 = DAT_030004d8;
|
|
do {
|
|
uVar2 = DAT_030004dc;
|
|
uVar1 = *puVar6;
|
|
if ((uVar1 & DAT_030004da & ~uVar4) != 0) {
|
|
```
|
|
Ostatni warunek sprawdza, czy **`uVar4`** znajduje się w **ostatnich kluczach** i nie jest aktualnym kluczem, nazywanym również zwolnieniem przycisku (aktualny klucz jest przechowywany w **`uVar1`**).
|
|
```c
|
|
if (uVar1 == 4) {
|
|
DAT_030000d4 = 0;
|
|
uVar3 = FUN_08001c24(DAT_030004dc);
|
|
FUN_08001868(uVar2,0,uVar3);
|
|
DAT_05000000 = 0x1483;
|
|
FUN_08001844(&DAT_0200ba18);
|
|
FUN_08001844(&DAT_0200ba20,&DAT_0200ba40);
|
|
DAT_030000d8 = 0;
|
|
uVar4 = DAT_030004d8;
|
|
}
|
|
else {
|
|
if (uVar1 == 8) {
|
|
if (DAT_030000d8 == 0xf3) {
|
|
DISPCNT = 0x404;
|
|
FUN_08000dd0(&DAT_02008aac,0x6000000,&DAT_030000dc);
|
|
FUN_08000354(&DAT_030000dc,0x3c);
|
|
uVar4 = DAT_030004d8;
|
|
}
|
|
}
|
|
else {
|
|
if (DAT_030000d4 < 8) {
|
|
DAT_030000d4 = DAT_030000d4 + 1;
|
|
FUN_08000864();
|
|
if (uVar1 == 0x10) {
|
|
DAT_030000d8 = DAT_030000d8 + 0x3a;
|
|
```
|
|
W poprzednim kodzie widać, że porównujemy **uVar1** (miejsce, w którym znajduje się **wartość naciśniętego przycisku**) z pewnymi wartościami:
|
|
|
|
- Najpierw jest porównywana z **wartością 4** (**przycisk SELECT**): W wyzwaniu ten przycisk czyści ekran.
|
|
- Następnie jest porównywana z **wartością 8** (**przycisk START**): W wyzwaniu sprawdza, czy kod jest ważny, aby uzyskać flagę.
|
|
- W tym przypadku zmienna **`DAT_030000d8`** jest porównywana z 0xf3, a jeśli wartość jest taka sama, wykonywany jest pewien kod.
|
|
- W innych przypadkach sprawdzana jest zmienna cont (`DAT_030000d4`). To jest cont, ponieważ dodaje 1 zaraz po wejściu w kod.\
|
|
**Jeśli** jest mniej niż 8, wykonywane jest coś, co polega na **dodawaniu** wartości do **`DAT_030000d8`** (w zasadzie dodaje wartości naciśniętych klawiszy do tej zmiennej, o ile cont jest mniejszy niż 8).
|
|
|
|
Tak więc, w tym wyzwaniu, znając wartości przycisków, musiałeś **nacisnąć kombinację o długości mniejszej niż 8, której wynikowa suma to 0xf3.**
|
|
|
|
**Referencja do tego samouczka:** [**https://exp.codes/Nostalgia/**](https://exp.codes/Nostalgia/)
|
|
|
|
## Game Boy
|
|
|
|
{{#ref}}
|
|
https://www.youtube.com/watch?v=VVbRe7wr3G4
|
|
{{#endref}}
|
|
|
|
## Kursy
|
|
|
|
- [https://github.com/0xZ0F/Z0FCourse_ReverseEngineering](https://github.com/0xZ0F/Z0FCourse_ReverseEngineering)
|
|
- [https://github.com/malrev/ABD](https://github.com/malrev/ABD) (deobfuskacja binarna)
|
|
|
|
{{#include ../../banners/hacktricks-training.md}}
|