NAME=wen 3
FILE=malloc://100
CMDS=<<EOF
r
wen 3
r
EOF
EXPECT=<<EOF
100
103
EOF
RUN

NAME=wen 3 writable bin
FILE=--
CMDS=<<EOF
mkdir .tmp
cp bins/mach0/mac-ls2 .tmp/ls-wen
o .tmp/ls-wen
r
wen 3
r
oo+
r
wen 3
r
rm .tmp/ls-wen
EOF
EXPECT=<<EOF
38704
38704
38704
38707
EOF
RUN

NAME=wen 3 in readonly bin
FILE=bins/mach0/mac-ls2
CMDS=<<EOF
# cannot resize in va and non-write mode
r
wen 3
r
EOF
EXPECT=<<EOF
38704
38704
EOF
RUN

NAME=quoted comments bug
FILE=malloc://1024
CMDS=<<EOF
w "hello # world"
ps
EOF
EXPECT=<<EOF
hello # world
EOF
RUN

NAME=labels replacements (common prefix)
FILE=malloc://1024
ARGS=-a x86 -b 32
CMDS=<<EOF
p8 7 @ 0
waf bins/other/asm/multiline_prefix.asm
p8 7 @ 0
EOF
EXPECT=<<EOF
00000000000000
9090e803000000
EOF
RUN

NAME=wa
FILE=malloc://1024
ARGS=-a x86 -b 32
CMDS=<<EOF
wa "nop;mov eax,33"
pi 2
EOF
EXPECT=<<EOF
nop
mov eax, 0x21
EOF
RUN

NAME=wa je 0x33
FILE=malloc://1024
ARGS=-a x86 -b 32
CMDS=<<EOF
wa "je 0x33" @ 0x10
pi 1 @ 0x10
EOF
EXPECT=<<EOF
je 0x33
EOF
RUN

# wao : modify operation of current opcode
NAME=wao nop (x86)
FILE=malloc://1024
ARGS=-a x86 -b 64
CMDS=<<EOF
wx 31ed4989d15e4889e24883e4f0
pi 5
wao nop
pi 3
EOF
EXPECT=<<EOF
xor ebp, ebp
mov r9, rdx
pop rsi
mov rdx, rsp
and rsp, 0xfffffffffffffff0
nop
nop
mov r9, rdx
EOF
RUN

# wao : modify operation of current opcode
NAME=wao trap (x86)
FILE=malloc://1024
ARGS=-a x86 -b 64
CMDS=<<EOF
wx 31ed4989d15e4889e24883e4f0
pi 5
wao trap
pi 3
EOF
EXPECT=<<EOF
xor ebp, ebp
mov r9, rdx
pop rsi
mov rdx, rsp
and rsp, 0xfffffffffffffff0
int3
in eax, dx
mov r9, rdx
EOF
RUN

# wao : modify operation of current opcode, on ARM
NAME=wao nop (arm)
FILE=malloc://1024
ARGS=-a arm -b 32
CMDS=<<EOF
wx 24c09fe500b0a0e304109de40d20a0e1
pi 4
wao nop
pi 3
EOF
EXPECT=<<EOF
ldr ip, [0x0000002c]
mov fp, 0
pop {r1}
mov r2, sp
mov r0, r0
mov fp, 0
pop {r1}
EOF
RUN

# wao : modify operation of current opcode, on ARM
NAME=wao trap (arm)
FILE=malloc://1024
ARGS=-a arm -b 32
CMDS=<<EOF
wx 24c09fe500b0a0e304109de40d20a0e1
pi 4
wao trap
pi 3
EOF
EXPECT=<<EOF
ldr ip, [0x0000002c]
mov fp, 0
pop {r1}
mov r2, sp
trap
mov fp, 0
pop {r1}
EOF
RUN


## "wx" - write hex value

# Writing of bytes.
NAME=wx
FILE=malloc://1024
CMDS=<<EOF
wx 010203
p8 3
EOF
EXPECT=<<EOF
010203
EOF
RUN

## "wxf" - write hex pairs from file

NAME=wxf
FILE=malloc://1024
CMDS=<<EOF
wxf bins/other/hexpairs
p8 4
EOF
EXPECT=<<EOF
de4db33f
EOF
RUN

## "wo" - write in block with operation

# Batch adding to bytes works (bug report #59).
NAME=wo
FILE=malloc://8
ARGS=-w
CMDS=<<EOF
wx 0001020304050607
woa 01 @ 0!8
p8 8
woa 01 @ 0!8
p8 8
EOF
EXPECT=<<EOF
0102030405060708
0203040506070809
EOF
RUN

NAME=write to file 2
FILE==
#bins/pe/b.exe
CMDS=<<EOF
pr 0x400 > a_piece_of_ls_saved_to_PWD
ls -l a_piece_of_ls_saved_to_PWD~[3]
rm a_piece_of_ls_saved_to_PWD
EOF
EXPECT=<<EOF
1024
EOF
EXPECT_ERR=<<EOF

EOF
RUN

NAME=endian tests: wv
FILE==
CMDS=<<EOF
e cfg.bigendian=false
e asm.bits=32
wv4 3
p8 4
e cfg.bigendian=true
wv4 3
p8 4
EOF
EXPECT=<<EOF
03000000
00000003
EOF
RUN

NAME=wv endian
FILE=malloc://1024
CMDS=<<EOF
e cfg.bigendian=false
wv4 0x1234
p8 2
wv4 0x12345678
p8 4
EOF
EXPECT=<<EOF
3412
78563412
EOF
RUN

NAME=wx 0x
FILE=malloc://1024
CMDS=<<EOF
e cfg.bigendian=false
wx 0x1234
p8 2
wx 0x12345678
p8 4
EOF
EXPECT=<<EOF
1234
12345678
EOF
RUN

NAME=wci should commit the changes to the file
FILE=malloc://1024
CMDS=<<EOF
mkdir .tmp
cp bins/pe/b.exe .tmp/.b.exe.orig
cp bins/pe/b.exe .tmp/.b.exe.new
o+ .tmp/.b.exe.new
wx ff
wci
!!rz-diff -C -t command -0 "px 10" -1 "px 10" .tmp/.b.exe.orig .tmp/.b.exe.new
o--
rm .tmp/.b.exe.orig
rm .tmp/.b.exe.new
EOF
EXPECT=<<EOF
--- .tmp/.b.exe.orig
+++ .tmp/.b.exe.new
@@ --1,4 +-1,4 @@
 - offset -   0 1  2 3  4 5  6 7  8 9  A B  C D  E F  0123456789ABCDEF
-0x00401280  5589 e583 ec08 c704 2401                 U.......$.
+0x00401280  ff89 e583 ec08 c704 2401                 ........$.

EOF
RUN

NAME=wci should commit all the changes
FILE=malloc://512
CMDS=<<EOF
e io.cache=true
(wxseek ;  wx 909090;  sd +3)
3.(wxseek)
wci
wc
EOF
EXPECT=<<EOF
idx=0 addr=0x00000000 size=3 000000 -> 909090 (written)
idx=1 addr=0x00000003 size=3 000000 -> 909090 (written)
idx=2 addr=0x00000006 size=3 000000 -> 909090 (written)
EOF
RUN

NAME=wx pcache
FILE=bins/pe/b.exe
CMDS=<<EOF
e io.va=0
e io.pcache=true
s 0
ps @! 2
wx 9090
p8 2
e io.pcache=0
sd +1
s 0
ps @! 2
EOF
EXPECT=<<EOF
MZ
9090
MZ
EOF
RUN

NAME=w octal esc
FILE=malloc://16
CMDS=<<EOF
w 0123456789abcde
w a\57b\0
w 1\0532\0 @ 0x4
w 0\1741\0 @ 0x8
ps @e:str.encoding=utf8
ps @ 0x4 @e:str.encoding=utf8
ps @ 0x8 @e:str.encoding=utf8
EOF
EXPECT=<<EOF
a/b
1+2
0|1
EOF
RUN

## "wen" - insert null bytes

NAME=wen
FILE=malloc://4
CMDS=<<EOF

wx 01020304
wen 2 @ 1
wen 1 @ 6
p8 7
EOF
EXPECT=<<EOF
01000002030400
EOF
RUN

NAME=wen should insert X null bytes even if io.cache=false
FILE=--
CMDS=<<EOF
cp bins/pe/b.exe .b.exe
o+ .b.exe
r
s 0x200
wen 1
r
o--
rm .b.exe
EOF
EXPECT=<<EOF
216607
216608
EOF
RUN

## wxs: write hex and seek

FILE=malloc://1024
NAME=data written after multiple wxs
CMDS=<<EOF
2 wx 9090 @ 8 @e:cfg.wseek=true
x 16 @ 0
EOF
EXPECT=<<EOF
- offset -   0 1  2 3  4 5  6 7  8 9  A B  C D  E F  0123456789ABCDEF
0x00000000  0000 0000 0000 0000 9090 9090 0000 0000  ................
EOF
RUN

FILE=malloc://1024
NAME=address after wxs at tmpseek
CMDS=<<EOF
2 wx 9090 @ 8 @e:cfg.wseek=true
%vi $$
EOF
EXPECT=<<EOF
0
EOF
RUN

NAME=wz esc seqs
FILE==
CMDS=<<EOF
e str.escbslash=true
wz \a\b\t\n\v\f\r\e\\\x40\7\15\176
izz~0x0
px 16~0x0
EOF
EXPECT=<<EOF
  0 0x00000000 0x00000000  13   14         ascii \a\b\t\n\v\f\r\e\\@\a\r~
0x00000000  0708 090a 0b0c 0d1b 5c40 070d 7e00 0000  ........\@..~...
EOF
RUN

NAME=wz macro + \\ esc seq
FILE==
CMDS=<<EOF
b 16
$addr=$0
$new_addr=%v \`$addr\`+16
(wz_px str; wz ${str}; px~:1)
(wz16 str; .(wz_px ${str}) @ `$addr`; $addr=$`$new_addr`)
.(wz16 \\)
.(wz16 \\\\)
.(wz16 \\a)
.(wz16 "a \\ b")
.(wz16 a\\)
.(wz16 "c `%vi 123+1` d")
.(wz16 \`)
.(wz16 "e \` f")
..(wz16 \# "g \# h" "i \" j")
EOF
EXPECT=<<EOF
0x00000000  5c00 0000 0000 0000 0000 0000 0000 0000  \...............
0x00000010  5c5c 0000 0000 0000 0000 0000 0000 0000  \\..............
0x00000020  5c61 0000 0000 0000 0000 0000 0000 0000  \a..............
0x00000030  6120 5c20 6200 0000 0000 0000 0000 0000  a \ b...........
0x00000040  615c 0000 0000 0000 0000 0000 0000 0000  a\..............
0x00000050  6320 3132 3420 6400 0000 0000 0000 0000  c 124 d.........
0x00000060  6000 0000 0000 0000 0000 0000 0000 0000  `...............
0x00000070  6520 6020 6600 0000 0000 0000 0000 0000  e ` f...........
0x00000080  2300 0000 0000 0000 0000 0000 0000 0000  #...............
0x00000090  6720 2320 6800 0000 0000 0000 0000 0000  g # h...........
0x000000a0  6920 2220 6a00 0000 0000 0000 0000 0000  i " j...........
EOF
EXPECT_ERR=
RUN

NAME=Automatically reanalyze function control flow after a write
FILE==
ARGS=-a x86 -b 64 -e analysis.detectwrites=true
CMDS=<<EOF
e asm.bytes=true
wa "jne 6" @ 2
wa ret @ 8
af
pdr
wa "jne 8" @ 4
pdr
wa "mov rax, [rbp-4]"
pdr
afvn test var_4h
wa "jne 0" @ 4
pdr
wx 00000000
afvl # check var was deleted
EOF
EXPECT=<<EOF
/ fcn.00000000();
| 0x00000000      0000           add   byte [rax], al
| 0x00000002      7502           jne   6
| ----------- true: 0x00000006  false: 0x00000004
| 0x00000004      0000           add   byte [rax], al
| ----------- true: 0x00000006
| 0x00000006      0000           add   byte [rax], al
\ 0x00000008      c3             ret

/ fcn.00000000();
| 0x00000000      0000           add   byte [rax], al
| 0x00000002      7502           jne   6
| ----------- true: 0x00000006  false: 0x00000004
| 0x00000004      7502           jne   8
| ----------- true: 0x00000008  false: 0x00000006
| 0x00000006      0000           add   byte [rax], al
| ----------- true: 0x00000008
\ 0x00000008      c3             ret

/ fcn.00000000();
| ; var int64_t var_4h @ stack - 0x4
| 0x00000000      488b45fc       mov   rax, qword [var_4h]
| 0x00000004      7502           jne   8
| ----------- true: 0x00000008  false: 0x00000006
| 0x00000006      0000           add   byte [rax], al
| ----------- true: 0x00000008
\ 0x00000008      c3             ret

/ fcn.00000000();
| ; var int64_t test @ stack - 0x4
| 0x00000000      488b45fc       mov   rax, qword [test]
| 0x00000004      75fa           jne   fcn.00000000
| ----------- true: 0x00000000  false: 0x00000006
| 0x00000006      0000           add   byte [rax], al
\ 0x00000008      c3             ret

EOF
RUN

NAME=Write misaligns jump instruction, control flow is reanalyzed
FILE==
ARGS=-a x86 -b 64 -e analysis.detectwrites=true
CMDS=<<EOF
e asm.bytes=true
wx e80200000075020000c3
af
pdr
wa "jne 9"
pdr
wx e802
pdr
EOF
EXPECT=<<EOF
/ fcn.00000000();
| 0x00000000      e802000000     call  7
| 0x00000005      7502           jne   9
| ----------- true: 0x00000009  false: 0x00000007
| ; CALL XREF from fcn.00000000 @ 
| 0x00000007      0000           add   byte [rax], al
| ----------- true: 0x00000009
\ 0x00000009      c3             ret

/ fcn.00000000(int64_t arg_2h);
| ; arg int64_t arg_2h @ stack + 0x2
| 0x00000000      7507           jne   9
| ----------- true: 0x00000009  false: 0x00000002
| 0x00000002      0000           add   byte [rax], al
| 0x00000004      007502         add   byte [arg_2h], dh
| ; CALL XREF from fcn.00000000 @ 
| 0x00000007      0000           add   byte [rax], al
| ----------- true: 0x00000009
\ 0x00000009      c3             ret

/ fcn.00000000(int64_t arg_2h);
| ; arg int64_t arg_2h @ stack + 0x2
| 0x00000000      e802000000     call  7
| 0x00000005      7502           jne   9
| ----------- true: 0x00000009  false: 0x00000007
| ; CALL XREF from fcn.00000000 @ 
| 0x00000007      0000           add   byte [rax], al
| ----------- true: 0x00000009
\ 0x00000009      c3             ret

EOF
RUN

NAME=Write reanalysis keeps already unreachable block
FILE==
ARGS=-a x86 -b 64 -e analysis.detectwrites=true
CMDS=<<EOF
e asm.bytes=true
wx 0000c300c3
af
afb+ 0 4 1
pdr
wa "add byte [rax], bl"
pdr
EOF
EXPECT=<<EOF
/ fcn.00000000();
| 0x00000000      0000           add   byte [rax], al
| 0x00000002      c3             ret

\ 0x00000004      c3             ret

/ fcn.00000000();
| 0x00000000      0018           add   byte [rax], bl
| 0x00000002      c3             ret

\ 0x00000004      c3             ret

EOF
RUN

NAME=Write reanalysis of child of non-modified block
FILE==
ARGS=-a x86 -b 64 -e analysis.detectwrites=true
CMDS=<<EOF
e asm.bytes=true
wx eb020000000075fac3
af
wx eb04eb02
pdr
af-
wx eb020000eb020000000075fac3
af
wx eb040000eb02 @ 4
pdr
EOF
EXPECT=<<EOF
/ fcn.00000000();
| 0x00000000      eb04           jmp   6
| ----------- true: 0x00000006
| 0x00000002      eb02           jmp   6
| ----------- true: 0x00000006
| ; CODE XREFS from fcn.00000000 @ , 0x2
| 0x00000006      75fa           jne   2
| ----------- true: 0x00000002  false: 0x00000008
\ 0x00000008      c3             ret

/ fcn.00000000();
| 0x00000000      eb02           jmp   4
| ----------- true: 0x00000004
| ; CODE XREF from fcn.00000000 @ 
| 0x00000004      eb04           jmp   0xa
| ----------- true: 0x0000000a
| ; CODE XREF from fcn.00000000 @ 
| ; CODE XREF from fcn.00000000 @ +0x2
| 0x00000006      0000           add   byte [rax], al
| ; CODE XREF from fcn.00000000 @ 0x4
| 0x00000008      eb02           jmp   0xc
| ----------- true: 0x0000000c
| ; CODE XREF from fcn.00000000 @ 0x4
| 0x0000000a      75fa           jne   6
| ----------- true: 0x00000006  false: 0x0000000c
| ; CODE XREF from fcn.00000000 @ 0x8
\ 0x0000000c      c3             ret

EOF
RUN

NAME=wd
FILE=malloc://20
CMDS=<<EOF
wx 1122334455667788
p8 8 @ 0
s 4
wd 0 2
p8 8 @ 0
EOF
EXPECT=<<EOF
1122334455667788
1122334411227788
EOF
RUN
