虚拟机题目入门
虚拟机题目入门
笔记
IDADefines.cpp
1 |
|
做题
[NCTF 2018]wcyvm
第一个VM题,看着题解搞懂了,但还不是太懂,主要是内存调用非常混乱…
dispatcher:
1 | _BOOL8 dispatcher() |
各指令代码实现:
1 | void __fastcall opr_mov1(_DWORD *a1, int a2, _QWORD *a3) |
Compiler:
1 | v5=[8, 1, 0, 8, 3, 70, 14, 21, 10, 1, 9, 2, 11, 10, 1, 10, 2, 9, 1, 17, 1, 13, 1, 3, 15, 8, 8, 1, 0, 8, 3, 71, 14, 70, 10, 1, 26, 2, 6, 29, 1, 4, 20, 2, 1, 25, 1, 2, 27, 1, 1, 29, 1, 110, 19, 1, 99, 21, 1, 116, 19, 1, 102, 28, 2, 1, 9, 1, 17, 1, 13, 1, 3, 15, 34, 100] |
Assembly:
1 | 0 mov r0 0 |
大致加密逻辑:$(((r_0\times110)+99)\oplus116)+102$
由网上wp可知exp:
1 | enc=[0xD3, 0x36, 0x00, 0x00, 0xFF, 0x2A, 0x00, 0x00, 0xCB, 0x2A, |
[HGAME 2022 week4]ezvm
虚拟机逆向,每个指令(可能是):
1 | int __fastcall main(int argc, const char **argv, const char **envp) |
exp(不是我写的):
1 | s=[94,70,97,67,14,83,73,31,81,94,54,55,41,65,99,59,100,59,21,24,91,62,34,80,70,94,53,78,67,35,96,59] |
[watevrCTF 2019]Repyc
Python虚拟机,解析不是自己写的:
1 | # uncompyle6 version 3.7.4 |
解密脚本:
1 | x="á×äÓâæíäàßåÉÛãåäÉÖÓÉäàÓÉÖÓåäÉÓÚÕæïèäßÙÚÉÛÓäàÙÔÉÓâæÉàÓÚÕÓÒÙæäàÉäàßåÉßåÉäàÓÉÚÓáÉ·Ôâ×ÚÕÓÔɳÚÕæïèäßÙÚÉÅä×ÚÔ×æÔÉ×Úïá×ïåÉßÉÔÙÚäÉæÓ×ÜÜïÉà×âÓÉ×ÉÑÙÙÔÉâßÔÉÖãäÉßÉæÓ×ÜÜïÉÓÚÞÙïÉäàßåÉåÙÚÑÉßÉàÙèÓÉïÙãÉáßÜÜÉÓÚÞÙïÉßäÉ×åáÓÜÜ\x97ÉïÙãäãÖÓ\x9aÕÙÛ\x99á×äÕà©â«³£ï²ÕÔÈ·±â¨ë" |
[羊城杯 2023]vm_wo
第一次做MacOS的题,比想象中的要简单,简单虚拟机题目。
IDA8.3不支持反汇编为C,这里用7.7的。
myoperate
函数中有操作指令,导出,interpretBytecode
中有dispatcher。
翻译脚本不是自己写的,从网上copy的:
1 | opcode = [26, 0, 3, 25, 1, 1, 13, 2, 7, 24, 1, 2, 1, 0, 3, 26, 0, 3, 25, |
结果如下:
1 | 0 mov reg0 3 |
看到位移为3 4 5 6的寄存器,算vm_body
偏移,看到初始化为0xBEEDBEEF,即为连着4个字节。
1 | enc = [0xDF, 0xD5, 0xF1, 0xD1, 0xFF, 0xDB, 0xA1, 0xA5, 0x89, 0xBD, 0xE9, 0x95, 0xB3, 0x9D, 0xE9, 0xB3, 0x85, 0x99, 0x87, |
脚本依旧是偷的。
[HGAME 2023 week4]vm
史上最简单虚拟机…
根据提示恢复结构体,得一系列:
1 | void __fastcall sub_1400018A0(vm *a1) |
从网上wp嗦个脚本跑:
1 | opcode = [0x00, 0x03, 0x02, 0x00, 0x03, 0x00, 0x02, 0x03, 0x00, 0x00, |
结果这样:
1 | 0 mov reg[2], 0 |
然后inputStr
布局这样:
1 | .data:0000000140005040 ; _DWORD inputStr[200] |
input[0]
是读入,input[50+i]
是a1
,input[100+i]
是a2
,input[150+i]
是a3
。
大致看一下,写exp:
1 | a1=[0x0000009B,0x000000A8,0x00000002,0x000000BC,0x000000AC,0x0000009C,0x000000CE,0x000000FA,0x00000002,0x000000B9,0x000000FF,0x0000003A,0x00000074,0x00000048,0x00000019,0x00000069,0x000000E8,0x00000003,0x000000CB,0x000000C9,0x000000FF,0x000000FC,0x00000080,0x000000D6,0x0000008D,0x000000D7,0x00000072,0x00000000,0x000000A7,0x0000001D,0x0000003D,0x00000099,0x00000088,0x00000099,0x000000BF,0x000000E8,0x00000096,0x0000002E,0x0000005D,0x00000057] |
[GWCTF 2019]babyvm
简单虚拟机,先识别指令集:
1 | void __fastcall op_cal(__int64 a1) |
从网上嗦个脚本跑:
1 | opcode = [0xF5, 0xF1, 0xE1, 0x00, 0x00, 0x00, 0x00, 0xF2, 0xF1, 0xE4, |
结果如下:
1 | 0 cmp 21 |
发现288处是输入,也就是说前面部分都是忽悠人的。
看一下后面的加密逻辑差不多是:
1 | flag[0] = flag[0] ^ flag[1] |
网上偷的exp:
1 | from z3 import * |
[羊城杯 2021]Babyvm
先是TEA类的SMC,动调找到Dispatcher和opcodes,写脚本跑,下面代码都是网上的:
1 | opcode = [0xA1, 0xC1, 0x00, 0xB1, 0x77, 0xC2, 0x4A, 0x01, 0x00, 0x00, |
找出指令流:
1 | 0 cmp len 44 |
前32字符就是异或加密:
1 | print(chr(0x7b^74)+chr(0x2f^25)+chr(0xe8^221)+chr(0x37^15)+chr(0x2f^27)+chr(0xe8^137)+chr(0x7b^25)+chr(0x37^84)+chr(0x7b^79)+chr(0x7b^78)+chr(0x37^85)+chr(0x37^86)+chr(0xe8^142)+chr(0x2f^73)+chr(0x37^14)+chr(0x7b^75)+chr(0x37^6)+chr(0x37^84)+chr(0x2f^26)+chr(0x7b^66)+chr(0x37^83)+chr(0x7b^31)+chr(0x37^82)+chr(0xe8^219)+chr(0x7b^25)+chr(0xe8^217)+chr(0x7b^25)+chr(0x37^85)+chr(0x2f^25)+chr(0x37^0)+chr(0x7b^75)+chr(0x2f^30)) |
接下来4个爆破:
1 | start = 0x20202020 |
还是4个爆破:
1 |
|
最后4个爆破:
1 |
|
拼起来:16584abc45baff901c59dde3b1bb6701a254b06cdc23
[GKCTF 2020]EzMachine
很常规很贴近现实的虚拟机题,找到opcodes、reg_table、regs、dispatcher。
函数分别为:
1 | nop |
dump出opcodes,翻译成伪汇编:
1 | opcode = [0x01, 0x03, 0x03, 0x05, 0x00, 0x00, 0x11, 0x00, 0x00, 0x01, |
结果如下:
1 | 1:mov reg data 3,3 |
凑合着看,能发现简单加密逻辑,脚本是网上的:
1 | data = [0x7,0xd,0x0,0x5,0x1,0xc,0x1,0x0,0x0,0xd,0x5,0xf,0x0,0x9,0x5,0xf,0x3,0x0,0x2,0x5,0x3,0x3,0x1,0x7,0x7,0xb,0x2,0x1,0x2,0x7,0x2,0xc,0x2,0x2,] |