NAME=r-+
FILE=malloc://512
CMDS=<<EOF
r
r-3
r
r+3
r
r -3
r
r +3
r
EOF
EXPECT=<<EOF
512
509
512
509
512
EOF
RUN

NAME=r+ keeps the end of the file
FILE=malloc://8
CMDS=<<EOF
wx 6162636465666768
r+2 @ 3
r
p8 10 @e:io.va=0
r-2 @ 3
r
p8 8
EOF
EXPECT=<<EOF
10
61626364656465666768
8
6162636465666768
EOF
RUN

NAME=r+ and r- at a mapped address
FILE=malloc://8
ARGS=-m 0x1000
CMDS=<<EOF
wx 6162636465666768 @ 0x1000
r+2 @ 0x1003
r
p8 10 @ 0 @e:io.va=0
r-2 @ 0x1003
r
p8 8 @ 0 @e:io.va=0
EOF
EXPECT=<<EOF
10
61626364656465666768
8
6162636465666768
EOF
RUN

NAME=r+ and r- below the file size at a mapped address
FILE=malloc://8
ARGS=-m 4
CMDS=<<EOF
wx 6162636465666768 @ 4
r+2 @ 7
r
p8 10 @ 0 @e:io.va=0
r-2 @ 7
r
p8 8 @ 0 @e:io.va=0
EOF
EXPECT=<<EOF
10
61626364656465666768
8
6162636465666768
EOF
RUN

NAME=r
FILE=malloc://512
CMDS=r
EXPECT=<<EOF
512
EOF
RUN

NAME=wx 90 r pd 1
FILE=malloc://512
CMDS=<<EOF
e asm.arch=x86
e asm.bits=64
wx 90
r
pd 1
EOF
EXPECT=<<EOF
512
            0x00000000      90             nop
EOF
RUN

NAME=rj-pj
FILE=bins/elf/crackme0x05
CMDS=rj
EXPECT=<<EOF
{"size":7656}
EOF
RUN

NAME=r-infloop
FILE=-
CMDS=<<EOF
r- 304 @@s:0x0800 0x022b97a0 2048
?e ok
EOF
EXPECT=<<EOF
ok
EOF
EXPECT_ERR=
RUN

NAME=rapatch2 main from the REPL without PATH
FILE=-
CMDS=<<EOF
r?~rapatch2?
env PATH=
rapatch2
EOF
EXPECT=<<EOF
1
Usage: rapatch2 [-p N] [-sv] [-R] [patchfile] ([targetfile])
EOF
EXPECT_ERR=
RUN

NAME=REPL r2 JavaScript shortcut
FILE=-
ARGS=-NN
CMDS=r2.cmd("?e shortcut").trim()
EXPECT=<<EOF
shortcut
EOF
EXPECT_ERR=
RUN

NAME=REPL missing plugin diagnostics
FILE=-
ARGS=-NN
CMDS=<<EOF
r2mcp ignored
r2ai ignored
r2flutter ignored
r2hermes ignored
r2unity ignored
EOF
EXPECT=
EXPECT_ERR=<<EOF
ERROR: You need to install the plugin with r2pm -ci r2mcp
ERROR: You need to install the plugin with r2pm -ci r2ai
ERROR: You need to install the plugin with r2pm -ci r2flutter
ERROR: You need to install the plugin with r2pm -ci r2hermes
ERROR: You need to install the plugin with r2pm -ci r2unity
EOF
RUN

NAME=REPL rejects tool name suffixes
FILE=malloc://512
ARGS=-NN
CMDS=<<EOF
env PATH=
rax2suffix 33
r2suffix
r
EOF
EXPECT=<<EOF
512
EOF
EXPECT_ERR=<<EOF
ERROR: Invalid `a` subcommand, try `r?`
ERROR: Invalid `2` subcommand, try `r?`
EOF
RUN

NAME=rasm2 main from the REPL without PATH
FILE=-
ARGS=-NN
CMDS=<<EOF
env PATH=
rasm2 -a x86 -b 64 nop
rasm2 -a x86 -b 64 -d 90
rasm2 -a x86 -b 64 "mov rax, 33"
?e after
EOF
EXPECT=<<EOF
90
nop
48c7c021000000
after
EOF
EXPECT_ERR=
RUN

