# PatriotCTF Bài này tương tự với bài Stack VM của giải BKCTF. Nó mô phỏng lại chương trình của 1 con `VM`. ![](https://hackmd.io/_uploads/B15hgPky6.png) Khi ta khởi chạy chương trình thì con `VM` này sẽ đọc dữ liệu của 1 file khác có tên là `password_checker.smol` như sau: ![](https://hackmd.io/_uploads/HkiQbwk1T.png) hàm `execute_instruction`: ![](https://hackmd.io/_uploads/HyyCXdyk6.png) Chương trình sẽ kiểm tra từng switch case, sau đó con `VM` sẽ thực hiện tiến trình của case đó: Sau khi đọc và phân tích, mình rút ra kết luận về các hàm như sau ``` CASE 0: VM_MOVE a1 = a2 CASE 1: VM_ADD a1 += a2 + a3 CASE 2: VM_ADD a1 += a2 + a3 CASE 3: VM_PRINT printf("%d", a1) CASE 4: VM__MOV a1 = a3 CASE 5: VM_PUSH sp += 8; *sp = value CASE 6: VM_POP sp -= 8; value = *sp CASE 7: VM_CMP value = a1 - a2 CASE 8: VM_JZ if(!ip) ip + =a3 CASE 9: VM_WRITE write(1, sp, a3) CASE 10: VM_MULADD a1 *= a2; a1 + =a3 CASE 11: VM_ADD a1 = a3 CASE 12: VM_EXIT exit(0) CASE 13: VM_SCANF scanf("%u", v5) ``` Dưới đây sẽ là cái tracer để xem làm file `smol` làm gì ```python= f = open("password_checker.smol", "rb").read() rbp =[] for i in range(25): rbp.append(0) rbp_24 = [] for i in range(1000): rbp_24.append(0) offset_24 = 500 rbp_16 = 0 ptr = 4 while(ptr < len(f)): offset_1 = f[ptr + 1] * 4 offset_2 = f[ptr + 2] * 4 if f[ptr] == 0: print(f"MOV *[rbp + {offset_1}] = *[rbp + {offset_2}]") rbp[offset_1] = rbp[offset_2] print(f"[rbp + {offset_1}] = {rbp[offset_1]}") if f[ptr] == 1 or f[ptr] == 2: print(f"ADD *[rbp + {offset_1}] += *[rbp + {offset_2}] + {ptr[ptr + 3]}") rbp[offset_1] += rbp[offset_2] + f[ptr + 3] print(f"[rbp + {offset_1}] = {rbp[offset_1]}") if f[ptr] == 3: print(f"PRINT *[rbp + {offset_1}]") if f[ptr] == 4: print(f"MOV *[rbp + {offset_1}] = {f[ptr + 3]}") rbp[offset_1] = f[ptr + 3] print(f"*[rbp + {offset_1}] = {rbp[offset_1]}") if f[ptr] == 5: print(f"ADD *[rbp + 24] += 8, THEN MOV **[rbp + 24] = [rbp + {offset_2}] = {rbp[offset_2]}") offset_24 += 8 rbp_24[offset_24] = rbp[offset_2] if f[ptr] == 6: print(f"MOV *rbp[{offset_1}] = **[rbp + 24] THEN SUB *[rbp + 24] -= 8") rbp[offset_1] = rbp_24[offset_24] offset_24 -= 8 print(f"*[rbp + {offset_1}] = {rbp[offset_1]}") if f[ptr] == 7: print(f"MOV *rbp_16 = *rbp[{offset_1}] - rbp[{offset_2}] = {rbp[offset_1]} - {rbp[offset_2]}") rbp_16 = rbp[offset_1] - rbp[offset_2] print(f"rbp_16 = {rbp_16}") if f[ptr] == 8: print(f"LSEEK({f[ptr + 2] * 256 + f[ptr + 3]}) bytes") if rbp_16 == 0: ptr += f[ptr + 2] * 256 + f[ptr + 3] continue if f[ptr] == 9: print(f"WRITE ({f[ptr + 3]}) bytes of **[rpb + 24]") hex_str = hex(rbp_24[offset_24])[2:] print(hex_str) if f[ptr] == 10: print(f"MUL *[rbp + {offset_1}] *= *[rbp + {offset_2}] THEN ADD *[rbp + {offset_1}] += {f[ptr + 3]}") rbp[offset_1] *= rbp[offset_2] rbp[offset_1] += f[ptr + 3] print(f"[rbp{offset_1}] = {rbp[offset_1]}") if f[ptr] == 11: print(f"ADD *[rbp + {offset_1}] += {f[ptr + 3]}") rbp[offset_1] += f[ptr + 3] print(f"*[rbp + {offset_1}] = {rbp[offset_1]}") if f[ptr] == 12: print("EXIT") if f[ptr] == 13: print("INPUT") ptr += 4 ```