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
BROKEN=1
CMDS=<<EOF
e asm.arch=x86
e asm.bits=32
waf bins/other/asm/multiline_prefix.asm
p8 7@0
EOF
EXPECT=<<EOF
9090e8fbffffff
EOF
RUN


NAME=wa
FILE=malloc://1024
ARGS=-a x86 -b 32
CMDS=<<EOF
"wa nop;mov eax,33"
e asm.profile=simple
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 -e io.cache=1
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 -e io.cache=1
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 -e io.cache=1
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 -e io.cache=1
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

## "wt" - write to file

# see bug #503
NAME=wt
FILE=-
#bins/pe/b.exe
CMDS=<<EOF
wt a_piece_of_ls_saved_to_PWD 0x400
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
Dumped 1024 bytes from 0x00000000 into a_piece_of_ls_saved_to_PWD
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 should behave like wv? imho nope
FILE=malloc://1024
BROKEN=1
CMDS=<<EOF
e cfg.bigendian=false
wx 0x1234
p8 2
wx 0x12345678
p8 4
EOF
EXPECT=<<EOF
3412
78563412
EOF
RUN

NAME=wci should commit the changes to the file
FILE=malloc://1024
BROKEN=1
CMDS=<<EOF
!rm -rf .tmp
mkdir .tmp
cp -f bins/pe/b.exe .tmp/.b.exe.orig
cp -f bins/pe/b.exe .tmp/.b.exe.new
e io.cache=true
o+ .tmp/.b.exe.new
wx ff
wci
e.src.null=true
!!rz-diff .tmp/.b.exe.orig .tmp/.b.exe.new
EOF
EXPECT=<<EOF
File size
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
ps @ 0x4
ps @ 0x8
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
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 wxs 9090 @ 8
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 wxs 9090 @ 8
?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=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
afv # check var was deleted
EOF
EXPECT=<<EOF
/ 9: 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

/ 9: 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

/ 9: fcn.00000000 ();
| ; var int64_t var_4h @ rbp-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

/ 9: fcn.00000000 ();
| ; var int64_t test @ rbp-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
/ 10: 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

/ 10: fcn.00000000 (int64_t arg_2h);
| ; arg int64_t arg_2h @ rbp+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

/ 10: fcn.00000000 (int64_t arg_2h);
| ; arg int64_t arg_2h @ rbp+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
/ 4: fcn.00000000 ();
| 0x00000000      0000           add   byte [rax], al
| 0x00000002      c3             ret

\ 0x00000004      c3             ret

/ 4: 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
/ 7: 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

/ 11: 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
