This repository showcases a simple example of using Radare2 to patch an existing ARM64 “Hello World” binary on a Raspberry Pi 4 running Kali Linux (ARM64). The project includes:
- A C++ source file (
hello.cpp) that prints “Hello World!”. - The original compiled binary (
hello). - A patched binary (
hacked) where the string has been modified to “Hacked World!” using Radare2. - A JSON diff file (
patchHW.json) generated by Radare2’sradiff2 -ucommand, illustrating the binary-level changes between the original and patched executables. - A JSON file (
HW_disasm.json) containing a snippet of the disassembly around the patched string location.
hello.cpp- C++ source code for a minimal “Hello World!” program.
hello- The ARM64-compiled binary of
hello.cpp. When executed, it prints “Hello World!” to stdout.
- The ARM64-compiled binary of
hacked- The patched ARM64 binary. Its output has been changed from “Hello World!” to “Hacked World!”.
patchHW.json- A JSON delta file produced by running:
radiff2 -u hello hacked > patchHW.json - This file contains the differences (in JSON format) between the original and patched binaries.
- A JSON delta file produced by running:
HW_disasm.json- A snippet of the disassembly around the patched code region, exported from Radare2. It shows the function prologue, instructions that load the string address, and the call to
std::cout. - Example contents:
; DATA XREF from entry0 @ 0x860(r) ; DATA XREF from entry.fini0 @ 0x920(r) ┌ 52: int main (int argc, char **argv, char **envp); │ afv: vars(2:sp[0x8..0x10]) │ 0x00000968 fd7bbfa9 stp x29, x30, [sp, -0x10]! │ 0x0000096c fd030091 mov x29, sp │ 0x00000970 00000090 adrp x0, 0 │ 0x00000974 01002791 add x1, x0, str.Hello_World_ ; 0x9c0 ; "Hello World!" │ 0x00000978 e00000f0 adrp x0, 0x1f000 │ 0x0000097c 00e447f9 ldr x0, [x0, 0xfc8] ; [0x1ffc8:4]=0 │ ; reloc.std::cout │ 0x00000980 98ffff97 bl method std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*) ; method.std::basic_ostream_char__std::char_traits_char____std::operator____std.char_traits_char____std::basic_ostream_char__std::char_traits_char_____char_const_ │ 0x00000984 e10000f0 adrp x1, 0x1f000 │ 0x00000988 21dc47f9 ldr x1, [x1, 0xfb8] ; [0x1ffb8:4]=0 │ ; reloc.std::basic_ostream_char__std::char_traits_char____std::endl_char__std::char_traits_char____std::basic_ostream_char__std::char_traits_char____ │ 0x0000098c 99ffff97 bl sym std::ostream::operator<<(std::ostream& (*)(std::ostream&)) ; sym.imp.std::ostream::operator___std::ostream____std::ostream__ │ 0x00000990 00008052 mov w0, 0 │ 0x00000994 fd7bc1a8 ldp x29, x30, [sp], 0x10 וגם אני משתמשת ב רסברי פיי4 עם מערכת הפעלה של קאלי לינוקס ARM 64 └ 0x00000998 c0035fd6 ret
- A snippet of the disassembly around the patched code region, exported from Radare2. It shows the function prologue, instructions that load the string address, and the call to
- Hardware: Raspberry Pi 4 (ARM64).
- Operating System: Kali Linux (ARM64).
- Installed Tools:
g++(for compiling C++ code targeting ARM64).radare2(for interactive binary patching and generating diffs).
- Open a terminal on Raspberry Pi 4 with Kali Linux (ARM64).
- Navigate to the directory containing
hello.cpp. - Compile the source code:
g++ -o hello hello.cpp
Verify that the hello executable runs correctly:
./hello
Patching with Radare2 Open Radare2 in writeable mode on the original hello binary:
r2 -w hello Seek to the offset where the string “Hello World!” is located. In this example, the offset is 0x9c0. To navigate:
s 0x9c0 Patch the string at that address:
wx 48 61 63 6b 65 64 20 57 6f 72 6c 64 21 00 This writes the ASCII bytes for Hacked World! followed by a null terminator.
Save the patched binary under a new name:
wq! hacked Exit Radare2.
Confirm the patched binary runs:
./hacked
Generating the JSON Diff (patchHW.json) To capture the differences between hello and hacked in JSON format:
radiff2 -u hello hacked > patchHW.json The -u flag tells Radare2 to produce a unified diff in JSON format.
The resulting patchHW.json file contains the specific byte offsets and changed data bytes.
Disassembly Snippet (HW_disasm.json) Within Radare2, you can generate a JSON-formatted disassembly snippet by running:
pdj @ 0x960 > HW_disasm.json This dumps a JSON array of instructions around the function prologue in main, including the patched string reference.
The provided HW_disasm.json in this repository corresponds to the region near the patched string, illustrating how the instructions reference str.Hello_World_.
File Descriptions hello.cpp
#include
int main() { std::cout << "Hello World!" << std::endl; return 0; } Minimal C++ program that prints “Hello World!”.
hello
ARM64 ELF binary compiled from hello.cpp.
hacked
ARM64 ELF binary with the string modified to “Hacked World!” via Radare2.
patchHW.json
Unified JSON diff showing byte-level changes between hello and hacked.
HW_disasm.json
JSON-formatted disassembly snippet around the patched code region. Useful for verifying the patched instruction addresses and string references.
How to Reproduce Clone or download this repository onto your Raspberry Pi 4.
Ensure you have both g++ and radare2 installed:
sudo apt update sudo apt install build-essential radare2 -y Build the original binary:
g++ -o hello hello.cpp Verify the original output:
./hello Open Radare2 and apply the patch:
r2 -w hello Navigate to offset 0x9c0.
Write the bytes for “Hacked World!”:
wx 48 61 63 6b 65 64 20 57 6f 72 6c 64 21 00 Save as hacked and quit.
Verify the patched output:
./hacked Generate the JSON diff:
radiff2 -u hello hacked > patchHW.json (Optional) In Radare2, dump the nearby instructions into JSON:
pdj @ 0x960 > HW_disasm.json Notes & Tips The exact offset (0x9c0) may differ if compiler options or versions change. Always confirm the string’s address by searching within Radare2:
iz~Hello Look for the address of Hello World! in the string table.
To view the JSON diff in a human-readable format, you can pipe it through jq. For example:
cat patchHW.json | jq To examine the JSON disassembly, use:
cat HW_disasm.json | jq License This project is released under the MIT License. See LICENSE for details.
Acknowledgments Radare2 for providing powerful reverse-engineering and binary-patching tools.
The ARM64 community for guidance on building and running binaries on Raspberry Pi.
Kali Linux team for maintaining the ARM64 distribution used in this demonstration.