def
write_mem_str(addr, content):
global
vm_ctx
if
type
(content)
=
=
str
:
for
i
in
range
(
len
(content)):
vm_ctx[addr
+
i]
=
ord
(content[i])
else
:
raise
Exception(
"TODO"
)
return
addr
def
write_mem_word(addr, content):
global
vm_ctx
for
i
in
range
(
2
):
vm_ctx[addr
+
i]
=
content &
0xFF
content >>
=
8
def
write_mem_arr(addr, arr):
global
vm_ctx
for
i
in
range
(
len
(arr)):
vm_ctx[addr
+
i]
=
arr[i]
def
write_mem_dword(addr, content):
global
vm_ctx
for
i
in
range
(
4
):
vm_ctx[addr
+
i]
=
content &
0xFF
content >>
=
8
def
read_mem_dword(addr):
global
vm_ctx
return
vm_ctx[addr] | (vm_ctx[addr
+
1
] <<
8
) | (vm_ctx[addr
+
2
] <<
16
) | (vm_ctx[addr
+
3
] <<
24
)
def
read_mem_word(addr):
global
vm_ctx
return
vm_ctx[addr] | (vm_ctx[addr
+
1
] <<
8
)
def
read_mem_byte(addr):
global
vm_ctx
return
vm_ctx[addr]
def
push_data(data):
global
vm_ctx
sp
=
read_mem_word(
0x10002
)
tmp
=
sp
+
4
write_mem_word(
0x10002
, tmp)
write_mem_dword(tmp, data)
def
pop_data():
global
vm_ctx
sp
=
read_mem_word(
0x10002
)
data
=
read_mem_dword(sp)
write_mem_word(
0x10002
, sp
-
4
)
return
data
def
read_sp_data():
sp
=
read_mem_word(
0x10002
)
data
=
read_mem_dword(sp)
return
data
def
set_sp_data(data):
sp
=
read_mem_word(
0x10002
)
write_mem_dword(sp, data)
def
load_opcodes():
global
vm_ctx
with
open
(
"./dump/opcodes"
, mode
=
"rb"
) as f:
opcodes
=
bytearray(f.read())
for
i
in
range
(
len
(opcodes)):
vm_ctx[
0xC000
+
i]
=
opcodes[i]
def
hex_to_negative(value, bits
=
8
):
if
value & (
1
<< (bits
-
1
)):
value
=
value
-
(
1
<< bits)
return
value
def
start_vm():
global
vm_ctx, pc, arg, v13
pc
=
None
arg
=
None
v13
=
None
def
handler_0_xor():
n1
=
pop_data()
n2
=
read_sp_data()
res
=
n1 ^ n2
set_sp_data(res)
print
(f
"[h0_xor]\t pop, *sp = {hex(n2)} ^ {hex(n1)} = {hex(res)}"
)
def
handler_1_opposite():
n
=
read_sp_data()
set_sp_data(
-
n)
print
(f
"[h1_opposite]\t *sp = -{hex(n)}"
)
def
handler_2_subsp():
sp
=
read_mem_word(
0x10002
)
write_mem_word(
0x10002
, sp
-
4
*
arg)
print
(f
"[h2_subsp]\t sp -= {4 * arg}"
)
def
handler_4_orr():
n1
=
pop_data()
n2
=
read_sp_data()
res
=
n1 | n2
set_sp_data(res)
print
(f
"[h4_orr]\t pop, *sp = {hex(n2)} | {hex(n1)} = {hex(res)}"
)
def
handler_5_():
global
pc
sp
=
read_mem_word(
0x10002
)
v23
=
read_sp_data()
v24
=
sp
-
8
-
4
*
arg
+
4
pc
=
read_mem_dword(sp
-
4
)
write_mem_word(
0x10002
, v24)
write_mem_dword(v24, v23)
print
(f
"[h5_]\t sp = {hex(v24)}, [{hex(v24)}] = {hex(v23)}, pc = {hex(pc)}"
)
def
handler_6_noeq():
n1
=
pop_data()
n2
=
read_sp_data()
res
=
n1 !
=
n2
set_sp_data(res)
print
(f
"[h6_noeq]\t pop, *sp = {hex(n2)} != {hex(n1)} = {hex(res)}"
)
def
handler_7_swap():
global
arg
sp
=
read_mem_word(
0x10002
)
n1
=
read_mem_dword(sp)
n2
=
read_mem_dword(sp
-
4
*
arg)
write_mem_dword(sp, n2)
write_mem_dword(sp
-
4
*
arg, n1)
print
(f
"[h7_swap]\t swap(sp, sp - {arg}) -> swap({hex(n1), hex(n2)})"
)
def
handler_8_and():
n1
=
pop_data()
n2
=
read_sp_data()
res
=
n1 & n2
set_sp_data(res)
print
(f
"[h8_and]\t pop, *sp = {hex(n2)} & {hex(n1)} = {hex(res)}"
)
def
handler_9_lsl():
sp_data
=
read_sp_data()
set_sp_data(sp_data << arg)
print
(f
"[h9_lsl]\t *sp = *sp << arg = {hex(sp_data)} << {arg} = {hex(sp_data << arg)}"
)
def
handler_10_not():
sp_data
=
read_sp_data()
set_sp_data(~sp_data)
print
(f
"[h10_not]\t *sp = ~(*sp) = ~{hex(sp_data)} = {hex(~sp_data & 0xffffffff)}"
)
def
handler_12_add():
n1
=
pop_data()
n2
=
read_sp_data()
res
=
n1
+
n2
set_sp_data(res)
print
(f
"[h12_add]\t pop, *sp = {hex(n2)} + {hex(n1)} = {hex(res)}"
)
def
handler_14_():
global
pc
pc
+
=
hex_to_negative(arg)
print
(f
"[h14_]\t pc += {hex_to_negative(arg)}"
)
def
handler_15_():
write_mem_word(
0x10004
,
257
)
print
(
"[h15_]\t write_mem_word(0x10004, 257)"
)
def
handler_17_lsr():
sp_data
=
read_sp_data()
set_sp_data(sp_data >> arg)
print
(f
"[h17_lsr]\t *sp = *sp >> arg = {hex(sp_data)} >> {arg} = {hex(sp_data >> arg)}"
)
def
handler_18_mod():
n1
=
pop_data()
n2
=
read_sp_data()
res
=
n2
%
n1
set_sp_data(res)
print
(f
"[h18_mod]\t pop, *sp = {hex(n2)} % {hex(n1)} = {hex(res)}"
)
def
handler_20_dword2byte():
sp
=
read_mem_word(
0x10002
)
sp_data
=
read_mem_byte(sp)
set_sp_data(sp_data)
print
(f
"[h20_dword2byte]\t *(dword*)sp = *(byte*)sp = {hex(sp_data)}"
)
def
handler_21_mul():
n1
=
pop_data()
n2
=
read_sp_data()
res
=
n1
*
n2
set_sp_data(res)
print
(f
"[h21_mul]\t pop, *sp = {hex(n2)} * {hex(n1)} = {hex(res)}"
)
def
handler_22_pushpc():
global
pc
sp
=
read_mem_word(
0x10002
)
pc_
=
pc
pc
+
=
hex_to_negative(arg)
v34
=
sp
+
4
write_mem_word(
0x10002
, v34)
write_mem_dword(v34, pc_)
print
(f
"[h22_pushpc]\t push(pc) -> push({hex(pc_)}), pc += {hex_to_negative(arg)}"
)
def
handler_23_eq():
global
pc
sp
=
read_mem_word(
0x10002
)
v16
=
sp
-
4
v15
=
sp
-
8
n1
=
read_mem_dword(sp)
n2
=
read_mem_dword(sp
-
4
)
write_mem_word(
0x10002
, v15)
if
(v13
=
=
25
)
=
=
(n1
=
=
n2):
print
(f
"[h23_eq]\t sp = sp - 8"
)
return
if
arg &
0xFFFFFF00
!
=
0
:
raise
Exception(
"TODO"
)
pc
+
=
hex_to_negative(arg)
print
(f
"[h23_eq]\t sp = sp - 8, pc += {hex_to_negative(arg)} ({hex(arg)})"
)
def
handler_26_getinput():
n1
=
pop_data()
n2
=
read_sp_data()
res
=
read_mem_byte(n1
+
n2)
set_sp_data(res)
print
(f
"[h26_getinput]\t pop, *sp = vm_ctx[{hex(n2)} + {hex(n1)}] = {hex(res)}"
)
def
handler_27_pusharg():
global
arg
sp
=
read_mem_word(
0x10002
)
orig_arg
=
arg
arg
=
read_mem_dword(sp
-
4
*
arg)
push_data(arg)
print
(f
"[h27_pusharg]\t push({hex(arg)}) arg == [sp - 4 * {orig_arg}]"
)
def
handler_29_pusharg2():
push_data(arg)
print
(f
"[h29_pusharg2]\t push({hex(arg)})"
)
def
handler_30_sub1():
sp_data
=
read_sp_data()
set_sp_data(sp_data
-
1
)
print
(f
"[h30_sub1]\t *sp = *sp - 1 = {hex(sp_data)} - 1 = {hex(sp_data - 1)}"
)
pc
=
read_mem_word(
0x10000
)
while
True
:
pc_1
=
pc
+
1
cur_opcode
=
read_mem_byte(pc)
arg
=
cur_opcode &
7
if
arg !
=
7
:
pc
+
=
1
v13
=
cur_opcode >>
3
_opcode
=
v13
-
1
else
:
pc
+
=
2
arg
=
read_mem_byte(pc_1)
v13
=
cur_opcode >>
3
_opcode
=
v13
-
1
if
v13
-
1
>
0x1E
:
raise
Exception(
"TODO"
)
break
if
_opcode
=
=
0
:
handler_0_xor()
elif
_opcode
=
=
1
:
handler_1_opposite()
elif
_opcode
=
=
2
:
handler_2_subsp()
elif
_opcode
=
=
3
or
_opcode
=
=
25
:
continue
elif
_opcode
=
=
4
:
handler_4_orr()
elif
_opcode
=
=
5
:
handler_5_()
elif
_opcode
=
=
6
:
handler_6_noeq()
elif
_opcode
=
=
7
:
handler_7_swap()
elif
_opcode
=
=
8
:
handler_8_and()
elif
_opcode
=
=
9
:
handler_9_lsl()
elif
_opcode
=
=
10
:
handler_10_not()
elif
_opcode
=
=
12
:
handler_12_add()
elif
_opcode
=
=
14
:
handler_14_()
elif
_opcode
=
=
15
:
handler_15_()
break
elif
_opcode
=
=
17
:
handler_17_lsr()
elif
_opcode
=
=
18
:
handler_18_mod()
elif
_opcode
=
=
20
:
handler_20_dword2byte()
elif
_opcode
=
=
21
:
handler_21_mul()
elif
_opcode
=
=
22
:
handler_22_pushpc()
elif
_opcode
=
=
23
or
_opcode
=
=
24
:
handler_23_eq()
elif
_opcode
=
=
26
:
handler_26_getinput()
elif
_opcode
=
=
27
:
handler_27_pusharg()
elif
_opcode
=
=
29
:
handler_29_pusharg2()
elif
_opcode
=
=
30
:
handler_30_sub1()
else
:
print
(
"else _opcode: "
, _opcode)
raise
Exception(
"TODO"
)
break
write_mem_word(
0x10000
, pc)
res
=
read_sp_data()
return
res
vm_ctx
=
[
0
]
*
0x10006
load_opcodes()
write_mem_dword(
0x10000
,
0x8000C000
)
write_mem_word(
0x10004
,
0
)
write_mem_arr(
0x204
*
0x10
, [
0x00
,
0x03
,
0x0F
,
0x20
,
0x0D
,
0x02
,
0x23
,
0x06
,
0x1B
,
0x14
,
0x0E
,
0x01
,
0x16
,
0x19
,
0x08
,
0x12
])
write_mem_arr(
0x205
*
0x10
, [
0x1F
,
0x17
,
0x24
,
0x0B
,
0x1E
,
0x07
,
0x1A
,
0x05
,
0x18
,
0x1D
,
0x22
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
])
write_mem_arr(
0x203
*
0x10
, [
0x09
,
0x0A
,
0x10
,
0x15
,
0x21
,
0x13
,
0x0C
,
0x04
,
0x11
,
0x1C
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
,
0x00
])
write_mem_str(
0x1000
,
"flag{44444-44444-44444-44444}"
)
push_data(
1898208
)
push_data(
0x1000
)
push_data(
0x2000
)
res
=
start_vm()
print
(
"[res]: "
,
hex
(res))