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=<