diff --git a/binr/r2agent/Makefile b/binr/r2agent/Makefile index aa5032e1dc..88d1a97830 100644 --- a/binr/r2agent/Makefile +++ b/binr/r2agent/Makefile @@ -6,6 +6,7 @@ ifeq ($(OSTYPE),android) LDFLAGS+=${DL_LIBS} -lm endif include ../../libr/main/deps.mk +include ../../shlr/java/deps.mk include ../rules.mk diff --git a/libr/main/rax2.c b/libr/main/rax2.c index 9557a34921..3551be3d14 100644 --- a/libr/main/rax2.c +++ b/libr/main/rax2.c @@ -39,6 +39,7 @@ typedef struct { bool jsonbases; // -j bool forcebase; // -b bool quiet; // -q + int swapbytes; } RaxActions; typedef struct { @@ -50,13 +51,17 @@ static bool rax(RNum *num, char *str, int len, int last, RaxActions *flags, RaxM static int use_stdin(RNum *num, RaxActions *flags, RaxMode *mode, PJ **pj) { R_RETURN_VAL_IF_FAIL (num && flags, -1); + if (flags->hexstr2raw && flags->swapendian && !flags->swapbytes) { + R_LOG_ERROR ("Endian swap with -s requires -b <8|16|32|64>"); + return 1; + } int rc = 0; if (flags->slurphex) { char buf[1] = { 0 }; if (!rax (num, buf, 1, 0, flags, mode, pj)) { rc = 1; } - } else if (flags->raw2hexstr) { + } else if (flags->raw2hexstr || (flags->hexstr2raw && flags->swapendian)) { int len = 0; char *buf = r_stdin_slurp (&len); if (buf) { @@ -203,7 +208,8 @@ static int help(void) { " raw -> hex ; rax2 -S < /binfile\n" " hex -> raw ; rax2 -s 414141\n" " -a show ascii table ; rax2 -a\n" - " -b output in ; rax2 -b 10 0x46\n" + " -b output in ; with -s, word size in bits\n" + " rax2 -esb 32 < in.hex > out.raw\n" " -c output in C string ; rax2 -c 0x1234 # \\x34\\x12\\x00\\x00\n" " -C dump as C byte array ; rax2 -C < bytes\n" " -d force integer ; rax2 -d 3 -> 3 instead of 0x3\n" @@ -329,12 +335,37 @@ static bool rax(RNum *num, char *str, int len, int last, RaxActions *flags, RaxM } dotherax: + if (flags->hexstr2raw && flags->forcebase) { + ut64 bits = r_num_math_err (num, str, &errstr); + flags->forcebase = false; + if (errstr || (bits != 8 && bits != 16 && bits != 32 && bits != 64)) { + R_LOG_ERROR ("Invalid word size, expected 8, 16, 32, or 64 bits"); + return false; + } + flags->swapbytes = bits / 8; + return last? !use_stdin (num, flags, mode, pj): true; + } if (flags->hexstr2raw) { // -s int n = ((strlen (str)) >> 1) + 1; buf = calloc (1, n); if (buf) { n = r_hex_str2bin (str, (ut8 *)buf); if (n > 0) { + if (flags->swapendian) { + if (!flags->swapbytes) { + R_LOG_ERROR ("Endian swap with -s requires -b <8|16|32|64>"); + free (buf); + return false; + } + if (n % flags->swapbytes) { + R_LOG_ERROR ("Input size is not a multiple of the word size"); + free (buf); + return false; + } + for (i = 0; i < n; i += flags->swapbytes) { + r_mem_swapendian (buf + i, buf + i, flags->swapbytes); + } + } fwrite (buf, n, 1, stdout); } rax2_newline (*flags); diff --git a/man/rax2.1 b/man/rax2.1 index 76deadf3bb..49e591545b 100644 --- a/man/rax2.1 +++ b/man/rax2.1 @@ -1,4 +1,4 @@ -.Dd Jul 10, 2025 +.Dd Aug 22, 2026 .Dt RAX2 1 .Sh NAME .Nm rax2 @@ -27,6 +27,13 @@ Force output mode (numeric base) 8 octal 10 decimal 16 hexadecimal +.Pp +When used with +.Fl s +and +.Fl e , +select the word size in bits for endian-swapping hex input. Valid word sizes +are 8, 16, 32, and 64 bits. .It Fl c Show hexadecimal C string from integer value .It Fl C @@ -36,7 +43,11 @@ Print the result in decimal (base 10) .It Fl D Decode the input data using base64 .It Fl e -Swap endianness +Swap endianness. With +.Fl s , +requires +.Fl b +to specify the word size. .It Fl E Encode the input data using base64 .It Fl f @@ -122,6 +133,11 @@ You can do 'unpack' hexpair encoded strings easily. $ rax2 \-s 41 42 43 ABC .Pp +Swap the byte order of each 32-bit word in a hex stream: +.Pp + $ printf 1122334455667788 | rax2 \-esb 32 | rax2 \-S + 4433221188776655 +.Pp It supports some math operations: .Pp $ rax2 1+1 "0x5*101b+5" @@ -169,4 +185,4 @@ rax2 does not use any environment variables. https://www.radare.org .Sh AUTHORS .Pp -pancake \ No newline at end of file +pancake diff --git a/test/db/tools/rax2 b/test/db/tools/rax2 index d8340e87ab..1a4a0a086f 100644 --- a/test/db/tools/rax2 +++ b/test/db/tools/rax2 @@ -297,6 +297,14 @@ CMDS=!printf 414141 | rax2 -s EXPECT=AAA RUN +NAME=rax2 endian swap hex stream +FILE=- +CMDS=!printf 1122334455667788 | rax2 -esb 32 | rax2 -S +EXPECT=<