NAME=rasm2 REPL output uses console filters and aliases
FILE=-
ARGS=-NN
CMDS=<<EOF
env PATH=
rasm2~Usage
rasm2 -hh~include
rasm2 -a x86 -b 64 -d 90c3~ret
rasm2 -a x86 -b 64 nop >$assembled
cat $assembled
rasm2 -qv~?
rasm2 -S invalid
?e after
EOF
EXPECT=<<EOF
Usage: rasm2 [-ACdDehHLBvw] [-a arch] [-b bits] [-s addr] [-S syntax]
.include
.incbin foo.bin include binary file
ret
90
1
after
EOF
EXPECT_ERR=
RUN

NAME=rasm2 REPL binary output preserves NUL bytes
FILE=-
ARGS=-NN
CMDS=<<EOF
env PATH=
rasm2 -a x86 -b 64 -B ".hex 410042" >$raw
$**
?e after
EOF
EXPECT=<<EOF
$raw=base64:QQBC
after
EOF
EXPECT_ERR=
RUN

NAME=rasm2 REPL keeps the passed console environment
FILE=-
ARGS=-NN
CMDS=<<EOF
env PATH=
env R2CONS=previous
rasm2 -a x86 -b 64 nop
env~R2CONS=previous?
env~R2CONS=?
rasm2 -S invalid
env~R2CONS=previous?
env~R2CONS=?
?e after
EOF
EXPECT=<<EOF
90
0
1
0
1
after
EOF
EXPECT_ERR=
RUN

NAME=ragg2 main from the REPL without PATH
FILE=-
ARGS=-NN
CMDS=<<EOF
env PATH=
ragg2 -a x86 -b 64 -e "main@global{main(123)}"
ragg2 -a x86 -b 32 -e "main@global{main(123)}"
ragg2 -B 410042 -z
ragg2 -S "hello world"
?e after
EOF
EXPECT=<<EOF
48c7c07b00000050c3
6a7bc3
"\x41\x00\x42"
68656c6c6f20776f726c64
after
EOF
EXPECT_ERR=
RUN

NAME=ragg2 REPL output uses console filters and aliases
FILE=-
ARGS=-NN
CMDS=<<EOF
env PATH=
ragg2~Usage
ragg2 -L~encoders
ragg2 -v~birth~?
r2pm -jv >$version
cat $version~name~?
r2pm -qv~?
ragg2 -H
ragg2 -H R2_NOPLUGINS
ragg2 -q 0x45414146~Big
ragg2 -B 4142 >$compiled
cat $compiled
ragg2 -a x86 -b 64 -s -e "main@global{main(123)}"~ret
?e after
EOF
EXPECT=<<EOF
Usage: ragg2 [-FOLsrxhvz] [-a arch] [-b bits] [-k os] [-o file] [-I path]
encoders:
1
1
1
R2_NOPLUGINS=1
1
Big endian: 12
4142
  ret
after
EOF
EXPECT_ERR=
RUN

NAME=ragg2 REPL code formats use console output
FILE=-
ARGS=-NN
CMDS=<<EOF
env PATH=
ragg2 -B 4142 -f c~const
ragg2 -B 4142 -f python >$python
cat $python
ragg2 -B 4142 -f javascript >$javascript
cat $javascript
?e after
EOF
EXPECT=<<EOF
const unsigned char cstr[2] = ""\
import struct
buf = struct.pack ("2B", *[
0x41,0x42])
[65,66]
after
EOF
EXPECT_ERR=
RUN

NAME=ragg2 REPL binary output preserves NUL bytes
FILE=-
ARGS=-NN
CMDS=<<EOF
env PATH=
ragg2 -r -B 410042 >$raw
$**
?e after
EOF
EXPECT=<<EOF
$raw=base64:QQBC
after
EOF
EXPECT_ERR=
RUN

