From a3b251bf3a412a52ca6af7a7fea9aa799be1b5cf Mon Sep 17 00:00:00 2001 From: RetroGameDeveloper <40120498+RetroGameDeveloper@users.noreply.github.com> Date: Sat, 28 Sep 2024 15:12:42 +0100 Subject: [PATCH 1/6] Update GDBReversing.md --- pages/tutorials/GDBReversing.md | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/pages/tutorials/GDBReversing.md b/pages/tutorials/GDBReversing.md index cdabf552..93ba6895 100644 --- a/pages/tutorials/GDBReversing.md +++ b/pages/tutorials/GDBReversing.md @@ -227,6 +227,33 @@ You can find out more about the GDB Remote Serial Protocol on the official docum ## Security Implications As GDB Stubs provide a pathway for remote interaction with a program, developers must consider security implications and ensure proper safeguards to prevent unauthorized access. Software should not be released with the GDB stub embedded inside and proper network hygene is required between the two remote systems to prevent Man in the Middle attacks. +--- +# Adding GDB to existing emulators/software +Not all emulators have support for GDB out of the box, which is a shame as it is an incredibly useful feature for reverse engineering. Luckily most good emulators are open source so we can in theory add GDB support ourselves! + +## Using Rust and *rust-gdb-remote-protocol +**Marcin Mikołajczyk** has a good tutorial on how to add GDB support to a dummy MIPS CPU emulator using Rust and specifically the **rust-gdb-remote-protocol** available to read online [here](https://medium.com/virtuslab/integrating-gdb-support-in-an-emulator-ef41ff13f301). + +Note that if you are using MacOS you will need to get the MIPS compiler **mipsel-unknown-linux-gnu** using the folowing custom homebrew tap: +```bash +brew tap messense/macos-cross-toolchains +brew install mipsel-unknown-linux-gnu +``` +It will install to a path similar to `/usr/local/Cellar/mipsel-unknown-linux-gnu/13.3.0/bin` which you can either add to PATH or just run directly: +```bash +/usr/local/Cellar/mipsel-unknown-linux-gnu/13.3.0/bin/mipsel-unknown-linux-gnu-gcc --version + +/usr/local/Cellar/mipsel-unknown-linux-gnu/13.3.0/bin/mipsel-unknown-linux-gnu-gcc -nostdlib -march=r3000 -Wl,--section-start=.text=0xbfc00000 hello_mips.c +``` +This will give you a.out to use with the emulator + +To run the rust program itself you can simple do: +``` +cargo build +cargo run a.out +``` + + --- # References [^1]: [Reversing and Cracking first simple Program - bin 0x05 - YouTube](https://www.youtube.com/watch?v=VroEiMOJPm8&list=WL&index=40) From 210987f7260221cf88a4d8154145a55740bc866b Mon Sep 17 00:00:00 2001 From: RetroGameDeveloper <40120498+RetroGameDeveloper@users.noreply.github.com> Date: Sat, 28 Sep 2024 15:14:41 +0100 Subject: [PATCH 2/6] Update GDBReversing.md --- pages/tutorials/GDBReversing.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pages/tutorials/GDBReversing.md b/pages/tutorials/GDBReversing.md index 93ba6895..36178521 100644 --- a/pages/tutorials/GDBReversing.md +++ b/pages/tutorials/GDBReversing.md @@ -244,13 +244,15 @@ It will install to a path similar to `/usr/local/Cellar/mipsel-unknown-linux-gnu /usr/local/Cellar/mipsel-unknown-linux-gnu/13.3.0/bin/mipsel-unknown-linux-gnu-gcc --version /usr/local/Cellar/mipsel-unknown-linux-gnu/13.3.0/bin/mipsel-unknown-linux-gnu-gcc -nostdlib -march=r3000 -Wl,--section-start=.text=0xbfc00000 hello_mips.c + +/usr/local/Cellar/mipsel-unknown-linux-gnu/13.3.0/bin/mipsel-linux-gnu-objcopy -O binary -j .text a.out a.bin ``` This will give you a.out to use with the emulator To run the rust program itself you can simple do: ``` cargo build -cargo run a.out +cargo run a.bin ``` From 28a36d26e51f81bb01622ee0ad1b63600197a001 Mon Sep 17 00:00:00 2001 From: RetroGameDeveloper <40120498+RetroGameDeveloper@users.noreply.github.com> Date: Sat, 28 Sep 2024 15:18:03 +0100 Subject: [PATCH 3/6] Update GDBReversing.md --- pages/tutorials/GDBReversing.md | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/pages/tutorials/GDBReversing.md b/pages/tutorials/GDBReversing.md index 36178521..a0fe0966 100644 --- a/pages/tutorials/GDBReversing.md +++ b/pages/tutorials/GDBReversing.md @@ -231,7 +231,7 @@ As GDB Stubs provide a pathway for remote interaction with a program, developers # Adding GDB to existing emulators/software Not all emulators have support for GDB out of the box, which is a shame as it is an incredibly useful feature for reverse engineering. Luckily most good emulators are open source so we can in theory add GDB support ourselves! -## Using Rust and *rust-gdb-remote-protocol +## Using Rust and rust-gdb-remote-protocol **Marcin Mikołajczyk** has a good tutorial on how to add GDB support to a dummy MIPS CPU emulator using Rust and specifically the **rust-gdb-remote-protocol** available to read online [here](https://medium.com/virtuslab/integrating-gdb-support-in-an-emulator-ef41ff13f301). Note that if you are using MacOS you will need to get the MIPS compiler **mipsel-unknown-linux-gnu** using the folowing custom homebrew tap: @@ -255,6 +255,12 @@ cargo build cargo run a.bin ``` +Initially it give the output: +``` +thread 'main' panicked at 'index out of bounds: the len is 80 but the index is 384', src/cpu.rs:28:19 +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace +``` +Which may or may not be intentional to start the tutorial. However switching to the final branch did at least listen for gdb on port 2424. --- # References From c4582d6e44c2c426e35b9bdc66348455fa8cfe1a Mon Sep 17 00:00:00 2001 From: RetroGameDeveloper <40120498+RetroGameDeveloper@users.noreply.github.com> Date: Sat, 28 Sep 2024 15:37:05 +0100 Subject: [PATCH 4/6] Update GDBReversing.md --- pages/tutorials/GDBReversing.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/pages/tutorials/GDBReversing.md b/pages/tutorials/GDBReversing.md index a0fe0966..2055d942 100644 --- a/pages/tutorials/GDBReversing.md +++ b/pages/tutorials/GDBReversing.md @@ -262,6 +262,20 @@ note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace ``` Which may or may not be intentional to start the tutorial. However switching to the final branch did at least listen for gdb on port 2424. +If you load up standard GDB and type the following command in: +```gdb +target remote localhost:2424 +``` + +The GDB server will output the following: +```bash +Listening on port 2424 +Got connection +Connection closed +``` + +This is probably because GDB only has the target architecture that your CPU has (probably either x64 or arm) but requires mips support. This is where **gdb-multiarch** comes in useful as it is a build of GDB with all the architectures enabled. However the problem is there doesn't seem to be any release of it for MacOS, so if you are on Linux you should be fine but for MacOS we will need to build GDB ourselves. + --- # References [^1]: [Reversing and Cracking first simple Program - bin 0x05 - YouTube](https://www.youtube.com/watch?v=VroEiMOJPm8&list=WL&index=40) From 3f0a38a769fdef5877a5ef15baabf6ec0a860a7c Mon Sep 17 00:00:00 2001 From: RetroGameDeveloper <40120498+RetroGameDeveloper@users.noreply.github.com> Date: Sat, 28 Sep 2024 16:14:09 +0100 Subject: [PATCH 5/6] Update GDBReversing.md --- pages/tutorials/GDBReversing.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/pages/tutorials/GDBReversing.md b/pages/tutorials/GDBReversing.md index 2055d942..155d722e 100644 --- a/pages/tutorials/GDBReversing.md +++ b/pages/tutorials/GDBReversing.md @@ -169,12 +169,24 @@ On systems that support package managers, you can typically install `gdb-multiar sudo apt-get install gdb-multiarch ``` +However on MacOS there is no such build in brew or other package managers so you may want to run a docker image with a linux distro in it to use it. + ### How to use gdb-multiarch Once installed, you can use `gdb-multiarch` similarly to the standard `gdb`. The key difference is that `gdb-multiarch` allows you to specify the target architecture when loading an executable. ```bash gdb-multiarch -q -tui -ex "target sim" -ex "load" -ex "run" -ex "quit" my_program.elf ``` +### How to see what architectures are available +You can see what target architectures are available simply by using the following command in gdb: +```bash +set architecture +``` +It will print out something like this: +``` +Requires an argument. Valid arguments are i386, i386:x86-64, i386:x64-32, i8086, i386:intel, i386:x86-64:intel, i386:x64-32:intel, i386:nacl, i386:x86-64:nacl, i386:x64-32:nacl, auto. +``` + ### How to change target architecture You can change the target architecture within the GDB session using the `set architecture` command. ```bash @@ -185,6 +197,8 @@ This flexibility is particularly useful when working with cross-compilation envi + + --- # GDB Frontends GDB frontends are graphical or text-based interfaces that provide a user-friendly way to interact with the GNU Debugger (GDB). These frontends simplify the debugging process by offering features like syntax highlighting, variable inspection, and breakpoint management. Here are some popular GDB frontends: From 691be0124031c11acde4f5bbd9f142c29f47e742 Mon Sep 17 00:00:00 2001 From: RetroGameDeveloper <40120498+RetroGameDeveloper@users.noreply.github.com> Date: Sat, 28 Sep 2024 16:31:50 +0100 Subject: [PATCH 6/6] Update GDBReversing.md --- pages/tutorials/GDBReversing.md | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/pages/tutorials/GDBReversing.md b/pages/tutorials/GDBReversing.md index 155d722e..da93abc4 100644 --- a/pages/tutorials/GDBReversing.md +++ b/pages/tutorials/GDBReversing.md @@ -182,11 +182,23 @@ You can see what target architectures are available simply by using the followin ```bash set architecture ``` -It will print out something like this: +It will print out something like this if it really is gdb-multiarch: ``` -Requires an argument. Valid arguments are i386, i386:x86-64, i386:x64-32, i8086, i386:intel, i386:x86-64:intel, i386:x64-32:intel, i386:nacl, i386:x86-64:nacl, i386:x64-32:nacl, auto. +Requires an argument. Valid arguments are i386, i386:x86-64, i386:x64-32, i8086, i386:intel, i386:x86-64:intel, i386:x64-32:intel, i386:nacl, i386:x86-64:nacl, i386:x64-32:nacl, aarch64, aarch64:ilp32, arm, armv2, armv2a, armv3, armv3m, armv4, armv4t, armv5, armv5t, armv5te, xscale, ep9312, iwmmxt, iwmmxt2, armv5tej, armv6, armv6kz, armv6t2, armv6k, armv7, armv6-m, armv6s-m, armv7e-m, armv8-a, armv8-r, armv8-m.base, armv8-m.main, arm_any, alpha, alpha:ev4, alpha:ev5, alpha:ev6, hppa1.0, ia64-elf64, ia64-elf32, m68k, m68k:68000, m68k:68008, m68k:68010, m68k:68020, m68k:68030, m68k:68040, m68k:68060, m68k:cpu32, m68k:fido, m68k:isa-a:nodiv, m68k:isa-a, m68k:isa-a:mac, m68k:isa-a:emac, m68k:isa-aplus, m68k:isa-aplus:mac, m68k:isa-aplus:emac, m68k:isa-b:nousp, m68k:isa-b:nousp:mac, m68k:isa-b:nousp:emac, m68k:isa-b, m68k:isa-b:mac, m68k:isa-b:emac, m68k:isa-b:float, m68k:isa-b:float:mac, m68k:isa-b:float:emac, m68k:isa-c, m68k:isa-c:mac, m68k:isa-c:emac, m68k:isa-c:nodiv, m68k:isa-c:nodiv:mac, m68k:isa-c:nodiv:emac, m68k:5200, m68k:5206e, m68k:5307, m68k:5407, m68k:528x, m68k:521x, m68k:5249, m68k:547x, m68k:548x, m68k:cfv4e, mips, mips:3000, mips:3900, mips:4000, mips:4010, mips:4100, mips:4111, mips:4120, mips:4300, mips:4400, mips:4600, mips:4650, mips:5000, mips:5400, mips:5500, mips:5900, mips:6000, mips:7000, mips:8000, mips:9000, mips:10000, mips:12000, mips:14000, mips:16000, mips:16, mips:mips5, mips:isa32, mips:isa32r2, mips:isa32r3, mips:isa32r5, mips:isa32r6, mips:isa64, mips:isa64r2, mips:isa64r3, mips:isa64r5, mips:isa64r6, mips:sb1, mips:loongson_2e, mips:loongson_2f, mips:loongson_3a, mips:octeon, mips:octeon+, mips:octeon2, mips:octeon3, mips:xlr, mips:interaptiv-mr2, mips:micromips, rs6000:6000, rs6000:rs1, rs6000:rsc, rs6000:rs2, powerpc:common64, powerpc:common, powerpc:603, powerpc:EC603e, powerpc:604, powerpc:403, powerpc:601, powerpc:620, powerpc:630, powerpc:a35, powerpc:rs64ii, powerpc:rs64iii, powerpc:7400, powerpc:e500, powerpc:e500mc, powerpc:e500mc64, powerpc:MPC8XX, powerpc:750, powerpc:titan, powerpc:vle, powerpc:e5500, powerpc:e6500, riscv, riscv:rv64, riscv:rv32, s390:64-bit, s390:31-bit, sh, sh2, sh2e, sh-dsp, sh3, sh3-nommu, sh3-dsp, sh3e, sh4, sh4a, sh4al-dsp, sh4-nofpu, sh4-nommu-nofpu, sh4a-nofpu, sh2a, sh2a-nofpu, sh2a-nofpu-or-sh4-nommu-nofpu, sh2a-nofpu-or-sh3-nommu, sh2a-or-sh4, sh2a-or-sh3e, sparc, sparc:sparclet, sparc:sparclite, sparc:v8plus, sparc:v8plusa, sparc:sparclite_le, sparc:v9, sparc:v9a, sparc:v8plusb, sparc:v9b, sparc:v8plusc, sparc:v9c, sparc:v8plusd, sparc:v9d, sparc:v8pluse, sparc:v9e, sparc:v8plusv, sparc:v9v, sparc:v8plusm, sparc:v9m, sparc:v8plusm8, sparc:v9m8, m32r, m32rx, m32r2, auto. ``` +Most useful for games consoles would be: +* arm - Nintendo GBA/DS (mGBA has a GDB stub) +* mips:4300 - Nintendo 64 +* mips:3000 - Playstation 1 +* mips:5900 - Playstation 2 +* powerpc - Gamecube/Wii/ps3 +* m68k - Sega Mega Drive +* sh2 - Sega Saturn +* sh4 - Sega Dreamcast + +You will notice that there is no good options for 6502 or Z80 variants in GDB as these systems tend to be too old to have official GDB support. + ### How to change target architecture You can change the target architecture within the GDB session using the `set architecture` command. ```bash