RAGG2(1)

πŸ“¦
version 6.2.2 Β· 4 versions
, in alpine 3.24, arch rolling, nixos 26.05, nixpkgs unstable, opensuse-leap 16.0, ubuntu stonking

πŸ’– 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, like 32, 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 -L for 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 -L bestie.
  • -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 β€” append 32bit number (4 bytes). πŸ”’
  • -N dword β€” append 64bit number (8 bytes). πŸ”’ but bigger.
  • -o file β€” output file. where the baby goes.
  • -O β€” use default output file (filename without extension or a.out). the lazy girl option and we love her for it.
  • -p padding β€” add padding after compilation (padding=n10s32) ntas : begin nop, trap, 'a', sequence NTAS : 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 🧚


πŸ’œ 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