RAGG2(1)
π ragg2 β bestie's guide to the tiny-binary machine π
okay so. pookies. gather round. this is ragg2(1), aka the Radare2 Frontend for r_egg, and it Compiles Programs into Tiny Binaries for x86 and ARM Architectures. yes that's the whole name, she's dramatic like that π
β¨ SYNOPSIS β¨
ragg2 [-FOLsrxhvz] [-a arch] [-b bits] [-k os] [-o file] [-i sc]
[-I path] [-E enc] [-B hex] [-c k=v] [-C file] [-p pad] [-q off]
[-S string] [-f fmt] [-nN dword] [-dDw off:hex] [-e expr]
like, that's a LOT of little letters but don't panic, we're going through every single one, fr fr π«Ά
πΈ DESCRIPTION πΈ
so ragg2 is the frontend for r_egg, and what it does is compile assembly programs into minimal binaries for x86-32, x86-64, and ARM architectures. tiny little guys. little baby binaries. obsessed π
it's built on top of r_asm and r_bin, and it provides a library for generating small standalone binaries across the supported platforms. like a whole toolkit for making smol executables.
here's the iconic part: programs generated by r_egg are relocatable, which means you can inject them in a running process, or into an on-disk binary file. main character energy, no cap.
and! ragg2 can generate shellcodes from C code. the final code can be linked with rabin2 and it is relocatable, so it can be used to inject it on any remote process. yes bestie, we're doing remote stuff. it's giving hacker movie but make it cute π
π OPTIONS π
every single one. no skips. we don't do that here.
-a archβ pick your architecture:x86,mips,arm. choose your fighter β¨-b bitsβ register size, like32,64,... big girl numbers.-B hexpairsβ append some hexpair bytes. sprinkle sprinkle π-c k=vβ set configuration options. key equals value, that's it.-C fileβ append contents of file. yeet that file in there.-d off:dwordβ patch dword (4 bytes) at given offset. lil patch, lil surgery π-D off:qwordβ patch qword (8 bytes) at given offset. big patch, big surgery π€-e egg-exprβ take egg program from string instead of file. π₯ no file needed, just vibes.-E encoderβ use specific encoder. check-Lfor the list, iykyk.-f formatβ output format:raw,c,pe,elf,mach0,python,javascript. pick your output aesthetic π-Fβ output native format (osx=mach0,linux=elf,..). it just knows what your OS wants. intuitive queen.-hβ show usage help message. hi, help me π«Ά-H varβ display variable. peek at a var.-i shellcodeβ include shellcode plugin, uses options. see-Lbestie.-I pathβ add include path. because files live places.-k osβ operating system's kernel:linux,bsd,osx,w32. pick your kingdom π-Lβ list all plugins (shellcodes and encoders). the whole roster, slay.-n dwordβ append32bitnumber (4 bytes). π’-N dwordβ append64bitnumber (8 bytes). π’ but bigger.-o fileβ output file. where the baby goes.-Oβ use default output file (filename without extension ora.out). the lazy girl option and we love her for it.-p paddingβ add padding after compilation (padding=n10s32)ntas: beginnop,trap,'a', sequenceNTAS: same as above, but at the end. yes it's a whole little language, keep up π-P sizeβ prepend debruijn pattern.-q fragmentβ debruijn pattern offset.-rβ show raw bytes instead of hexpairs. raw. unfiltered. πΈ-sβ show assembler.-S stringβ append a string.-vβ show version information. who are you, ragg2?-w off:hexβ patch hexpairs at given offset.-xβ execute. run it, bestie, send it π-X hexpairsβ execute rop chain, using the stack provided.-zβ output in C string syntax.
π ENVIRONMENT π
the vibes your shell gives off before ragg2 even starts:
R2_NOPLUGINSβ do not load any plugin. none. zero. a plugin-free zone πR2_PLUGINS_ORDERβ plugin load order:i=internal,e=env,h=home,s=system; default=iehs;?prints help. so like, set the lineup for who loads first π
π¦ EXAMPLES π¦
using r_egg language
$ cat hi.r
/* hello world in r_egg */
write@syscall(4); //x64 write@syscall(1);
exit@syscall(1); //x64 exit@syscall(60);
main@global(128) {
.var0 = "hi!\n";
write(1,.var0, 4);
exit(0);
}
$ ragg2 -O -F hi.r
$ ./hi
hi!
look at her go. hi! β¨
using C language
$ cat hi.c
main() {
write(1, "Hello\n", 6);
exit(0);
}
$ ragg2 -O -F hi.c
$ ./hi
Hello
C girlies rise up, it works the same way π«Ά
tiny binary output
$ wc -c < hi
165
one 165 bytes. she's tiny. she's perfect. π
compiled shellcode with zeroes
$ ragg2 hi.c | tail -1
eb0748656c6c6f0a00bf01000000488d35edffffffba06000000b8010
000000f0531ffb83c0000000f0531c0c3
using XOR encoder with key 64
$ ragg2 -e xor -c key=64 -B $(ragg2 hi.c | tail -1)
6a2d596a405be8ffffffffc15e4883c60d301e48ffc6e2f9ab4708252
c2c2f4a40ff4140404008cd75adbfbfbffa46404040f8414040404f45
71bff87c4040404f45718083
encoded, keyed, glowing π₯
π§ SEE ALSO π§
radare2(1)β the mothership. go say hi.
π AUTHORS π
Written by pancake <pancake@nopcode.org>. thank you pancake, you ate π
real talk though: this whole thing is powerful and it touches processes and binaries, so be a responsible bestie and only point it at stuff you're allowed to point it at π
and that's the page, babes!! this lil writeup is from the ragg2 manual, dated Jul 10, 2025, and she goes by RAGG2(1) in the man page world. mwah π go make smol binaries.
π¦ where this page comes from
- alpine 3.24: radare2-doc 6.1.6-r0 Β· GPL-3.0-or-later AND LGPL-2.0-or-later AND LGPL-2.1-or-later
- arch rolling: radare2 6.2.2-1 Β· GPL-3.0-only AND LGPL-3.0-only
- nixos 26.05: radare2 6.1.8
- nixpkgs unstable: radare2 6.2.4
- opensuse-leap 16.0: radare2 6.2.2-bp160.1.1 Β· GPL-3.0-only AND LGPL-3.0-only
- opensuse-leap 16.0: radare2 6.2.2-bp160.1.1 Β· GPL-3.0-only AND LGPL-3.0-only
- opensuse-leap 16.0: radare2 6.2.2-bp160.1.1 Β· GPL-3.0-only AND LGPL-3.0-only
- opensuse-leap 16.0: radare2 6.2.2-bp160.1.1 Β· GPL-3.0-only AND LGPL-3.0-only
- ubuntu stonking: radare2 6.1.8+ds-1 Β· LGPL-3.0-only
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms