---
# System prepended metadata

title: VM disassembler

---

# MagicVM - Dreamhack  

```python=
import pwn
pwn.context.log_level = "CRITICAL"  
opcodes=[]#65536 bytes opcodes
def sub_5555555CE8DA(v1) :
    #print(v1)
    PROMPT = b"(gdb)"
    io: pwn.tube
    with pwn.process(["gdb", "-q", "--nx", "./main"]) as io:
        io.sendlineafter(PROMPT, b"b *0x5555555CECAD")
        io.sendlineafter(PROMPT, b"b *0x5555555CECB2")
        io.sendlineafter(PROMPT, b"run")
        io.sendline(b'a'*64)
        io.sendlineafter(PROMPT, f"set $si = {v1}".encode())
        io.sendlineafter(PROMPT, b"continue")
        io.sendlineafter(PROMPT, b"info registers al") #x/_ ___
        n=(io.recvline())
        #print(int(n[-8:-1]])%256)
        io.close()

    return int(n[-8:-1])%256
#'''
dic=[]
for i in range(256):
    d=sub_5555555CE8DA(i)
    dic.append(sub_5555555CE8DA(i))
    print(i,":",hex(d), end=", ")
print(dic)
#'''
#dic=[74, 151, 182, 234, 232, 27, 172, 253, 99, 177, 28, 113, 52, 81, 58, 218, 149, 8, 181, 245, 118, 42, 122, 13, 57, 66, 86, 112, 110, 188, 229, 171, 32, 162, 244, 47, 242, 55, 23, 16, 231, 102, 252, 174, 0, 173, 19, 166, 129, 40, 205, 227, 249, 135, 184, 233, 85, 48, 105, 142, 100, 4, 127, 104, 96, 200, 208, 152, 43, 106, 250, 11, 145, 203, 117, 239, 202, 150, 192, 134, 148, 157, 201, 98, 21, 83, 108, 54, 41, 179, 72, 39, 51, 215, 79, 114, 220, 75, 24, 126, 111, 15, 22, 95, 189, 195, 167, 9, 46, 251, 124, 223, 153, 180, 155, 132, 30, 14, 128, 207, 68, 18, 63, 131, 190, 65, 80, 5, 224, 60, 64, 26, 168, 70, 38, 125, 156, 59, 84, 56, 206, 212, 45, 199, 2, 71, 175, 10, 6, 209, 61, 92, 20, 160, 194, 141, 226, 3, 82, 88, 103, 154, 1, 90, 236, 187, 191, 44, 93, 178, 241, 138, 36, 247, 37, 101, 246, 158, 120, 243, 62, 159, 216, 7, 143, 91, 77, 130, 76, 107, 225, 144, 94, 116, 170, 197, 140, 136, 121, 123, 214, 255, 204, 213, 87, 193, 235, 12, 89, 146, 210, 183, 198, 211, 78, 69, 109, 222, 163, 115, 240, 97, 164, 49, 219, 137, 73, 186, 169, 67, 221, 34, 17, 185, 248, 29, 230, 238, 165, 139, 147, 133, 25, 196, 33, 217, 53, 176, 119, 237, 50, 31, 228, 161, 254, 35]
v45=0
v47=32
print(f"bat dau")
i=0
file = open("output.txt", "w")

while True:
    try:
        i += 1
        v1 = v45
        v46 = v1 + 1
        print(hex(v1) + ": ", end='')
        file.write(hex(v1) + ": ")
        v41 = dic[opcodes[v1]]
        op = v41 >> 4
        

        if op in range(0, 9) or op == 11:  
            v18 = dic[opcodes[v46]]
            v2 = v46 + 1
            v45 = v2 + 1
            v30 = dic[opcodes[v2]]
            ins = ["mov", "add", "sub", "mul", "shl", "shr", "xor", "and", "or", 0, 0, "cmp"][op]
            if v41>>2==0:
                L=f"arr1[{hex(v18)}]"
            if v41>>2!=0:
                L=f"arr2[{hex(v18)}]"
            if v41&3!=0:
                if v41&3==1:
                    R=f"arr1[{hex(v30)}]"
                else:
                    R=f"arr2[{hex(v30)}]"
            if v41&3==0:
                R=hex(v30)
            print(f"{ins} {L}, {R}")
            file.write(f"{ins} {L}, {R}\n")

        elif op in [9]:  
            v18 = dic[opcodes[v46]]
            v45 = v46 + 1
            ins = ["mov"][op - 9]
            if v41&0xf!=0:
                if v41&0xf==1:
                    L=f"arr1[{hex(v18)}]"
                else:
                    L=f"arr2[{hex(v18)}]"
            if v41&0xf==0:
                L=f"{hex(v18)}"
            v47=v47+1
            print(f"{ins} input[32+i++], {L}")
            file.write(f"{ins} input[32+i++], {L}\n")
        elif op in [10]:  
            v18 = dic[opcodes[v46]]
            v45 = v46 + 1
            ins = ["mov"][op - 10]
            if v41&0xf!=0:
                L=f"arr1[{hex(v18)}]"
            if v41&0xf==0:
                L=f"arr2[{hex(v18)}]"
            print(f"{ins} {L}, input[32+i--]")
            v47=v47-1
            file.write(f"{ins} {L}, input[32+i--]\n")
        elif op in [12, 13, 14]: 
            low = dic[opcodes[v46]]
            high = dic[opcodes[v46 + 1]]
            v45 = v46 + 2
            addr = low + (high << 8)
            ins = ["jmp", "jz", "call"][op - 12]
            print(f"{ins} {hex(addr)}")
            file.write(f"{ins} {hex(addr)}\n")
        elif op == 15:
            v45 = v46
            print("ret")
            file.write("ret\n")

        else:
            break
    except:
        break

print("xong")
file.write("xong\n")
file.close()

```
# bitvm  - Dreamhack  
vm cơ bản  
```python=
with open("command","rb") as f:
    opcodes=f.read()

ip=0
sp=0
i=0
while True:
    #print(hex(ip)+": ",end='')
    op=opcodes[ip]
    ip+=1
    if ip==len(opcodes):
        print("xong")
        break
    if op==32:
        break
    if op==0x21:
        print(f"print {chr(opcodes[ip])}")
        ip+=1
        continue
    if op==0x22:
        print(f"mov arr1[{hex(sp)}], input[{hex(i)}]")
        i+=1
        sp+=1
        continue
    if op==0x23:
        print(f"mov arr2[{hex(opcodes[ip])}], {hex(opcodes[ip+1])}")
        ip+=2
        continue
    if op==0x24:
        print(f"mov arr2[{hex(opcodes[ip])}], arr2[{hex(opcodes[ip+1])}]")
        ip+=2
        continue
    if op in range(0x25,0x28):
        ins=["and","or","xor"][op-0x28]
        print(f"mov reg1, arr2[{hex(opcodes[ip+1])}]")
        print(f"mov reg2, arr2[{hex(opcodes[ip+2])}]")
        print(f"{ins} reg1, reg2")
        print(f"mov arr2[{hex(opcodes[ip])}], reg1")
        ip+=3
        continue
    if op==0x28:
        print(f"mov arr2[0x0], arr1[{hex(sp)}]")
        sp-=1
        continue
    if op==0x29:
        print(f"mov reg1, arr2[{hex(opcodes[ip])}]")
        print(f"mov arr1[{hex(sp)}], reg1")
        sp+=1
        continue
        ip+=1
    else:
        print("unk")
```
# Havana32 - ShaktiCTF25  
bài này kết hợp giữa dll injection và vm, xử lý opcode vm qua dll.  
```python=
opcodes=[0x0000001E, 0x0000004F, 0x0000001E, 0x0000000F, 0x0000001E, 0x00000002, 0x00000003, 0x0000005C, 0x00000015, 0x0004284A, 0x0000001E, 0x0000003B, 0x0000001D, 0x0000002F, 0x0000001D, 0x00000028, 0x00000011, 0x0000005D, 0x0000001E, 0x00000006, 0x00000011, 0x00000012, 0x00000015, 0x0000923A, 0x00000011, 0x0000003E, 0x00000011, 0x00000007, 0x00000003, 0x0000002E, 0x00000011, 0x0000001B, 0x00000015, 0x00000093, 0x0000001D, 0x00000052, 0x0000001D, 0x00000046, 0x00000003, 0x00000063, 0x0000001E, 0x0000000A, 0x00000003, 0x0000004C, 0x00000003, 0x00000060, 0x00000015, 0x0000006C, 0x00000011, 0x00000048, 0x00000003, 0x0000004E, 0x00000011, 0x0000000C, 0x00000003, 0x0000001A, 0x00000015, 0x00000060, 0x0000001E, 0x00000059, 0x0000001D, 0x00000060, 0x00000003, 0x0000005B, 0x00000011, 0x0000002B, 0x0000001E, 0x00000028, 0x00000003, 0x0000003B, 0x00000015, 0x0005BB6D, 0x0000001D, 0x0000000B, 0x0000001D, 0x00000032, 0x00000003, 0x00000003, 0x00000011, 0x00000038, 0x00000015, 0x0000008F, 0x00000003, 0x00000052, 0x0000001D, 0x00000030, 0x0000001D, 0x0000003A, 0x00000011, 0x00000036, 0x00000003, 0x00000029, 0x0000001D, 0x00000038, 0x00000015, 0x0000000D, 0x00000011, 0x00000027, 0x00000003, 0x00000033, 0x00000003, 0x0000005F, 0x0000001D, 0x00000046, 0x00000015, 0xFFFFFFBD, 0x00000011, 0x00000055, 0x00000003, 0x00000050, 0x00000011, 0x00000010, 0x0000001E, 0x00000053, 0x00000015, 0x00002EB0, 0x0000001E, 0x0000003D, 0x0000001E, 0x00000036, 0x0000001D, 0x00000018, 0x0000001E, 0x0000005A, 0x0000001E, 0x0000001B, 0x00000015, 0x22599F30, 0x0000001E, 0x0000005B, 0x00000003, 0x0000001C, 0x00000003, 0x00000016, 0x0000001E, 0x00000033, 0x00000003, 0x00000031, 0x00000015, 0x0003A48D, 0x00000011, 0x00000040, 0x0000001D, 0x0000001E, 0x00000003, 0x0000003C, 0x00000003, 0x00000049, 0x00000015, 0x0000002D, 0x00000003, 0x0000005E, 0x0000001D, 0x0000002F, 0x0000001E, 0x0000002A, 0x00000011, 0x00000003, 0x0000001D, 0x00000006, 0x00000011, 0x00000061, 0x00000015, 0x000006D0, 0x0000001E, 0x0000002B, 0x0000001D, 0x00000001, 0x0000001E, 0x0000000B, 0x00000011, 0x00000041, 0x00000003, 0x00000052, 0x0000001E, 0x00000024, 0x00000015, 0x0018AB0C, 0x00000003, 0x0000001D, 0x0000001E, 0x0000005C, 0x00000011, 0x00000049, 0x0000001E, 0x00000014, 0x0000001E, 0x0000005C, 0x00000011, 0x00000011, 0x00000015, 0x00332081, 0x0000001E, 0x00000020, 0x0000001E, 0x00000026, 0x0000001E, 0x00000006, 0x00000003, 0x0000003D, 0x0000001E, 0x0000001B, 0x00000015, 0x01329291, 0x0000001D, 0x0000003A, 0x0000001D, 0x0000004C, 0x0000001D, 0x0000002E, 0x0000001D, 0x0000005F, 0x00000015, 0x00000058, 0x0000001D, 0x00000062, 0x0000001D, 0x0000002B, 0x0000001D, 0x0000004A, 0x00000011, 0x0000003A, 0x00000015, 0x000000A8, 0x0000001D, 0x0000000F, 0x0000001E, 0x0000005D, 0x00000011, 0x0000000A, 0x00000011, 0x00000060, 0x00000015, 0x00001FA8, 0x00000003, 0x0000001A, 0x00000003, 0x00000021, 0x0000001E, 0x00000021, 0x00000011, 0x00000058, 0x00000011, 0x00000049, 0x0000001D, 0x00000062, 0x00000015, 0x00000527, 0x00000011, 0x0000000A, 0x0000001D, 0x0000000E, 0x00000003, 0x0000004D, 0x00000003, 0x00000053, 0x00000015, 0xFFFFFFBC, 0x0000001D, 0x0000002D, 0x0000001E, 0x00000062, 0x0000001D, 0x00000063, 0x00000003, 0x00000063, 0x00000015, 0x00000ABC, 0x00000011, 0x00000014, 0x00000003, 0x00000003, 0x0000001D, 0x00000011, 0x0000001E, 0x00000031, 0x0000001E, 0x0000003B, 0x00000015, 0x0003B49C, 0x00000011, 0x00000036, 0x00000003, 0x00000054, 0x0000001D, 0x0000003A, 0x0000001D, 0x00000001, 0x00000011, 0x0000000E, 0x00000015, 0x0000007D, 0x0000001D, 0x00000043, 0x00000011, 0x00000027, 0x00000003, 0x00000058, 0x0000001E, 0x0000000A, 0x0000001D, 0x0000002C, 0x00000015, 0x00000010, 0x00000003, 0x00000047, 0x00000003, 0x00000031, 0x00000011, 0x00000025, 0x00000003, 0x0000004D, 0x00000015, 0xFFFFFFBF, 0x0000001E, 0x00000011, 0x00000011, 0x00000024, 0x0000001E, 0x0000002A, 0x00000003, 0x00000028, 0x0000001D, 0x00000014, 0x00000015, 0x00008E7E, 0x0000001D, 0x00000019, 0x00000011, 0x00000020, 0x00000003, 0x0000005A, 0x0000001E, 0x0000004D, 0x0000001E, 0x00000035, 0x00000015, 0x0002FD30, 0x00000003, 0x00000023, 0x0000001E, 0x00000046, 0x00000011, 0x0000002D, 0x00000011, 0x00000029, 0x00000003, 0x00000061, 0x0000001E, 0x00000041, 0x00000015, 0x0004279D, 0x00000003, 0x0000005F, 0x0000001E, 0x00000003, 0x00000011, 0x0000003C, 0x0000001E, 0x0000001E, 0x00000015, 0xFFFFF6DC, 0x00000003, 0x00000026, 0x0000001D, 0x0000004E, 0x0000001D, 0x0000003D, 0x00000011, 0x0000000E, 0x00000015, 0x00000049, 0x00000011, 0x00000002, 0x0000001E, 0x00000051, 0x00000003, 0x00000049, 0x00000011, 0x0000000B, 0x00000011, 0x0000004B, 0x00000003, 0x00000064, 0x00000015, 0x00001E5A, 0x00000011, 0x00000052, 0x00000003, 0x0000001C, 0x00000011, 0x00000021, 0x00000003, 0x0000001F, 0x0000001E, 0x00000045, 0x00000015, 0x00002280, 0x00000003, 0x0000003B, 0x0000001E, 0x00000028, 0x0000001D, 0x00000062, 0x00000003, 0x00000063, 0x00000015, 0xFFFFFE27, 0x00000011, 0x0000001A, 0x0000001D, 0x0000001F, 0x0000001D, 0x00000030, 0x0000001D, 0x0000003C, 0x00000011, 0x0000000C, 0x00000015, 0x0000008F, 0x0000001D, 0x0000003A, 0x0000001D, 0x00000037, 0x0000001E, 0x00000002, 0x00000011, 0x00000002, 0x00000015, 0x00000074, 0x0000001E, 0x00000059, 0x00000011, 0x0000002A, 0x0000001E, 0x00000049, 0x0000001D, 0x0000001D, 0x00000011, 0x00000056, 0x00000015, 0x000AF40B, 0x0000001D, 0x00000001, 0x00000003, 0x0000005D, 0x00000011, 0x00000052, 0x00000011, 0x00000013, 0x00000015, 0x0000003D, 0x0000001D, 0x00000006, 0x00000003, 0x00000032, 0x00000011, 0x00000032, 0x00000011, 0x0000005F, 0x00000011, 0x00000012, 0x0000001E, 0x00000010, 0x00000015, 0x00000CA0, 0x0000001E, 0x00000028, 0x0000001E, 0x0000005E, 0x00000003, 0x00000063, 0x00000003, 0x00000041, 0x00000015, 0x0002C05C, 0x00000011, 0x00000007, 0x0000001E, 0x00000045, 0x0000001E, 0x0000003C, 0x0000001E, 0x00000032, 0x0000001D, 0x00000057, 0x00000011, 0x00000013, 0x00000015, 0x0174B65A, 0x00000011, 0x00000039, 0x0000001E, 0x0000004A, 0x0000001E, 0x0000005A, 0x00000011, 0x00000024, 0x0000001D, 0x0000000A, 0x0000001E, 0x00000059, 0x00000015, 0x048EC7D2, 0x0000001E, 0x00000032, 0x0000001D, 0x0000001C, 0x0000001E, 0x00000009, 0x00000011, 0x00000061, 0x00000003, 0x00000003, 0x00000015, 0x0000A780, 0x00000003, 0x0000004C, 0x00000003, 0x00000010, 0x0000001E, 0x00000011, 0x00000011, 0x0000004A, 0x00000003, 0x0000002F, 0x0000001E, 0x0000002A, 0x00000015, 0x000036A2, 0x00000003, 0x00000037, 0x0000001E, 0x00000049, 0x0000001E, 0x00000001, 0x00000003, 0x00000004, 0x0000001E, 0x00000007, 0x00000015, 0xFFFFF9E7, 0x00000011, 0x00000029, 0x00000011, 0x00000057, 0x0000001E, 0x00000046, 0x00000003, 0x0000003B, 0x00000003, 0x0000004F, 0x0000001E, 0x00000028, 0x00000015, 0x000A1590, 0x0000001D, 0x00000023, 0x0000001D, 0x0000002D, 0x00000011, 0x00000048, 0x0000001D, 0x00000038, 0x00000011, 0x0000000D, 0x00000015, 0x000000C7, 0x0000001D, 0x0000003F, 0x00000003, 0x00000058, 0x0000001E, 0x00000002, 0x0000001E, 0x00000047, 0x00000015, 0xFFFFF3CC]
ip=0
low=0
i=0
print(f"mov reg, input[{hex(i)}]")
i+=1
while ip<=578:
    op=opcodes[ip]

    hi=opcodes[ip+1]
    
    if op<3:
        #print("inc ip")
        ip+=2
        continue
    if op==3:
        print(f"sub reg, {hi}")
        ip+=2
        continue
    if op==10:
        print(f"inc low")
        low+=1
        ip+=2
        continue
    if op==11:
        print(f"dec low")
        low-=1
        ip+=2
        continue
    if op==14:
        print(f"swap low, hi")
        ip+=2
        continue
    if op ==17:
        print(f"add reg, {hi}")
        #print(f"unk ",op,opcodes[ip+1])
        ip+=2
        continue
    if op ==25:
        #print(chr(opcodes[ip+1]))
        print(f"cmp low, 0")
        print(f"mov reg, input[{hex(i)}]")
        i+=1
        ip+=2
        continue
    if op ==21:
        print(f"cmp reg, {hi}")
        print(f"mov reg, input[{hex(i)}]")
        i+=1
        ip+=2
        continue
    if op ==29:
        print(f"xor reg, {hi}")
        ip+=2
        continue
    if op ==30:
        print(f"mul reg, {hi}")
        ip+=2
        continue
    if op==33:
        print(f"inc ip")
        ip+=1
        ip+=3
        continue
    if op>39:
        print(f"unk ",op,opcodes[ip+1])
        ip+=2
        continue
```
Flag: `shaktictf{H4lf_0f_mY_H34rt_1s_1n_H4v4n4_0oH_n4n4}`
# Lazy VM - idekctf 2025  
bài này thay vì disassemble vm thì lại làm ngược lại là assemble vm  
```python=
from pwn import*
from Crypto.Util.number import*
context.log_level = "CRITICAL"
import re
payload=\
'''
push 0
push 2
push 118
pop r0
pop r1
xor r1
pushr r0
push 12
pop r1
xor r1
pushr r0
push 12
pop r1
xor r1
pushr r0
push 90
pop r1
xor r1
pushr r0
push 73
pop r1
xor r1
pushr r0
push 6
pop r1
xor r1
pushr r0
push 13
pop r1
xor r1
pushr r0
push 10
pop r1
xor r1
pushr r0
pop r1
store mem0, r1
pop r1
store mem1, r1
pop r1
store mem2, r1
pop r1
store mem3, r1
pop r1
store mem4, r1
pop r1
store mem5, r1
pop r1
store mem6, r1
pop r1
store mem7, r1
push 0
pop r1
push 2
pop r0
syscall
push 0
pop r1
push 45
pop r3
push 0
pop r0
syscall
push 1
pop r1
push 1
pop r0
syscall
'''

bytecode=''
l=payload.split('\n')
#print(l)
for i in l:
    try:
        n=i.split(' ')
        m=len(n)
        ins=n[0]
        #print(ins)
        a=["push","pop","pushr","or","xor"]
        b=["load","store"]
        c=["syscall"]
        if m==1:
            #print(c.index(ins)+8)
            bytecode+=hex(c.index(ins)+8)[2:].zfill(2)
            continue
        elif m==2:
            #print(a.index(ins)+1)
            op1=n[1]
            bytecode+=hex(a.index(ins)+1)[2:].zfill(2)
            #print(int(re.search(r'\d+', op1).group()))
            bytecode+=hex(int(re.search(r'\d+', op1).group()))[2:].zfill(2)
            continue
        elif m==3:
            op1=n[1]
            op2=n[2]
            bytecode+=hex(b.index(ins)+6)[2:].zfill(2)
            bytecode+=hex(int(re.search(r'\d+', op1).group()))[2:].zfill(2)
            bytecode+=hex(int(re.search(r'\d+', op2).group()))[2:].zfill(2)
            print(bytecode[-6:])
            continue
        else:
            continue

    except:
        continue
print(bytecode)
for i in range(0,1):
    print(chr(i).encode())
    p=remote("lazy-vm.chal.idek.team", 1337)
    print(p.recvuntil(b'code:\n'))
    payload= long_to_bytes(int(bytecode,16))#0600000201020006000008)
    p.sendline(payload+b'i')
    print(p.recv(100000000000000000000000).decode())
    print(p.recv(100000000000000000000000).decode())
    p.close()
##idek{Th15_I$_thE_L@Z13$t_vM_i_h4vE_EvEr_5EEN}
```
# GameshieldVM  
```python=
import struct
ops=bytearray(open("game.bin",'rb').read()[8:])
#print(a)
ip=0
addr=0
for i in range(len(ops)):
    ops[i]=ops[i]^0xe1
while 1:
    op=ops[ip]
    addr=ip
    print(hex(addr), end=': ')
    ip+=1
    if op==1:
        reg=ops[ip]&7
        ip+=1
        val=struct.unpack('<I', ops[ip : ip + 4])[0]
        ip+=4
        print(f"mov reg{reg}, {hex(val)}")
        continue
    if op==2:
        reg=ops[ip]&7
        ip+=1
        val=struct.unpack('<H', ops[ip : ip + 2])[0]
        ip+=2
        print(f"mov reg{reg}, arr[{val}]")
        continue
    if op==3:
        val=struct.unpack('<H', ops[ip : ip + 2])[0]
        ip+=2
        reg=ops[ip]&7
        ip+=1
        print(f"mov arr[{val}], reg{reg}")
        continue
    if op in [4,5,6,7]:
        ins=["add","sub","mul","cmp"][op-4]
        reg=ops[ip]&7
        ip+=1
        val=ops[ip]&7
        ip+=1
        print(f"{ins} reg{reg}, reg{val}")
        continue
    if op in [8,9,10,11]:
        ins=["jz","jnz","jmp","call"][op-8]
        reg=ops[ip]
        ip+=1
        print(f"{ins} {hex(reg+ip)}")
        continue
    if op==0xc:
        print("ret")
        continue
    if op in [0xd,0xe]:
        ins=["push","pop"][op-0xd]
        reg=ops[ip]&7
        ip+=1
        print(f"{ins} reg[{reg}]")
        continue
    if op == 0x0f:
        reg=ops[ip]
        ip+=1
        print(f"syscall {hex(reg)}")
        continue
    else:
        print(f"unk {hex(ops[ip]^0xe1)}")
        
```