-
-
[原创]看雪 2016 CTF 第十八题 D-ASM-VM
-
发表于: 2016-12-8 12:32 6731
-
主要的技术点有:
a.以ret跳转的方式截断函数体,阻碍IDA流程图对局部变量的识别。
b.以SEH异常处理链的方式实现正确分支的间接跳转。
c.以模拟展平化汇编的vm隐藏普通对比和方程组等用于校验的h后半部分算法。
注册码校验分两部分进行 key = xsmKey + vmKey ,
其中前半部分xsmKey由a截断的函数体实现校验,成功后通过b实现跳转进入c的asm-vm校验后半部分vmKey。
vm相对简短,反编译出来即可得到校验条件,详细参考后续反编译代码解释和ASM-VM反编译代码。
1.入口
1.1 消息响应函数入口
_WinMain@16 中有注册对话框的初始化调用,Hi_DialogFunc_sub_401050为对话框消息响应函数,如下。
.text:0040101A push 0 ; dwInitParam
.text:0040101C push offset Hi_DialogFunc_sub_401050 ; lpDialogFunc
.text:00401021 push 0 ; hWndParent
.text:00401023 push 65h ; lpTemplateName
.text:00401025 mov eax, hInstance
.text:0040102A push eax ; hInstance
.text:0040102B call ds:DialogBoxParamA
1.2 校验入口
在1.1的消息函数 Hi_DialogFunc_sub_401050 中,
获取注册码key后进入核心校验函数Hi_XorSubIterMul_and_ASMvm_check_sub_401120
.text:004010AE call ds:GetDlgItemTextA
.text:004010B4 cmp esi, esp
.text:004010B6 call __chkesp
.text:004010BB lea ecx, [ebp+StringKey]
.text:004010BE push ecx
.text:004010BF mov edx, [ebp+hDlg]
.text:004010C2 push edx
.text:004010C3 call Hi_XorSubIterMul_and_ASMvm_check_sub_401120
2.前半部分注册码xsmKey校验与逆向求解
在Hi_XorSubIterMul_and_ASMvm_check_sub_401120中,函数被插入的ret跳转截断;
阻碍IDA对整个函数体局部变量的识别,ret的跳转是直接顺序连接的,直接nop掉即可。
nop掉后,快捷键"U"在函数首地址 401120 处去掉函数原有定义,
再快捷键"C"重建为代码,并重建函数,这时候流程图就比较清晰。
直接nop掉的代码片段:
.text:004011AC loc_4011AC:
.text:004011AC lea eax, loc_4011AC
.text:004011B2 add eax, 10h
.text:004011B5 push eax
.text:004011B6 retn
2.1 在函数Hi_XorSubIterMul_and_ASMvm_check_sub_401120中,逐步检测要求
a. key[0x0D]及其后面的字符都为数字
b. xsmKey = key[0~8], xkey='3!"!5|ben'
xsmKey_xs[i] = xsmKey[i] ^ xkey[i] - 0x41,其中i=0,..,8
要求 xsmKey_xs[0]>1,且xsmKey_xs为递增数列
c. xsmKey_xsm=1; xsmKey_xsm *= xsmKey_xs[i],其中i=0,..,8
要求累积xsmKey_xsm 等于 0x0D4C2086
d. 所以xsmKey就可以通过上述的逆操作得到
~c. python 尝试累积xsmKey_xsm=0xD4C2086的因式分解
>>> 0xD4C2086/2
111546435
>>> 0xD4C2086/2/5
22309287
>>> 0xD4C2086/2/5/7.0
3187041.0
>>> 0xD4C2086/2/5/7.0/9 //-----------9不正确
354115.6666666667
>>> 0xD4C2086/2/5/7.0/11
289731.0
>>> 0xD4C2086/2/5/7.0/11/13
22287.0
>>> 0xD4C2086/2/5/7.0/11/13/17
1311.0
>>> 0xD4C2086/2/5/7.0/11/13/17/19
69.0
>>> 0xD4C2086/2/5/7.0/11/13/17/19/23
3.0
刚刚好不多不少,且要求是递增数列,所以有数列
xsmKey_xs = [2,3,5,7,11,13,17,19,23]
~b. 一步到位就可以得到前半部分注册码
>>> xkey='3!"!5|ben'
>>> xsmKey_xs = [2,3,5,7,11,13,17,19,23]
>>> b"".join([chr((0x41+xsmKey_xs[i])^ord(xkey[i])) for i in xrange(0,9)])
'pediy2016'
2.2 异常跳转实现
2.2.1在 Hi_XorSubIterMul_and_ASMvm_check_sub_401120 的入口SEH初始化时,
跟进异常处理跳转表
.text:00401125 push offset Hi_SEH_ScopeTable_stru_4080C0
.text:0040112A push offset __except_handler3
Hi_SEH_ScopeTable_stru_4080C0 _SCOPETABLE_ENTRY <0FFFFFFFFh, offset loc_401334, offset loc_401338>
2.2.2 下述代码实现异常跳转表的修改,以实现产生异常时跳转到目标地址
a.分配新的跳转表条目lpMem_newScopeTableEntry
b.复制上面Hi_SEH_ScopeTable_stru_4080C0的前两个字段
c.新跳转表的第三字段为TryLevel=0保护的代码区异常处理回调,其修改为
上述的loc_401338+6,即为 0040133E,进入后半部分的ASM-vm校验。
.text:0040133E mov esp, [ebp+ms_exc.old_esp]
.text:00401341 mov edx, [ebp+P2_key]
.text:00401344 push edx ; P2_key
.text:00401345 mov eax, [ebp+hWnd]
.text:00401348 push eax ; hWnd
.text:00401349 call Hi_ASMvm_check_sub_4013B0
//----------------------------------------------------------
.text:0040115B push 0Ch ; size_t
.text:0040115D call _malloc
.text:00401162 add esp, 4
00401165 mov [ebp+lpMem_newScopeTableEntry], eax
...//省略无关代码
.text:004011C3 mov [ebp+ms_exc.registration.TryLevel], 0
.text:004011CA mov eax, [ebp+ms_exc.registration.ScopeTable]
.text:004011CD mov [ebp+var_1C_ScopeTable], eax
.text:004011D0 mov eax, [ebp+var_1C_ScopeTable]
.text:004011D3 mov [ebp+var_20_cpyScopeTable], eax
.text:004011D6 mov ecx, [ebp+lpMem_newScopeTableEntry]
.text:004011D9 mov edx, [ebp+var_20_cpyScopeTable]
.text:004011DC mov eax, [edx]
.text:004011DE mov [ecx], eax
.text:004011E0 mov ecx, [ebp+lpMem_newScopeTableEntry]
.text:004011E3 mov edx, [ebp+var_20_cpyScopeTable]
.text:004011E6 mov eax, [edx+4]
.text:004011E9 mov [ecx+4], eax
.text:004011EC mov ecx, [ebp+var_20_cpyScopeTable]
.text:004011EF mov edx, [ecx+8]
.text:004011F2 add edx, 6
.text:004011F5 mov eax, [ebp+lpMem_newScopeTableEntry]
.text:004011F8 mov [eax+8], edx
.text:004011FB mov eax, [ebp+lpMem_newScopeTableEntry]
.text:004011FE mov [ebp+ms_exc.registration.ScopeTable
//----------------------------------------------------------
d.如果累积xsmKey_xsm匹配,则会产生除零异常,转如后半部分校验
.text:00401318 loc_401318:
.text:00401318 mov ecx, 0D4C2086h
.text:0040131D sub ecx, dword ptr [ebp+var_58_xsmKey_xsm]
.text:00401320 mov eax, 64h
.text:00401325 cdq
.text:00401326 idiv ecx
3.模拟展平化汇编的vm
经过前半部分的校验正确后会进入 Hi_ASMvm_check_sub_4013B0 进行后部分校验
这种VM的模型类似于我们平时的汇编编程习惯,
编译器都会有汇编的MapList文件产生开关选项,其相当于把MapList的内容放在局部栈空间中。
而vm操作码也基本模仿我们的汇编指令也基本。
后续b中vm代码初始化和从中vm的指令handler表初始化指令都比较有规律,我们可以编写脚本提取出来做后续加工分析
后续的加工分析主要是vm指令反编译,即可反编译出vm代码的逻辑功能,参考后续分析。
a.下面是其VM寄存器缓存空间的分配,寄存器都是单字节的
其中
R7为标识flag寄存器,用于存储减和比较结果,
R6随后会初始化为0xFF,属于vm的栈寄存器vm-sp
R4_R5为16位寄存器相当于vm-eip,设为pc
Rxs=[R0,R1,R2,R3,pc:R4_R5,R6,R7]
.text:00401AE3 6A 08 push 8 ; size_t
.text:00401AE5 E8 81 28 00 00 call _malloc
.text:00401AEA 83 C4 04 add esp, 4
.text:00401AED 89 45 FC mov [ebp+lpMem_Rxs]
b. vm代码初始化
.text:004013DC C6 85 64 FD FE FF 01 mov [ebp+var_1029C], 1
.text:004013E3 C6 85 65 FD FE FF 00 mov [ebp+var_1029B], 0
.text:004013EA C6 85 66 FD FE FF 02 mov [ebp+var_1029A], 2
.text:004013F1 C6 85 67 FD FE FF 00 mov [ebp+var_10299], 0
.text:004013F8 C6 85 68 FD FE FF 03 mov [ebp+var_10298], 3
...//省略代码
.text:00401ACE C6 85 62 FE FE FF 00 mov [ebp+var_1019E], 0
.text:00401AD5 C6 85 63 FE FE FF 99 mov [ebp+var_1019D], 99h
.text:00401ADC C6 85 64 FE FE FF 00 mov [ebp+var_1019C], 0
c. vm的指令handler表初始化
.text:00401AF0 8D 05 01 21 40 00 lea eax, loc_402101
.text:00401AF6 89 85 70 FE FE FF mov [ebp+var_10190], eax
.text:00401AFC 8D 05 2D 21 40 00 lea eax, loc_40212D
...//省略代码
.text:004020E4 8D 05 44 41 40 00 lea eax, loc_404144
.text:004020EA 89 85 CC 00 FF FF mov [ebp+var_FF34], eax
.text:004020F0 8D 05 A3 41 40 00 lea eax, loc_4041A3
.text:004020F6 89 85 D0 00 FF FF mov [ebp+var_FF30]
3.1 vm代码chip提取和vm的指令handler表提取
a. vm的指令handler表提取
执行后续的#-------之间代码,即可得到vm指令的handler表,
后续即可根据需求之间定位到vm指令地址进行填表操作
格式 vm操作码:["vm操作指令名称","vmhandler地址"]
0x00:["vm_","4022CE"],#
0x01:["vm_","402101"],#
0x02:["vm_","40212D"],#
..//省略
0x98:["vm_","404144"],#
0x99:["vm_","4041A3"],#
#------- ------- -------
def pickOpTbl(InitTbl_s=0x401AED,InitTbl_e=0x4020FC):
InitTbl_ea = InitTbl_s
OpTbl = {}
while InitTbl_ea < InitTbl_e:
InitTbl_ea = FindCode(InitTbl_ea,SEARCH_NEXT|SEARCH_DOWN)
eaasm = GetDisasm(InitTbl_ea)
if "lea eax" in eaasm:
opAddr = int(eaasm.replace("lea eax, loc_",""),0x10)
InitTbl_ea = FindCode(InitTbl_ea,SEARCH_NEXT|SEARCH_DOWN)
eaasm = GetDisasm(InitTbl_ea)
locoff = int(eaasm[eaasm.index("_")+1:eaasm.index("]")],0x10)
OpTbl[locoff] = opAddr
return OpTbl
OpTbl = pickOpTbl()
OffRef = 0x10194
OpOffs = OpTbl.keys()
OpOffs.sort()
OpOffs.reverse()
OpvTbl = {}
for OpOff in OpOffs:
OpvTbl[(OffRef-OpOff)/4] = OpTbl[OpOff]
for op,opf in OpvTbl.viewitems():
print ' 0x{:02X}:["vm_","{:X}"],#'.format(op,opf)
#print "{:02X} var:{:X} {:X}".format(op,OffRef-op*4,opf)
#------- ------- -------
b. vm代码chip片段的提取
执行后续的#-------之间代码即可得到vm的代码片段Opcodes
#------- ------- -------
def pickOps(InitOp_s=0x4013DC,InitOp_e=0x401AE3):
Ops = {}
opoff = c_long(0)
for opa in xrange(InitOp_s,InitOp_e,7):
opoff.value = Dword(opa+2)
Ops[-opoff.value] = Byte(opa+6)
return Ops
Ops = pickOps()
OffRef = 0x1029C
OpOffs = Ops.keys()
OpOffs.sort()
OpOffs.reverse()
Opvs = {}
for OpOff in OpOffs:
Opvs[(OffRef-OpOff)] = Ops[OpOff]
Opcodes = []
for op,opf in Opvs.viewitems():
print "{:02X} var:{:X} {:X}".format(op,OffRef-op,opf)
Opcodes.append(opf)
#------- ------- -------
3.2 填完3.1的a中handler表,有了3.1的b在vm代码,就可以直接反编译了
以下是一种反编译框架,带仿真模拟功能,
这里并没有逆向所有vm指令,基本一边反编译一边添加,废话少说,
将后面的#-------直接代码直接复制到IDAPython里编译
Ccs=Opcodes
vm_run(Ccs,0) #反编译整个vm代码Ccs
#vm_run(Ccs,0,True) #仿真模拟执行
执行vm_run(Ccs,0)不带模拟直接反编译结果如下
pc为Ccs=Opcodes虚拟代码指令chip片段的指令指针,从偏移pc=0开始,0x100结束
op为指令操作码,后紧跟指令对应的handler地址,截至是指令的反编译
指令操作数格式与IA格式相仿。
pc:00 op:01 402101 vm_b_mov_R0_imm8 00 (0) //mov R0,imm8 后面为"无符号hex值 (有符号hex值)"
pc:02 op:02 40212D vm_b_mov_R1_imm8 00 (0)
pc:04 op:03 40215A vm_b_mov_R2_imm8 00 (0)
---------------------------{其中 var_E004 = 注册码key 执行前在.text 004041D8 call _strcpy处初始化
pc:06 op:96 40408B vm_b_R7_test_sub_RefVarBufR2_R1 R7=(var_E004[R2]-R1)? 1:0
pc:09 op:21 4027A5 vm_jz 13 else 0C
pc:0C op:29 402877 vm_b_add_R0_imm8 01 (01)
pc:0E op:2B 4028DB vm_b_add_R2_imm8 01 (01)
pc:10 op:27 402758 vm_jmp 06
---------------------------} 此断vm循环计算var_E004.key的字符长度,长度结果放于 R0
pc:13 op:81 403ABD vm_b_sub_R0_imm8 14 (14)
pc:15 op:21 4027A5 vm_jz 19 else 18 //key长度与0x14比较,如果不等则vm_reg_dtor_leave推出
pc:18 op:01 402101 vm_reg_dtor_leave
pc:19 op:01 402101 vm_b_mov_R0_imm8 2E (2E) //var_8004为后半部注册码逐步校验结果缓存区
pc:1B op:12 402401 vm_b_mov_VarX_R0 VarX:8000 var_8004[0]=R0 //当满足条件是会将相应位字节置为0x2E,以便最后检测
pc:1E op:01 402101 vm_b_mov_R0_imm8 63 (63)
pc:20 op:02 40212D vm_b_mov_R1_imm8 09 (9)
pc:22 op:8B 403CE8 vm_b_R7_test_sub_R0_RefVarBufR1 R7=(R0 - var_E004[R1])? 1:0
pc:25 op:21 4027A5 vm_jz 29 else 28 //-------key[0x09] == (R0 = 0x63 = 'c')
pc:28 op:01 402101 vm_reg_dtor_leave
pc:29 op:01 402101 vm_b_mov_R0_imm8 6F (6F)
pc:2B op:2A 4028A8 vm_b_add_R1_imm8 01 (01)
pc:2D op:8B 403CE8 vm_b_R7_test_sub_R0_RefVarBufR1 R7=(R0 - var_E004[R1])? 1:0
pc:30 op:21 4027A5 vm_jz 34 else 33 //-------key[0x0A] == (R0 = 0x6F = 'o')
pc:33 op:01 402101 vm_reg_dtor_leave
pc:34 op:2A 4028A8 vm_b_add_R1_imm8 01 (01)
pc:36 op:8B 403CE8 vm_b_R7_test_sub_R0_RefVarBufR1 R7=(R0 - var_E004[R1])? 1:0
pc:39 op:21 4027A5 vm_jz 3D else 3C //-------key[0x0B] == (R0 = 0x6F = 'o')
pc:3C op:01 402101 vm_reg_dtor_leave
pc:3D op:01 402101 vm_b_mov_R0_imm8 6C (6C)
pc:3F op:2A 4028A8 vm_b_add_R1_imm8 01 (01)
pc:41 op:8B 403CE8 vm_b_R7_test_sub_R0_RefVarBufR1 R7=(R0 - var_E004[R1])? 1:0
pc:44 op:21 4027A5 vm_jz 48 else 47 //-------key[0x0C] == (R0 = 0x6C = 'l')
pc:47 op:01 402101 vm_reg_dtor_leave
pc:48 op:01 402101 vm_b_mov_R0_imm8 2E (2E)
pc:4A op:03 40215A vm_b_mov_R2_imm8 01 (1) //比对结果var_8004[1]=0x2E,前面是var_8004[0]=0x2E
pc:4C op:14 402496 vm_b_mov_RefVarBufR2_R0 VarBufAddr:8000 var_8004[R2]=R0
pc:4F op:01 402101 vm_b_mov_R0_imm8 31 (31)
pc:51 op:2A 4028A8 vm_b_add_R1_imm8 01 (01)
pc:53 op:8B 403CE8 vm_b_R7_test_sub_R0_RefVarBufR1 R7=(R0 - var_E004[R1])? 1:0
pc:56 op:21 4027A5 vm_jz 5A else 59 //-------key[0x0D] == (R0 = 0x31 = '1')
pc:59 op:01 402101 vm_reg_dtor_leave
pc:5A op:0B 40222E vm_b_mov_R0_RefVarBufR1 VarBufAddr:2000 R0=var_E004[R1]
pc:5D op:29 402877 vm_b_add_R0_imm8 D0 (-30)
pc:5F op:08 4021C8 vm_b_mov_R2_R0 R2=R0
pc:60 op:45 402F39 vm_b_imul_R0_R2 R0*=R2
pc:61 op:45 402F39 vm_b_imul_R0_R2 R0*=R2
pc:62 op:1B 402665 vm_b_push_R0 //-------R0 = dn3 = pown(key[0x0D]-0x30),立方,压栈
pc:63 op:2A 4028A8 vm_b_add_R1_imm8 01 (01)
pc:65 op:0B 40222E vm_b_mov_R0_RefVarBufR1 VarBufAddr:2000 R0=var_E004[R1]
pc:68 op:29 402877 vm_b_add_R0_imm8 D0 (-30)
pc:6A op:08 4021C8 vm_b_mov_R2_R0 R2=R0
pc:6B op:45 402F39 vm_b_imul_R0_R2 R0*=R2
pc:6C op:45 402F39 vm_b_imul_R0_R2 R0*=R2
pc:6D op:1B 402665 vm_b_push_R0 //-------R0 = en3 = pown(key[0x0E]-0x30),立方,压栈
pc:6E op:2A 4028A8 vm_b_add_R1_imm8 01 (01)
pc:70 op:0B 40222E vm_b_mov_R0_RefVarBufR1 VarBufAddr:2000 R0=var_E004[R1]
pc:73 op:29 402877 vm_b_add_R0_imm8 D0 (-30)
pc:75 op:08 4021C8 vm_b_mov_R2_R0 R2=R0
pc:76 op:45 402F39 vm_b_imul_R0_R2 R0*=R2
pc:77 op:45 402F39 vm_b_imul_R0_R2 R0*=R2 //-------R0 = fn3 = pown(key[0x0F]-0x30),立方
pc:78 op:1D 4026DE vm_b_pop_R2 // R2 = en3
pc:79 op:2D 402923 vm_b_add_R0_R2 // R0 = R0 + R2 = fn3 + en3
pc:7A op:1D 4026DE vm_b_pop_R2 // R2 = dn
pc:7B op:2D 402923 vm_b_add_R0_R2 // R0 = R0 + R2 = fn3 + en3 + dn3
pc:7C op:1B 402665 vm_b_push_R0 //压栈 def3 = fn3 + en3 + dn3
pc:7D op:02 40212D vm_b_mov_R1_imm8 0D (D)
pc:7F op:0B 40222E vm_b_mov_R0_RefVarBufR1 VarBufAddr:2000 R0=var_E004[R1]
pc:82 op:29 402877 vm_b_add_R0_imm8 D0 (-30)
pc:84 op:41 402E89 vm_b_imul_R0_imm8 64 (64)
pc:86 op:2A 4028A8 vm_b_add_R1_imm8 01 (01)
pc:88 op:11 4023B0 vm_b_mov_R2_RefVarBufR1 VarBufAddr:2000 R2=var_E004[R1]
pc:8B op:2B 4028DB vm_b_add_R2_imm8 D0 (-30)
pc:8D op:43 402EEF vm_b_imul_R2_imm8 0A (0A)
pc:8F op:2D 402923 vm_b_add_R0_R2
pc:90 op:2A 4028A8 vm_b_add_R1_imm8 01 (01)
pc:92 op:11 4023B0 vm_b_mov_R2_RefVarBufR1 VarBufAddr:2000 R2=var_E004[R1]
pc:95 op:2B 4028DB vm_b_add_R2_imm8 D0 (-30)//相当于三位数字符转为十进制数值
pc:97 op:2D 402923 vm_b_add_R0_R2 // R0 = int(key[0x0D~0x0F],0x0A)
pc:98 op:1D 4026DE vm_b_pop_R2 //出栈R2 = def3 = fn3 + en3 + dn3
pc:99 op:85 403BE6 vm_b_R7_test_sub_R0_R2 //即要求 key[0x0D~0x0F] 三位十进制的值等于各位数的立方和,
pc:9A op:21 4027A5 vm_jz 9E else 9D //其整个三位数的高位key[0x0D]="1"
pc:9D op:01 402101 vm_reg_dtor_leave
pc:9E op:01 402101 vm_b_mov_R0_imm8 2E (2E)
pc:A0 op:03 40215A vm_b_mov_R2_imm8 02 (2) //比对结果var_8004[2]=0x2E
pc:A2 op:14 402496 vm_b_mov_RefVarBufR2_R0 VarBufAddr:8000 var_8004[R2]=R0
pc:A5 op:2A 4028A8 vm_b_add_R1_imm8 01 (01)
pc:A7 op:0B 40222E vm_b_mov_R0_RefVarBufR1 VarBufAddr:2000 R0=var_E004[R1]
pc:AA op:29 402877 vm_b_add_R0_imm8 D0 (-30)
pc:AC op:41 402E89 vm_b_imul_R0_imm8 0A (0A)
pc:AE op:2A 4028A8 vm_b_add_R1_imm8 01 (01)
pc:B0 op:11 4023B0 vm_b_mov_R2_RefVarBufR1 VarBufAddr:2000 R2=var_E004[R1]
pc:B3 op:2B 4028DB vm_b_add_R2_imm8 D0 (-30)
pc:B5 op:2D 402923 vm_b_add_R0_R2
pc:B6 op:1B 402665 vm_b_push_R0 //压栈 x = int(key[0x10:0x11],0x0A)
pc:B7 op:2A 4028A8 vm_b_add_R1_imm8 01 (01)
pc:B9 op:11 4023B0 vm_b_mov_R2_RefVarBufR1 VarBufAddr:2000 R2=var_E004[R1]
pc:BC op:2B 4028DB vm_b_add_R2_imm8 D0 (-30)
pc:BE op:43 402EEF vm_b_imul_R2_imm8 0A (0A)
pc:C0 op:2A 4028A8 vm_b_add_R1_imm8 01 (01)
pc:C2 op:0B 40222E vm_b_mov_R0_RefVarBufR1 VarBufAddr:2000 R0=var_E004[R1]
pc:C5 op:29 402877 vm_b_add_R0_imm8 D0 (-30)
pc:C7 op:30 402965 vm_b_add_R2_R0 //R2 = y = int(key[0x12:0x13],0x0A)
pc:C8 op:1E 4026B5 vm_b_pop_R1 //出栈 R1 = x
pc:C9 op:04 402187 vm_b_mov_R0_R1
pc:CA op:2D 402923 vm_b_add_R0_R2 //R0 = x + y
pc:CB op:42 402EBA vm_b_imul_R1_imm8 04 (04) //R1 = R1 * 4 = x * 4
pc:CD op:43 402EEF vm_b_imul_R2_imm8 02 (02) //R2 = R2 * 2 = y * 2
pc:CF op:2F 40294E vm_b_add_R1_R2 //R1 = R1 + R2 = 4x+2y
pc:D0 op:81 403ABD vm_b_sub_R0_imm8 23 (23)
pc:D2 op:26 40280E vm_jnz E4 else D5 //R0 - 0x23 = 0 >>得到 x+y=0x23
pc:D5 op:82 403B14 vm_b_cmp_R1_imm8 5E (5E)
pc:D7 op:26 40280E vm_jnz E4 else DA //R1 - 0x5E = 0 >>得到 4x+2y=0x5E
pc:DA op:01 402101 vm_b_mov_R0_imm8 2E (2E)
pc:DC op:03 40215A vm_b_mov_R2_imm8 03 (3) //比对结果var_8004[3]=0x2E
pc:DE op:14 402496 vm_b_mov_RefVarBufR2_R0 VarBufAddr:8000 var_8004[R2]=R0
pc:E1 op:27 402758 vm_jmp E5
pc:E4 op:01 402101 vm_reg_dtor_leave
pc:E5 op:02 40212D vm_b_mov_R1_imm8 00 (0)
pc:E7 op:01 402101 vm_b_mov_R0_imm8 00 (0)
pc:E9 op:03 40215A vm_b_mov_R2_imm8 2E (2E)
---------------------------{var_8004[0,1,2,3]是否都等于0x2E,
pc:EB op:98 404144 vm_b_R7_test_sub_RefVarBufR1_R2 R7=(var_8004[R1]-R2)? 1:0
pc:EE op:26 40280E vm_jnz F3 else F1
pc:F1 op:29 402877 vm_b_add_R0_imm8 01 (01)
pc:F3 op:2A 4028A8 vm_b_add_R1_imm8 01 (01)
pc:F5 op:82 403B14 vm_b_cmp_R1_imm8 04 (04)
pc:F7 op:26 40280E vm_jnz EB else FA
---------------------------}如果都等则显示成功 vm_MsgBox_Success,否则退出
pc:FA op:81 403ABD vm_b_sub_R0_imm8 04 (04)
pc:FC op:26 40280E vm_jnz 100 else FF
pc:FF op:99 4041A3 vm_MsgBox_Success
pc:100 op:01 402101 vm_reg_dtor_leave
综上vm代码的解释我们可以得到注册码后半部分的边界条件
a. key[0x09~0x0C] = "cool"
key[0x09] == (R0 = 0x63 = 'c')
key[0x0A] == (R0 = 0x6F = 'o')
key[0x0B] == (R0 = 0x6F = 'o')
key[0x0C] == (R0 = 0x6C = 'l')
b. key[0x0D~0x0F] = "153"
dn = key[0x0D] = '1'
en = key[0x0E]
fn = key[0x0F]
根据三位十进制的值等于各位数的立方和,通过下面的python代码我们可以枚举到
满足条件的三位数 000,001,153,370,371,407
由于最高位为"1",所以只能是"153"
nstr = "0123456789"
for dn in nstr:
for en in nstr:
for fn in nstr:
defn = int(dn+en+fn,0x0A)
def3 = pow(int(dn,0x0A),3)
def3 += pow(int(en,0x0A),3)
def3 += pow(int(fn,0x0A),3)
if defn == def3:
print dn+en+fn
c. key[0x10~0x13] = "1223"
x = key[0x10~0x11]
y = key[0x12~0x13]
vm代码确定的方程组为
x+y=0x23
4x+2y=0x5E
解方程组得到
x=12,y=23
即我们可以得到注册码的后半部分为vmKey="cool1531223"
结合前半部分 xsmKey = "pediy2016"
则注册码为 key = xsmKey + vmKey = "pediy2016cool1531223"
3.3 ASM-VM反编译代码
#------- ------- ------- ------- ------- ------- -------
#Rxs,lvc只在仿真模拟时才使用,这里提供的是正确的注册码
#可以考虑提供非正确的注册码,仿真类似于Trace指令
Rxs = [0,0,0,0,0,0,0xFF,0,]
lvc = { #LocalVarCache
0xE004:ord("p"),
0xE003:ord("e"),
0xE002:ord("d"),
0xE001:ord("i"),
0xE000:ord("y"),
0xDFFF:ord("2"),
0xDFFE:ord("0"),
0xDFFD:ord("1"),
0xDFFC:ord("6"),
0xDFFB:ord("c"),
0xDFFA:ord("o"),
0xDFF9:ord("o"),
0xDFF8:ord("l"),
0xDFF7:ord("1"),
0xDFF6:ord("5"),
0xDFF5:ord("3"),
0xDFF4:ord("1"),
0xDFF3:ord("2"),
0xDFF2:ord("2"),
0xDFF1:ord("3"),
0xDFF0:ord("\0")
}
VMHandler = {
0x00:["vm_reg_dtor_leave","4022CE"],#
0x01:["vm_b_mov_R0_imm8","402101"],#
0x02:["vm_b_mov_R1_imm8","40212D"],#
0x03:["vm_b_mov_R2_imm8","40215A"],#
0x04:["vm_b_mov_R0_R1","402187"],#
0x05:["vm_b_mov_R0_R2","402197"],#
0x06:["vm_b_mov_R1_R0","4021A7"],#
0x07:["vm_b_mov_R1_R2","4021B7"],#
0x08:["vm_b_mov_R2_R0","4021C8"],#
0x09:["vm_b_mov_R2_R1","4021D8"],#
0x0A:["vm_","4021E9"],#
0x0B:["vm_b_mov_R0_RefVarBufR1","40222E"],#
0x0C:["vm_","40227E"],#
0x0E:["vm_","4022D3"],#
0x0F:["vm_","402319"],#
0x10:["vm_","40236A"],#
0x11:["vm_b_mov_R2_RefVarBufR1","4023B0"],#
0x12:["vm_b_mov_VarX_R0","402401"],#
0x13:["vm_","402446"],#
0x14:["vm_b_mov_RefVarBufR2_R0","402496"],#
0x15:["vm_","4024E6"],#
0x16:["vm_","40252C"],#
0x17:["vm_","40257D"],#
0x18:["vm_","4025C3"],#
0x19:["vm_","402614"],#
0x1A:["vm_","40263D"],#
0x1B:["vm_b_push_R0","402665"],#vm_b_mov_RefVarBufR6_R0
0x1C:["vm_b_pop_R0","40268D"],#vm_b_mov_R0_RefVarBufR6
0x1D:["vm_b_pop_R2","4026DE"],#vm_b_mov_R2_RefVarBufR6
0x1E:["vm_b_pop_R1","4026B5"],#vm_b_mov_R1_RefVarBufR6
0x1F:["vm_","402706"],#
0x20:["vm_","40272F"],#
0x21:["vm_jz","4027A5"],#
0x26:["vm_jnz","40280E"],#
0x27:["vm_jmp","402758"],#
0x28:["vm_","4027A0"],#
0x29:["vm_b_add_R0_imm8","402877"],#
0x2A:["vm_b_add_R1_imm8","4028A8"],#
0x2B:["vm_b_add_R2_imm8","4028DB"],#
0x2C:["vm_b_add_R0_R1","40290E"],#
0x2D:["vm_b_add_R0_R2","402923"],#
0x2E:["vm_b_add_R1_R0","402938"],#
0x2F:["vm_b_add_R1_R2","40294E"],#
0x30:["vm_b_add_R2_R0","402965"],#
0x31:["vm_b_add_R2_R1","40297B"],#
0x32:["vm_","402992"],#
0x33:["vm_","4029DC"],#
0x34:["vm_","402A31"],#
0x35:["vm_","402A86"],#
0x36:["vm_","402AD2"],#
0x37:["vm_","402B29"],#
0x38:["vm_","402B75"],#
0x39:["vm_","402BCC"],#
0x3A:["vm_","402C23"],#
0x3B:["vm_","402C90"],#
0x3C:["vm_","402CFD"],#
0x3D:["vm_","402D55"],#
0x3E:["vm_","402DC3"],#
0x3F:["vm_","402E1B"],#
0x41:["vm_b_imul_R0_imm8","402E89"],#
0x42:["vm_b_imul_R1_imm8","402EBA"],#
0x43:["vm_b_imul_R2_imm8","402EEF"],#
0x44:["vm_","402F24"],#
0x45:["vm_b_imul_R0_R2","402F39"],#
0x46:["vm_","402F4E"],#
0x47:["vm_","402F64"],#
0x48:["vm_","402F7B"],#
0x49:["vm_","402F91"],#
0x4A:["vm_","402FA8"],#
0x4B:["vm_","402FF2"],#
0x4C:["vm_","403049"],#
0x4E:["vm_","4030A0"],#
0x4F:["vm_","4030EE"],#
0x50:["vm_","403147"],#
0x51:["vm_","403195"],#
0x52:["vm_","4031EE"],#
0x53:["vm_","403245"],#
0x54:["vm_","4032B2"],#
0x55:["vm_","40331F"],#
0x56:["vm_","403377"],#
0x57:["vm_","4033E5"],#
0x58:["vm_","40343D"],#
0x61:["vm_","4034AB"],#
0x62:["vm_","4034DC"],#
0x63:["vm_","40350F"],#
0x64:["vm_","403542"],#
0x65:["vm_","403557"],#
0x66:["vm_","40356C"],#
0x67:["vm_","403582"],#
0x68:["vm_","403599"],#
0x69:["vm_","4035AF"],#
0x6A:["vm_","4035C6"],#
0x6B:["vm_","403610"],#
0x6C:["vm_","403665"],#
0x6E:["vm_","4036BA"],#
0x6F:["vm_","403706"],#
0x70:["vm_","40375D"],#
0x71:["vm_","4037A9"],#
0x72:["vm_","403800"],#
0x73:["vm_","403857"],#
0x74:["vm_","4038C4"],#
0x75:["vm_","403931"],#
0x76:["vm_","403989"],#
0x77:["vm_","4039F7"],#
0x78:["vm_","403A4F"],#
0x81:["vm_b_sub_R0_imm8","403ABD"],#
0x82:["vm_b_cmp_R1_imm8","403B14"],#
0x83:["vm_b_sub_R2_imm8","403B6C"],#
0x84:["vm_","403BC4"],#
0x85:["vm_b_R7_test_sub_R0_R2","403BE6"],#
0x86:["vm_","403C08"],#
0x87:["vm_","403C2A"],#
0x88:["vm_","403C4D"],#
0x89:["vm_","403C6F"],#
0x8A:["vm_","403C92"],#
0x8B:["vm_b_R7_test_sub_R0_RefVarBufR1","403CE8"],#
0x8C:["vm_","403D49"],#
0x8E:["vm_","403DAA"],#
0x8F:["vm_","403E01"],#
0x90:["vm_","403E63"],#
0x91:["vm_","403EBA"],#
0x92:["vm_","403F1C"],#
0x93:["vm_","403F72"],#
0x94:["vm_","403FD3"],#
0x95:["vm_","404034"],#
0x96:["vm_b_R7_test_sub_RefVarBufR2_R1","40408B"],#
0x97:["vm_","4040ED"],#
0x98:["vm_b_R7_test_sub_RefVarBufR1_R2","404144"],#
0x99:["vm_MsgBox_Success","4041A3"],#
}
def vm_run(code_chip = [],pc = 0,bSimTrace=False):
globals()['bSimTrace'] = bSimTrace
Rxs[6]=0xFF
pc_end = code_chip.__len__()
while pc < pc_end:
pc = vm_dispatch(pc,bSimTrace)
if not pc:
break
def vm_dispatch(pc=0,bSimTrace=False):
op = Ccs[pc]
if op in VMHandler:
try:
pc = globals()[VMHandler[op][0]](pc+1,bSimTrace)
return pc
except KeyError as er:
print """def {}(pc): #{}
npc = pc+1
Rx = Ccs[pc]
trace_tips(0x{:02X},pc,npc,"".format())
return npc
""".format(VMHandler[op][0],VMHandler[op][1],op)
return None
else:
print "op:{:02X} of pc:{:02X} is not vm code".format(op,pc)
return None
def trace_tips(op,pc,npc,tips):
bSimTrace = globals()["bSimTrace"]
if bSimTrace:
print "pc:{:02X} npc:{:02X} op:{:02X} {} {}".format(pc-1,npc,op,VMHandler[op][1],tips)
else:
print "pc:{:02X} op:{:02X} {} {}".format(pc-1,op,VMHandler[op][1],tips)
def vm_get_imm16_u(pc):
return c_ushort((Ccs[pc+1] << 8)|Ccs[pc]).value
def vm_get_imm16_s(pc):
return c_short((Ccs[pc+1] << 8)|Ccs[pc]).value
def vm_set_R7_flag(ResultVal):
if ResultVal:
Rxs[7] = 1
else:
Rxs[7] = 0
def vm_get_lvc(VarAddr):
if VarAddr <= 0xFF:
pass
else:
VarAddr = 0x10004-VarAddr
if VarAddr in lvc:
return lvc[VarAddr]
else:
#raise Exception("VarAddr {:X} not in lvc".format(VarAddr))
print ("VarAddr {:X} is not given in lvc, default 0x00".format(VarAddr))
return 0
def vm_set_lvc(VarAddr,Val):
if VarAddr <= 0xFF:
pass
else:
VarAddr = 0x10004-VarAddr
lvc[VarAddr]=Val
print "lvc[{:X}] = {:X}".format(VarAddr,Val)
def vm_reg_dtor_leave(pc = 0,bSimTrace = False): #402101
npc = pc
trace_tips(0x01,pc,npc,"vm_reg_dtor_leave")
#raise Exception("-------Chip End-------")
return npc
def vm_b_mov_R0_imm8(pc = 0,bSimTrace = False): #402101
npc = pc+1
Rx = Ccs[pc]
if bSimTrace:
Rxs[0]=Rx
trace_tips(0x01,pc,npc,"vm_b_mov_R0_imm8 {:02X} ({:X})".format(Rx,c_byte(Rx).value))
return npc
def vm_b_mov_R1_imm8(pc = 0,bSimTrace = False): #40212D
npc = pc+1
Rx = Ccs[pc]
if bSimTrace:
Rxs[1]=Rx
trace_tips(0x02,pc,npc,"vm_b_mov_R1_imm8 {:02X} ({:X})".format(Rx,c_byte(Rx).value))
return npc
def vm_b_mov_R2_imm8(pc = 0,bSimTrace = False): #40215A
npc = pc+1
Rx = Ccs[pc]
if bSimTrace:
Rxs[2]=Rx
trace_tips(0x03,pc,npc,"vm_b_mov_R2_imm8 {:02X} ({:X})".format(Rx,c_byte(Rx).value))
return npc
def vm_b_mov_R0_R1(pc = 0,bSimTrace = False): #402187
npc = pc
if bSimTrace:
Rxs[0] = Rxs[1]
trace_tips(0x04,pc,npc,"vm_b_mov_R0_R1".format())
return npc
def vm_b_mov_R0_R2(pc = 0,bSimTrace = False): #402197
npc = pc
if bSimTrace:
Rxs[0] = Rxs[2]
trace_tips(0x05,pc,npc,"vm_b_mov_R0_R2".format())
return npc
def vm_b_mov_R1_R0(pc = 0,bSimTrace = False): #4021A7
npc = pc
if bSimTrace:
Rxs[1] = Rxs[0]
trace_tips(0x06,pc,npc,"vm_b_mov_R1_R0".format())
return npc
def vm_b_mov_R1_R2(pc = 0,bSimTrace = False): #4021B7
npc = pc
if bSimTrace:
Rxs[1] = Rxs[2]
trace_tips(0x07,pc,npc,"vm_b_mov_R1_R2".format())
return npc
def vm_b_mov_R2_R0(pc = 0,bSimTrace = False): #4021C8
npc = pc
if bSimTrace:
Rxs[2] = Rxs[0]
trace_tips(0x08,pc,npc,"vm_b_mov_R2_R0".format())
return npc
def vm_b_mov_R2_R1(pc = 0,bSimTrace = False): #4021D8
npc = pc
if bSimTrace:
Rxs[2] = Rxs[1]
trace_tips(0x09,pc,npc,"vm_b_mov_R2_R1".format())
return npc
def vm_b_R7_test_sub_RefVarBufR2_R1(pc = 0,bSimTrace = False): #40408B
npc = pc+2
RefVarOff = vm_get_imm16_u(pc)
if bSimTrace:
vm_set_R7_flag(vm_get_lvc(RefVarOff+Rxs[2])-Rxs[1])
trace_tips(0x96,pc,npc,"vm_b_R7_test_sub_RefVarBufR2_R1 R7=(var_{:X}[R2]-R1)? 1:0 ".format(0x10004-RefVarOff))
return npc
def vm_b_R7_test_sub_RefVarBufR1_R2(pc = 0,bSimTrace = False): #404144
npc = pc+2
RefVarOff = vm_get_imm16_u(pc)
if bSimTrace:
vm_set_R7_flag(vm_get_lvc(RefVarOff+Rxs[1])-Rxs[2])
trace_tips(0x98,pc,npc,"vm_b_R7_test_sub_RefVarBufR1_R2 R7=(var_{:X}[R1]-R2)? 1:0 ".format(0x10004-RefVarOff))
return npc
from ctypes import *
def vm_MsgBox_Success(pc = 0,bSimTrace = False): #4041A3
npc = pc
if bSimTrace:
windll.user32.MessageBoxA(0,"Sucess!","Sucess!",0)
trace_tips(0x99,pc,npc,"vm_MsgBox_Success".format())
return npc
def vm_jz(pc = 0,bSimTrace = False): #4027A5
npc = pc
#
skip_jmp_npc = pc+2
#
off = vm_get_imm16_s(pc)
jmp_npc = pc-1
jmp_npc += off
#
if bSimTrace:
if Rxs[7]:#NZ skip jmp
npc = skip_jmp_npc
else: #Z jmp
npc = jmp_npc
else:
npc = skip_jmp_npc
trace_tips(0x21,pc,npc,"vm_jz {:02X} else {:02X}".format(jmp_npc,skip_jmp_npc))
return npc
def vm_jnz(pc = 0,bSimTrace = False): #40280E
npc = pc
#
skip_jmp_npc = pc+2
#
off = vm_get_imm16_s(pc)
jmp_npc = pc-1
jmp_npc += off
#
if bSimTrace:
if not Rxs[7]:#Z skip jmp
npc = skip_jmp_npc
else: #NZ jmp
npc = jmp_npc
else:
npc = skip_jmp_npc
trace_tips(0x26,pc,npc,"vm_jnz {:02X} else {:02X}".format(jmp_npc,skip_jmp_npc))
return npc
#return skip_jmp_npc
#return npc ******* ******* *******
def vm_b_add_R0_imm8(pc = 0,bSimTrace = False): #402877
npc = pc+1
imm8 = Ccs[pc]
if bSimTrace:
Rxs[0]+=c_byte(imm8).value
trace_tips(0x29,pc,npc,"vm_b_add_R0_imm8 {:02X} ({:02X})".format(imm8,c_byte(imm8).value))
return npc
def vm_b_add_R1_imm8(pc = 0,bSimTrace = False): #4028A8
npc = pc+1
imm8 = Ccs[pc]
if bSimTrace:
Rxs[1]+=c_byte(imm8).value
trace_tips(0x2A,pc,npc,"vm_b_add_R1_imm8 {:02X} ({:02X})".format(imm8,c_byte(imm8).value))
return npc
def vm_b_add_R2_imm8(pc = 0,bSimTrace = False): #4028DB
npc = pc+1
imm8 = Ccs[pc]
if bSimTrace:
Rxs[2]+=c_byte(imm8).value
trace_tips(0x2B,pc,npc,"vm_b_add_R2_imm8 {:02X} ({:02X})".format(imm8,c_byte(imm8).value))
return npc
def vm_jmp(pc = 0,bSimTrace = False): #402758
off = vm_get_imm16_s(pc)
jmp_npc = pc-1
jmp_npc += off
if bSimTrace:
npc = jmp_npc
else:
skip_jmp_npc = pc+2
npc = skip_jmp_npc
trace_tips(0x27,pc,npc,"vm_jmp {:02X}".format(jmp_npc))
return npc
def vm_b_sub_R0_imm8(pc = 0,bSimTrace = False): #403ABD
npc = pc+1
imm8 = Ccs[pc]
if bSimTrace:
#print "R0={:02X}".format(Rxs[0])
Rxs[0]-=imm8
vm_set_R7_flag(Rxs[0])
trace_tips(0x81,pc,npc,"vm_b_sub_R0_imm8 {:02X} ({:02X})".format(imm8,c_byte(imm8).value))
return npc
def vm_b_cmp_R1_imm8(pc = 0,bSimTrace = False): #403B14
npc = pc+1
imm8 = Ccs[pc]
if bSimTrace:
#Rxs[1]-=imm8 not given back to Rxs[1]
vm_set_R7_flag(Rxs[1]-imm8)
trace_tips(0x82,pc,npc,"vm_b_cmp_R1_imm8 {:02X} ({:02X})".format(imm8,c_byte(imm8).value))
return npc
def vm_b_sub_R2_imm8(pc = 0,bSimTrace = False): #403B6C
npc = pc+1
imm8 = Ccs[pc]
if bSimTrace:
Rxs[2]-=imm8
vm_set_R7_flag(Rxs[2])
trace_tips(0x83,pc,npc,"vm_b_sub_R2_imm8 {:02X} ({:02X})".format(imm8,c_byte(imm8).value))
return npc
def vm_b_mov_VarX_R0(pc = 0,bSimTrace = False): #402401
npc = pc+2
VarAddr = vm_get_imm16_u(pc)
if bSimTrace:
vm_set_lvc(VarAddr,Rxs[0])
trace_tips(0x12,pc,npc,"vm_b_mov_VarX_R0 VarX:{:X} var_{:X}[0]=R0".format(VarAddr,0x10004-VarAddr))
return npc
def vm_b_R7_test_sub_R0_RefVarBufR1(pc = 0,bSimTrace = False): #403CE8
npc = pc+2
VarAddr = vm_get_imm16_u(pc)
if bSimTrace:
Rxs[0] -= vm_get_lvc(VarAddr)
vm_set_R7_flag(Rxs[0])
trace_tips(0x8B,pc,npc,"vm_b_R7_test_sub_R0_RefVarBufR1 R7=(R0 - var_{:X}[R1])? 1:0 ".format(0x10004-VarAddr))
return npc
def vm_b_mov_RefVarBufR2_R0(pc = 0,bSimTrace = False): #402496
npc = pc+2
VarBufAddr = vm_get_imm16_u(pc)
if bSimTrace:
VarBufXAddr = VarBufAddr + Rxs[2]
vm_set_lvc(VarBufXAddr,Rxs[0])
trace_tips(0x14,pc,npc,"vm_b_mov_RefVarBufR2_R0 VarBufAddr:{:X} var_{:X}[R2]=R0".format(VarBufAddr,0x10004-VarBufAddr))
return npc
def vm_b_mov_R0_RefVarBufR1(pc = 0,bSimTrace = False): #40222E
npc = pc+2
VarBufAddr = vm_get_imm16_u(pc)
if bSimTrace:
VarBufXAddr = VarBufAddr + Rxs[1]
Rxs[0] = vm_get_lvc(VarBufXAddr)
trace_tips(0x0B,pc,npc,"vm_b_mov_R0_RefVarBufR1 VarBufAddr:{:X} R0=var_{:X}[R1]".format(VarBufAddr,0x10004-VarBufAddr))
return npc
def vm_b_mov_R2_R0(pc = 0,bSimTrace = False): #4021C8
npc = pc
if bSimTrace:
Rxs[2] = Rxs[0]
trace_tips(0x08,pc,npc,"vm_b_mov_R2_R0 R2=R0".format())
return npc
def vm_b_imul_R0_R2(pc = 0,bSimTrace = False): #402F39
npc = pc
if bSimTrace:
Rxs[0] = c_ubyte(Rxs[0] * Rxs[2]).value
trace_tips(0x45,pc,npc,"vm_b_imul_R0_R2 R0*=R2".format())
return npc
def vm_b_push_R0(pc = 0,bSimTrace = False): #402665
npc = pc
if bSimTrace:
vm_set_lvc(Rxs[6],Rxs[0])
VarBufXAddr = Rxs[6]
Rxs[6] -= 1
trace_tips(0x1B,pc,npc,"vm_b_push_R0 VarXAddr:{:X} var_{:X}=R0".format(VarBufXAddr,0xFF04-c_ubyte(VarBufXAddr).value))
else:
trace_tips(0x1B,pc,npc,"vm_b_push_R0".format())
return npc
def vm_b_pop_R0(pc = 0,bSimTrace = False): #40268D
npc = pc
if bSimTrace:
Rxs[6] += 1
VarBufXAddr = Rxs[6]
Rxs[0] = vm_get_lvc(VarBufXAddr)
trace_tips(0x1C,pc,npc,"vm_b_pop_R0 VarXAddr:{:X} R2=var_{:X}".format(VarBufXAddr,0xFF04-c_ubyte(VarBufXAddr).value))
else:
trace_tips(0x1C,pc,npc,"vm_b_pop_R0".format())
return npc
def vm_b_pop_R2(pc = 0,bSimTrace = False): #4026DE
npc = pc
if bSimTrace:
Rxs[6] += 1
VarBufXAddr = Rxs[6]
Rxs[2] = vm_get_lvc(VarBufXAddr)
trace_tips(0x1D,pc,npc,"vm_b_pop_R2 VarXAddr:{:X} R2=var_{:X}".format(VarBufXAddr,0xFF04-c_ubyte(VarBufXAddr).value))
else:
trace_tips(0x1D,pc,npc,"vm_b_pop_R2".format())
return npc
def vm_b_pop_R1(pc = 0,bSimTrace = False): #4026B5
npc = pc
if bSimTrace:
Rxs[6] += 1
VarBufXAddr = Rxs[6]
Rxs[1] = vm_get_lvc(VarBufXAddr)
trace_tips(0x1E,pc,npc,"vm_b_pop_R1 VarXAddr:{:X} R2=var_{:X}".format(VarBufXAddr,0xFF04-c_ubyte(VarBufXAddr).value))
else:
trace_tips(0x1E,pc,npc,"vm_b_pop_R1".format())
return npc
def vm_b_add_R0_R1(pc = 0,bSimTrace = False): #40290E
npc = pc
if bSimTrace:
Rxs[0]+=Rxs[1]
trace_tips(0x2C,pc,npc,"vm_b_add_R0_R1".format())
return npc
def vm_b_add_R0_R2(pc = 0,bSimTrace = False): #402923
npc = pc
if bSimTrace:
Rxs[0]+=Rxs[2]
trace_tips(0x2D,pc,npc,"vm_b_add_R0_R2".format())
return npc
def vm_b_add_R1_R0(pc = 0,bSimTrace = False): #402938
npc = pc
if bSimTrace:
Rxs[1]+=Rxs[0]
trace_tips(0x2E,pc,npc,"vm_b_add_R1_R0".format())
return npc
def vm_b_add_R1_R2(pc = 0,bSimTrace = False): #40294E
npc = pc
if bSimTrace:
Rxs[1]+=Rxs[2]
trace_tips(0x2F,pc,npc,"vm_b_add_R1_R2".format())
return npc
def vm_b_add_R2_R0(pc = 0,bSimTrace = False): #402965
npc = pc
if bSimTrace:
#print "R2={:02X},R0={:02X}".format(Rxs[2],Rxs[0])
Rxs[2]+=Rxs[0]
trace_tips(0x30,pc,npc,"vm_b_add_R2_R0".format())
return npc
def vm_b_add_R2_R1(pc = 0,bSimTrace = False): #40297B
npc = pc
if bSimTrace:
Rxs[2]+=Rxs[1]
trace_tips(0x31,pc,npc,"vm_b_add_R2_R1".format())
return npc
def vm_b_imul_R0_imm8(pc = 0,bSimTrace = False): #402E89
npc = pc + 1
imm8 = Ccs[pc]
if bSimTrace:
Rxs[0]*=imm8
trace_tips(0x41,pc,npc,"vm_b_imul_R0_imm8 {:02X} ({:02X})".format(imm8,c_byte(imm8).value))
return npc
def vm_b_imul_R1_imm8(pc = 0,bSimTrace = False): #402EBA
npc = pc + 1
imm8 = Ccs[pc]
if bSimTrace:
Rxs[1]*=imm8
trace_tips(0x42,pc,npc,"vm_b_imul_R1_imm8 {:02X} ({:02X})".format(imm8,c_byte(imm8).value))
return npc
def vm_b_imul_R2_imm8(pc = 0,bSimTrace = False): #402EEF
npc = pc + 1
imm8 = Ccs[pc]
if bSimTrace:
Rxs[2]*=imm8
trace_tips(0x43,pc,npc,"vm_b_imul_R2_imm8 {:02X} ({:02X})".format(imm8,c_byte(imm8).value))
return npc
def vm_b_mov_R2_RefVarBufR1(pc = 0,bSimTrace = False): #4023B0
npc = pc+2
VarBufAddr = vm_get_imm16_u(pc)
VarBufXAddr = VarBufAddr + Rxs[1]
if bSimTrace:
Rxs[2] = vm_get_lvc(VarBufXAddr)
trace_tips(0x11,pc,npc,"vm_b_mov_R2_RefVarBufR1 VarBufAddr:{:X} R2=var_{:X}[R1]".format(VarBufAddr,0x10004-VarBufAddr))
return npc
def vm_b_R7_test_sub_R0_R2(pc = 0,bSimTrace = False): #403BE6
npc = pc
if bSimTrace:
Rxs[0] -= Rxs[2]
vm_set_R7_flag(Rxs[0])
trace_tips(0x85,pc,npc,"vm_b_R7_test_sub_R0_R2".format())
return npc
#------- ------- ------- ------- ------- ------- -------
3.4
ASM-VM最初的分析模型的所有handlerh列表
sti = StepInfo{ //=malloc(8)
.00h.Buf
.04hw.pc
.06h.spc
}
00 var:10194 4022CE exit
01 var:10190 402101 sti.Buf[0] = var_10004[sti.pc++]
02 var:1018C 40212D sti.Buf[1] = var_10004[sti.pc++]
03 var:10188 40215A sti.Buf[2] = var_10004[sti.pc++]
04 var:10184 402187 sti.Buf[0] = sti.Buf[1]
05 var:10180 402197 sti.Buf[0] = sti.Buf[2]
06 var:1017C 4021A7 sti.Buf[1] = sti.Buf[0]
07 var:10178 4021B7 sti.Buf[1] = sti.Buf[2]
08 var:10174 4021C8 sti.Buf[2] = sti.Buf[0]
09 var:10170 4021D8 sti.Buf[2] = sti.Buf[1]
0A var:1016C 4021E9 w = var_10004[sti.pc++2];sti.Buf[0] = var_10004[w]
0B var:10168 40222E w = var_10004[sti.pc++2];b=sti.Buf[1];sti.Buf[0] = var_10004[w+b]
0C var:10164 40227E w = var_10004[sti.pc++2];b=sti.Buf[2];sti.Buf[0] = var_10004[w+b]
0E var:1015C 4022D3 w = var_10004[sti.pc++2];sti.Buf[1] = var_10004[w]
0F var:10158 402319 w = var_10004[sti.pc++2];b=sti.Buf[2];sti.Buf[1] = var_10004[w+b]
10 var:10154 40236A w = var_10004[sti.pc++2];sti.Buf[2] = var_10004[w]
11 var:10150 4023B0 w = var_10004[sti.pc++2];b=sti.Buf[1];sti.Buf[2] = var_10004[w+b]
12 var:1014C 402401 w = var_10004[sti.pc++2];var_10004[w]=sti.Buf[0]
13 var:10148 402446 w = var_10004[sti.pc++2];b=sti.Buf[1];var_10004[w+b] = sti.Buf[0]
14 var:10144 402496 w = var_10004[sti.pc++2];b=sti.Buf[2];var_10004[w+b] = sti.Buf[0]
15 var:10140 4024E6 w = var_10004[sti.pc++2];var_10004[w] = sti.Buf[1]
16 var:1013C 40252C w = var_10004[sti.pc++2];b=sti.Buf[2];sti.var_10004[w+b] = Buf[1]
17 var:10138 40257D w = var_10004[sti.pc++2];var_10004[w] = sti.Buf[2]
18 var:10134 4025C3 w = var_10004[sti.pc++2];b=sti.Buf[1];var_10004[w+b] = sti.Buf[2]
19 var:10130 402614 var_FF04[sti.spc--] = sti.Buf[1]
1A var:1012C 40263D var_FF04[sti.spc--] = sti.Buf[2]
1B var:10128 402665 var_FF04[sti.spc--] = sti.Buf[0]
1C var:10124 40268D sti.Buf[0] = var_FF04[++sti.spc]
1D var:10120 4026DE sti.Buf[2] = var_FF04[++sti.spc]
1E var:1011C 4026B5 sti.Buf[1] = var_FF04[++sti.spc]
1F var:10118 402706 var_FF04[sti.spc--] = sti.Buf[7]
20 var:10114 40272F sti.Buf[7] = var_FF04[++sti.spc]
21 var:10110 4027A5 sti.Buf[7].al? sti.pc++2:(w1=var_10004[sti.pc--];sti.pc+=w1)
26 var:100FC 40280E sti.Buf[7].al? (w1=var_10004[sti.pc--];sti.pc+=w1):sti.pc++2
27 var:100F8 402758 w1 = var_10004[sti.pc--];sti.pc+=w1
28 var:100F4 4027A0 jmp
29 var:100F0 402877 sti.Buf[0].al+=var_10004[sti.pc++]
2A var:100EC 4028A8 sti.Buf[1].al+=var_10004[sti.pc++]
2B var:100E8 4028DB sti.Buf[2].al+=var_10004[sti.pc++]
2C var:100E4 40290E sti.Buf[0] += sti.Buf[1]
2D var:100E0 402923 sti.Buf[0] += sti.Buf[2]
2E var:100DC 402938 sti.Buf[1] += sti.Buf[0]
2F var:100D8 40294E sti.Buf[1] += sti.Buf[2]
30 var:100D4 402965 sti.Buf[2] += sti.Buf[0]
31 var:100D0 40297B sti.Buf[2] += sti.Buf[1]
32 var:100CC 402992 w = var_10004[sti.pc++2];sti.Buf[0].al+=var_10004[w]
33 var:100C8 4029DC w = var_10004[sti.pc++2];b = sti.Buf[1];sti.Buf[0].al+=var_10004[w+b]
34 var:100C4 402A31 w = var_10004[sti.pc++2];b = sti.Buf[2];sti.Buf[0].al+=var_10004[w+b]
35 var:100C0 402A86 w = var_10004[sti.pc++2];sti.Buf[1].al+=var_10004[w]
36 var:100BC 402AD2 w = var_10004[sti.pc++2];b = sti.Buf[2];sti.Buf[1].al+=var_10004[w+b]
37 var:100B8 402B29 w = var_10004[sti.pc++2];sti.Buf[2].al+=var_10004[w]
38 var:100B4 402B75 w = var_10004[sti.pc++2];b = sti.Buf[1];sti.Buf[2].al+=var_10004[w+b]
39 var:100B0 402BCC w = var_10004[sti.pc++2];var_10004[w]+=sti.Buf[0]
3A var:100AC 402C23 w = var_10004[sti.pc++2];b = sti.Buf[1];var_10004[w+b]+=sti.Buf[0]
3B var:100A8 402C90 w = var_10004[sti.pc++2];b = sti.Buf[2];var_10004[w+b]+=sti.Buf[0]
3C var:100A4 402CFD w = var_10004[sti.pc++2];var_10004[w]+=sti.Buf[1]
3D var:100A0 402D55 w = var_10004[sti.pc++2];b = sti.Buf[2];var_10004[w+b]+=sti.Buf[1]
3E var:1009C 402DC3 w = var_10004[sti.pc++2];var_10004[w]+=sti.Buf[2]
3F var:10098 402E1B w = var_10004[sti.pc++2];b = sti.Buf[1];var_10004[w+b]+=sti.Buf[2]
41 var:10090 402E89 w = var_10004[sti.pc++];sti.Buf[0]*=var_10004[w]
42 var:1008C 402EBA w = var_10004[sti.pc++];sti.Buf[1]*=var_10004[w]
43 var:10088 402EEF w = var_10004[sti.pc++];sti.Buf[2]*=var_10004[w]
44 var:10084 402F24 sti.Buf[0]*=sti.Buf[1]
45 var:10080 402F39 sti.Buf[0]*=sti.Buf[2]
46 var:1007C 402F4E sti.Buf[1]*=sti.Buf[0]
47 var:10078 402F64 sti.Buf[1]*=sti.Buf[2]
48 var:10074 402F7B sti.Buf[2]*=sti.Buf[0]
49 var:10070 402F91 sti.Buf[2]*=sti.Buf[1]
4A var:1006C 402FA8 w = var_10004[sti.pc++2];sti.Buf[0]*=var_10004[w]
4B var:10068 402FF2 w = var_10004[sti.pc++2];b = sti.Buf[1];sti.Buf[0]*=var_10004[w+b]
4C var:10064 403049 w = var_10004[sti.pc++2];b = sti.Buf[2];sti.Buf[0]*=var_10004[w+b]
4E var:1005C 4030A0 w = var_10004[sti.pc++2];sti.Buf[1]*=var_10004[w]
4F var:10058 4030EE w = var_10004[sti.pc++2];b = sti.Buf[2];sti.Buf[1]*=var_10004[w+b]
50 var:10054 403147 w = var_10004[sti.pc++2];sti.Buf[2]*=var_10004[w]
51 var:10050 403195 w = var_10004[sti.pc++2];b = sti.Buf[1];sti.Buf[2]*=var_10004[w+b]
52 var:1004C 4031EE w = var_10004[sti.pc++2];var_10004[w]*=sti.Buf[0]
53 var:10048 403245 w = var_10004[sti.pc++2];b = sti.Buf[1];var_10004[w+b]*=sti.Buf[0]
54 var:10044 4032B2 w = var_10004[sti.pc++2];b = sti.Buf[2];var_10004[w+b]*=sti.Buf[0]
55 var:10040 40331F w = var_10004[sti.pc++2];var_10004[w]*=sti.Buf[1]
56 var:1003C 403377 w = var_10004[sti.pc++2];b = sti.Buf[2];var_10004[w+b]*=sti.Buf[1]
57 var:10038 4033E5 w = var_10004[sti.pc++2];var_10004[w]*=sti.Buf[2]
58 var:10034 40343D w = var_10004[sti.pc++2];b = sti.Buf[1];var_10004[w+b]*=sti.Buf[2]
61 var:10010 4034AB w = var_10004[sti.pc++];sti.Buf[0]^=var_10004[w]
62 var:1000C 4034DC w = var_10004[sti.pc++];sti.Buf[1]^=var_10004[w]
63 var:10008 40350F w = var_10004[sti.pc++];sti.Buf[2]^=var_10004[w]
64 var:10004 403542 sti.Buf[0]^=sti.Buf[1]
65 var:10000 403557 sti.Buf[0]^=sti.Buf[2]
66 var:FFFC 40356C sti.Buf[1]^=sti.Buf[0]
67 var:FFF8 403582 sti.Buf[1]^=sti.Buf[2]
68 var:FFF4 403599 sti.Buf[2]^=sti.Buf[0]
69 var:FFF0 4035AF sti.Buf[2]^=sti.Buf[1]
6A var:FFEC 4035C6 w = var_10004[sti.pc++2];sti.Buf[0]^=var_10004[w]
6B var:FFE8 403610 w = var_10004[sti.pc++2];b = sti.Buf[1];sti.Buf[0]^=var_10004[w+b]
6C var:FFE4 403665 w = var_10004[sti.pc++2];b = sti.Buf[2];sti.Buf[0]^=var_10004[w+b]
6E var:FFDC 4036BA w = var_10004[sti.pc++2];sti.Buf[1]^=var_10004[w]
6F var:FFD8 403706 w = var_10004[sti.pc++2];b = sti.Buf[2];sti.Buf[1]^=var_10004[w+b]
70 var:FFD4 40375D w = var_10004[sti.pc++2];sti.Buf[2]^=var_10004[w]
71 var:FFD0 4037A9 w = var_10004[sti.pc++2];b = sti.Buf[1];sti.Buf[2]^=var_10004[w+b]
72 var:FFCC 403800 w = var_10004[sti.pc++2];var_10004[w]^=sti.Buf[0]
73 var:FFC8 403857 w = var_10004[sti.pc++2];b = sti.Buf[1];var_10004[w+b]^=sti.Buf[0]
74 var:FFC4 4038C4 w = var_10004[sti.pc++2];b = sti.Buf[2];var_10004[w+b]^=sti.Buf[0]
75 var:FFC0 403931 w = var_10004[sti.pc++2];var_10004[w]^=sti.Buf[1]
76 var:FFBC 403989 w = var_10004[sti.pc++2];b = sti.Buf[2];var_10004[w+b]^=sti.Buf[1]
77 var:FFB8 4039F7 w = var_10004[sti.pc++2];var_10004[w]^=sti.Buf[2]
78 var:FFB4 403A4F w = var_10004[sti.pc++2];b = sti.Buf[1];var_10004[w+b]^=sti.Buf[2]
81 var:FF90 403ABD w = var_10004[sti.pc++];sti.Buf[7]=(sti.Buf[0]-=var_10004[w])? 1:0
82 var:FF8C 403B14 w = var_10004[sti.pc++];sti.Buf[7]=(sti.Buf[1]-=var_10004[w])? 1:0
83 var:FF88 403B6C w = var_10004[sti.pc++];sti.Buf[7]=(sti.Buf[2]-=var_10004[w])? 1:0
84 var:FF84 403BC4 sti.Buf[7] = (sti.Buf[0]-sti.Buf[1])? 1:0
85 var:FF80 403BE6 sti.Buf[7] = (sti.Buf[0]-sti.Buf[2])? 1:0
86 var:FF7C 403C08 sti.Buf[7] = (sti.Buf[1]-sti.Buf[0])? 1:0
87 var:FF78 403C2A sti.Buf[7] = (sti.Buf[1]-sti.Buf[2])? 1:0
88 var:FF74 403C4D sti.Buf[7] = (sti.Buf[2]-sti.Buf[0])? 1:0
89 var:FF70 403C6F sti.Buf[7] = (sti.Buf[2]-sti.Buf[1])? 1:0
8A var:FF6C 403C92 w = var_10004[sti.pc++2];sti.Buf[7] = (sti.Buf[0]-var_10004[w])? 1:0
8B var:FF68 403CE8 w = var_10004[sti.pc++2];b = sti.Buf[1];sti.Buf[7] = (sti.Buf[0]-var_10004[w+b])? 1:0
8C var:FF64 403D49 w = var_10004[sti.pc++2];b = sti.Buf[2];sti.Buf[7] = (sti.Buf[0]-var_10004[w+b])? 1:0
8E var:FF5C 403DAA w = var_10004[sti.pc++2];sti.Buf[7] = (sti.Buf[1]-var_10004[w])? 1:0
8F var:FF58 403E01 w = var_10004[sti.pc++2];b = sti.Buf[2];sti.Buf[7] = (sti.Buf[1]-var_10004[w+b])? 1:0
90 var:FF54 403E63 w = var_10004[sti.pc++2];sti.Buf[7] = (sti.Buf[2]-var_10004[w])? 1:0
91 var:FF50 403EBA w = var_10004[sti.pc++2];b = sti.Buf[1];sti.Buf[7] = (sti.Buf[2]-var_10004[w+b])? 1:0
92 var:FF4C 403F1C w = var_10004[sti.pc++2];sti.Buf[7] = (var_10004[w]-sti.Buf[0])? 1:0
93 var:FF48 403F72 w = var_10004[sti.pc++2];b = sti.Buf[1];sti.Buf[7] = (var_10004[w+b]-sti.Buf[0])? 1:0
94 var:FF44 403FD3 w = var_10004[sti.pc++2];b = sti.Buf[2];sti.Buf[7] = (var_10004[w+b]-sti.Buf[0])? 1:0
95 var:FF40 404034 w = var_10004[sti.pc++2];sti.Buf[7] = (var_10004[w]-sti.Buf[1])? 1:0
96 var:FF3C 40408B w = var_10004[sti.pc++2];b = sti.Buf[2];sti.Buf[7] = (var_10004[w+b]-sti.Buf[1])? 1:0
97 var:FF38 4040ED w = var_10004[sti.pc++2];sti.Buf[7] = (var_10004[w]-sti.Buf[2])? 1:0
98 var:FF34 404144 w = var_10004[sti.pc++2];b = sti.Buf[1];sti.Buf[7] = (var_10004[w+b]-sti.Buf[2])? 1:0
99 var:FF30 4041A3 MessageBoxA(hWnd,"Success!","Success!",0)
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
赞赏
- [原创] KCTF 2022 Win. 第六题 约束与伪随机 6745
- [原创] KCTF 2021 Win. 第二题 排排坐 21174
- [原创] KCTF 2021 Win. 第一题 算力与攻击模式 4118
- 鸿蒙通识 26029
- [原创] KCTF 2021 Spr. 第二题 未选择的路 9249