NAME=ragg2 REPL restores include paths after success and errors
FILE=-
ARGS=-NN
CMDS=<<EOF
env PATH=
env EGG_INCDIR=original
ragg2 -I temporary -B 41
env EGG_INCDIR
ragg2 -I temporary -q invalid
env EGG_INCDIR
ragg2 -B 42
?e after
EOF
EXPECT=<<EOF
41
original
original
42
after
EOF
EXPECT_ERR=<<EOF
ERROR: Need hex value with `0x' prefix e.g. 0x41414142
EOF
RUN

NAME=ragg2 REPL executable output can be captured in aliases
FILE=malloc://512
ARGS=-NN
CMDS=<<EOF
env PATH=
ragg2 -a x86 -b 64 -f elf -B 410042 >$elf
wff $elf
p8 16
?e after
EOF
EXPECT=<<EOF
7f454c46020101000000000000000000
after
EOF
EXPECT_ERR=
RUN

NAME=in-process radiff2 keeps the session console alive
FILE=-
CMDS=<<EOF
radiff2 malloc://8 malloc://8
radiff2 malloc://8 malloc://8
?e alive
EOF
EXPECT=<<EOF
alive
EOF
RUN

NAME=rahash2 main from the REPL without PATH
FILE=-
ARGS=-NN
CMDS=<<EOF
env PATH=
rahash2 -a md5 -s abc
rahash2 -q -a sha1 -s "hello world"
rahash2 -q -a md5 -x 616263
rahash2 -q -a md5 -s ""
?e after
EOF
EXPECT=<<EOF
0x00000000-0x00000002 md5: 900150983cd24fb0d6963f7d28e17f72
2aae6c35c94fcfb415dbe95f408b9ce91ee846ed
900150983cd24fb0d6963f7d28e17f72
d41d8cd98f00b204e9800998ecf8427e
after
EOF
EXPECT_ERR=
RUN

NAME=rahash2 REPL output uses console filters and aliases
FILE=-
ARGS=-NN
CMDS=<<EOF
env PATH=
rahash2~Usage
rahash2 -h~Usage
rahash2 -L~md5~?
rahash2 -jv~{name}
rahash2 -q -a md5 -s abc >$hash
cat $hash
rahash2 -j -a md5 -s abc
rahash2 -J -a md5 -s abc
?e after
EOF
EXPECT=<<EOF
Usage: rahash2 [-BehjkLqRrvX] [-b S] [-a A] [-c H] [-E A] [-s S] [-f O] [-t O] [file] ...
Usage: rahash2 [-BehjkLqRrvX] [-b S] [-a A] [-c H] [-E A] [-s S] [-f O] [-t O] [file] ...
1
rahash2
900150983cd24fb0d6963f7d28e17f72
[{"name":"md5","hash":"900150983cd24fb0d6963f7d28e17f72"}]
{"md5":"900150983cd24fb0d6963f7d28e17f72"}
after
EOF
EXPECT_ERR=
RUN

NAME=rahash2 REPL hashes files and blocks
FILE=-
ARGS=-NN
CMDS=<<EOF
env PATH=
rahash2 -qq -a md5 malloc://4
rahash2 -j -a md5 malloc://4
rahash2 -B -b 2 -a md5 malloc://4
?e after
EOF
EXPECT=<<EOF
f1d3ff8443297732862df21dc4e57262
[{"name":"md5","hash":"f1d3ff8443297732862df21dc4e57262"}]
0x00000000-0x00000001 md5: c4103f122d27677c9db144cae1394a66
0x00000002-0x00000003 md5: c4103f122d27677c9db144cae1394a66
after
EOF
EXPECT_ERR=
RUN

NAME=rahash2 REPL binary output preserves NUL bytes
FILE=-
ARGS=-NN
CMDS=<<EOF
env PATH=
rahash2 -D base64 -s QQBC >$raw
$**
rahash2 -X -D base64 -s QQBC
rahash2 -j -E base64 -x 410042
rahash2 -E base64 -x 410042 >$encoded
cat $encoded
?e after
EOF
EXPECT=<<EOF
$raw=base64:QQBC
410042
{"algo":"base64","mode":"encrypt","data":[81,81,66,67]}
QQBC
after
EOF
EXPECT_ERR=
RUN

NAME=rahash2 REPL reports failures and remains usable
FILE=-
ARGS=-NN
CMDS=<<EOF
env PATH=
rahash2 -a invalid -s abc
?v $?
rahash2 -a md5 -c zz -s abc
?v $?
rahash2 -a md5 -c 00 -s abc
?v $?
rahash2 -qqq -a md5 -c 00000000000000000000000000000000 malloc://4
?v $?
rahash2 -qqq -a md5 -c f1d3ff8443297732862df21dc4e57262 malloc://4
?v $?
rahash2 -q -a md5 -s abc
?v $?
?e after
EOF
EXPECT=<<EOF
0x1
0x1
0x1
0x1
0x0
900150983cd24fb0d6963f7d28e17f72
0x0
after
EOF
EXPECT_ERR=<<EOF
ERROR: Invalid algorithm. See -E, -D maybe?
ERROR: Invalid -c hex hash
ERROR: Given -c hash has 1 byte(s) but the selected algorithm returns 16 byte(s)
EOF
RUN

NAME=rahash2 REPL keeps options local to each invocation
FILE=-
ARGS=-NN
CMDS=<<EOF
env PATH=
rahash2 -q -a md5 -S s:seed -s abc
rahash2 -q -a md5 -S ^s:seed -s abc
rahash2 -q -a md5 -f 1 -t 3 -s xabcx
rahash2 -q -a md5 -s abc
rahash2 -q -a md5 -s abc
?e after
EOF
EXPECT=<<EOF
175b444114a8dd5256128a6310ed8965
196d127761e0501b24ab74842ec36a8b
900150983cd24fb0d6963f7d28e17f72
900150983cd24fb0d6963f7d28e17f72
900150983cd24fb0d6963f7d28e17f72
after
EOF
EXPECT_ERR=
RUN

NAME=rahash2 streaming preserves filters and captures
FILE=-
ARGS=-NN
CMDS=<<EOF
env PATH=
e scr.flush=true
rahash2 -B -b 2 -a md5 malloc://4~?
rahash2 -B -b 2 -a md5 malloc://4~0x00000002
rahash2 -B -b 2 -a md5 malloc://4 >$hashes
cat $hashes
rahash2 -q -a md5 malloc://4
rahash2 -qq -a md5 malloc://4
rahash2 -qqq -a md5 malloc://4
.rahash2 -R -a md5 -s abc
k file.md5
e scr.flush=false
?e after
EOF
EXPECT=<<EOF
2
0x00000002-0x00000003 md5: c4103f122d27677c9db144cae1394a66
0x00000000-0x00000001 md5: c4103f122d27677c9db144cae1394a66
0x00000002-0x00000003 md5: c4103f122d27677c9db144cae1394a66
f1d3ff8443297732862df21dc4e57262 malloc://4
f1d3ff8443297732862df21dc4e57262
900150983cd24fb0d6963f7d28e17f72
after
EOF
EXPECT_ERR=
RUN

NAME=rahash2 streaming keeps JSON and binary captures intact
FILE=-
ARGS=-NN
CMDS=<<EOF
env PATH=
e scr.flush=true
rahash2 -j -B -b 2 -a md5 malloc://4 >$json
cat $json
rahash2 -J -a md5 malloc://4 >$object
cat $object
rahash2 -D base64 -s QQBC >$raw
$**~raw
rahash2 -j -a md5 -s abc~{[0].hash}
e scr.flush=false
?e after
EOF
EXPECT=<<EOF
[{"name":"md5","hash":"c4103f122d27677c9db144cae1394a66"},{"name":"md5","hash":"c4103f122d27677c9db144cae1394a66"}]
{"md5":"f1d3ff8443297732862df21dc4e57262"}
$raw=base64:QQBC
900150983cd24fb0d6963f7d28e17f72
after
EOF
EXPECT_ERR=
RUN

NAME=rahash2 plots run without PATH and preserve the caller
FILE=hex://90909090
ARGS=-NN
CMDS=<<EOF
env PATH=
s 1
b 2
e asm.bits=32
rahash2 -p e malloc://256~?
rahash2 -p b malloc://256 >$plot
cat $plot~malloc
cat $plot~?
rahash2 -p ? malloc://256~Usage
rahash2 -p e malloc://256 malloc://512~malloc
?v $$
?v $b
e asm.bits
e scr.interactive
p8 2
?e after
EOF
EXPECT=<<EOF
15
malloc://256:
15
Usage: p=[=bep?][qj] [N] ([len]) ([offset])   show entropy/printable chars/chars bars
malloc://256:
malloc://512:
0x1
0x2
32
false
9090
after
EOF
EXPECT_ERR=
RUN

NAME=rahash2 plot failures leave the shell usable
FILE=-
ARGS=-NN
CMDS=<<EOF
env PATH=
rahash2 -p e ""
?v $?
rahash2 -p e /missing-rahash2-input
?v $?
rahash2 -p e malloc://256 >$plot
?v $?
cat $plot~?
rahash2 -q -a md5 -s abc
?e after
EOF
EXPECT=<<EOF
0x1
/missing-rahash2-input:
0x1
0x0
15
900150983cd24fb0d6963f7d28e17f72
after
EOF
EXPECT_ERR=<<EOF
ERROR: Cannot open empty path
ERROR: Cannot open '/missing-rahash2-input'
EOF
RUN

NAME=rafind2 main from the REPL without PATH
FILE=-
ARGS=-NN
CMDS=<<EOF
env PATH=
rafind2 -b 2 -s ab hex://5f61626364656600
rafind2 -x 6162 hex://5f61626364656600
rafind2 -e /a.c/ hex://5f61626364656600
rafind2 -b 2 -Z -S ab hex://5f006100620063000000
rafind2 -V 1:97 hex://5f61626364656600
rafind2 -s "hello world" hex://68656c6c6f20776f726c6400
rafind2 -s ab hex://616200 hex://5f616200
?e after
EOF
EXPECT=<<EOF
0x1
0x1
0x1
0x2 abc
0x1
0x0
hex://616200: 0x0
hex://5f616200: 0x1
after
EOF
EXPECT_ERR=
RUN

NAME=rafind2 REPL output uses console filters and aliases
FILE=-
ARGS=-NN
CMDS=<<EOF
env PATH=
r?~rafind2?
rafind2~Usage
rafind2 -h~Usage
rafind2 -jv~{name}
rafind2 -qv~?
rafind2 -s ab hex://5f61626364656600 >$hits
cat $hits
rafind2 -b 2 -j -s ab hex://5f61626364656600
.rafind2 -r -s ab hex://5f61626364656600
?v hit0_0
?e after
EOF
EXPECT=<<EOF
1
Usage: rafind2 [-mBXnzZhqv] [-a align] [-b sz] [-f/t from/to] [-[e|s|S] str] [-x hex] [-R str] [-I str] [-g] -|file|dir ..
Usage: rafind2 [-mBXnzZhqv] [-a align] [-b sz] [-f/t from/to] [-[e|s|S] str] [-x hex] [-R str] [-I str] [-g] -|file|dir ..
rafind2
1
0x1
[{"file":"hex://5f61626364656600","offset":1,"type":"string","data":"abcdef"}]
0x1
after
EOF
EXPECT_ERR=
RUN

NAME=rafind2 REPL captures hexdumps
FILE=-
ARGS=-NN
CMDS=<<EOF
env PATH=
rafind2 -cX -s 250382 -b 3 bins/elf/ioli/crackme0x00 >$dump
cat $dump
rafind2 -cX -s 250382 -b 3 bins/elf/ioli/crackme0x00~0x0000058f
?e after
EOF
EXPECT=<<EOF
0x58f
- offset -   0 1  2 3  4 5  6 7  8 9  A B  C D  E F  0123456789ABCDEF
0x0000058f  3235 30                                  250
0x0000058f  3235 30                                  250
after
EOF
EXPECT_ERR=
RUN

NAME=rafind2 REPL reports failures and remains usable
FILE=-
ARGS=-NN
CMDS=<<EOF
env PATH=
rafind2 -b 1 -s ab hex://616200
?v $?
rafind2 -R h:zz -s ab hex://616200
?v $?
rafind2 -V 3:1 hex://616200
?v $?
rafind2 -s ab ""
?v $?
rafind2 -s ab /missing-rafind2-input
?v $?
rafind2 -s ab hex://616200
?v $?
?e after
EOF
EXPECT=<<EOF
0x1
0x1
0x1
0x1
0x1
0x0
0x0
after
EOF
EXPECT_ERR=<<EOF
ERROR: Invalid blocksize <= 1
ERROR: Invalid replace string
ERROR: Invalid value size. Must be 1, 2, 4 or 8
ERROR: Cannot open empty path
ERROR: Cannot open file '/missing-rafind2-input'
EOF
RUN

NAME=rafind2 streaming preserves filters and captures
FILE=-
ARGS=-NN
CMDS=<<EOF
env PATH=
e scr.flush=true
rafind2 -s ab hex://616200616200~?
rafind2 -s ab hex://616200616200~0x3
rafind2 -s ab hex://616200616200 >$hits
cat $hits
.rafind2 -r -s ab hex://5f616200
?v hit0_0
e scr.flush=false
?e after
EOF
EXPECT=<<EOF
2
0x3
0x0
0x3
0x1
after
EOF
EXPECT_ERR=
RUN

NAME=rafind2 internal core modes without PATH preserve the caller
FILE=hex://90909090
ARGS=-NN
CMDS=<<EOF
env PATH=
env R2CORE=caller
s 1
b 2
e asm.arch=x86
e asm.bits=32
rafind2 -z hex://61626364656600 >$strings
cat $strings
rafind2 -jz hex://61626364656600~{}
rafind2 -ci bins/elf/ioli/crackme0x00~ELF
rafind2 -cm -f 0 -t 64 bins/elf/ioli/crackme0x00 >$magic
cat $magic
rafind2 -E 0 hex://00000000
?v $$
?v $b
e asm.bits
e scr.interactive
p8 2
env PATH
env R2CORE
?e after
EOF
EXPECT=<<EOF
0x00000000 abcdef
[
  {
    "vaddr": 0,
    "paddr": 0,
    "ordinal": 0,
    "size": 7,
    "length": 6,
    "section": "",
    "type": "ascii",
    "string": "abcdef"
  }
]
0x00000000 0 ELF 32-bit LSB executable, Intel 80386, version 1
0x00000000 0 hit0_0 ELF 32-bit LSB executable, Intel 80386, version 1
0x1
0x2
32
false
9090

caller
after
EOF
RUN

NAME=rafind2 restores the environment after core open failures
FILE=-
ARGS=-NN
CMDS=<<EOF
env PATH=caller-path
env R2CORE=caller-core
rafind2 -ci /missing-rafind2-input
?v $?
env PATH
env R2CORE
rafind2 -cz hex://61626364656600
env PATH
env R2CORE
?e after
EOF
EXPECT=<<EOF
0x1
caller-path
caller-core
0x00000000 abcdef
caller-path
caller-core
after
EOF
EXPECT_ERR=
RUN

NAME=nested r2 quick exits preserve the parent shell without PATH
FILE=hex://01020304
ARGS=-NN
CMDS=<<EOF
env PATH=
s 1
b 2
r2 -NNQ -c "?e nested" --
r2 -NNLQ -c "?e nested-list" --
?v $$
?v $b
p8 2
?e parent-alive
EOF
EXPECT=<<EOF
nested
nested-list
0x1
0x2
0203
parent-alive
EOF
EXPECT_ERR=
RUN

NAME=nested r2 quick exits preserve sandboxed sessions
FILE=-
ARGS=-NN
CMDS=<<EOF
e cfg.sandbox.grain=none
e cfg.sandbox=true
r2 -NNQ --
r2 -NNLQ --
?e parent-alive
EOF
EXPECT=<<EOF
parent-alive
EOF
RUN
