第七节 Vmprotect中JMP和CMP的实现
对Vmprotect的jmp和cmp其实我并没有彻底搞懂,半看半猜,肯定有错误,请大家用怀疑的目光来看本节,希望有朋友给些提示和指出错误。
继续上节的分析。回顾一下上节的Jmp文件内容如下:
第0000次跳转,跳转到:0x00432285(VMInsBuff_00)
第0001次跳转,跳转到:0x004321AA(VMInsBuff_01)
第0002次跳转,跳转到:0x00432285(VMInsBuff_00)
第0003次跳转,跳转到:0x004322F8(VMInsBuff_03)
共有3个伪指令块,其中VMInsBuff_00被执行了两次,先来看一下它完成了什么。
一、VMInsBuff_00(VMB_dispatcher)
将该代码块使用伪指令宏简化表示:
00000000:[00000000][ ][ ]{00432285->95 0c }[ ][ ][ ]|0004|VM_POP_CT
00000001:[00000001][ ][ ]{00432287->d0 0a }[ ][ ][ ]|0008|VM_POP_CT
00000002:[7ffde000][ ][ ]{00432289->d0 0e }[ ][ ][ ]|0012|VM_POP_CT
00000003:[cccccccc][ ][ ]{0043228B->95 05 }[ ][ ][ ]|0016|VM_POP_CT
00000004:[0012fe04][ ][ ]{0043228D->95 0d }[ ][ ][ ]|0020|VM_POP_CT
00000005:[00000212][ ][ ]{0043228F->95 02 }[ ][ ][ ]|0024|VM_POP_CT
00000006:[0012fe04][ ][ ]{00432291->d0 06 }[ ][ ][ ]|0028|VM_POP_CT
00000007:[00429500][ ][ ]{00432293->d0 07 }[ ][ ][ ]|0032|VM_POP_CT
00000008:[771a3dbf][ ][ ]{00432295->95 04 }[ ][ ][ ]|0036|VM_POP_CT
00000009:[771a3dbf][ ][ ]{00432297->95 0b }[ ][ ][ ]|0040|VM_POP_CT
00000010:[00432285][ ][ ]{00432299->95 01 }[ ][ ][ ]|0044|VM_POP_CT
VMM_POP_CT 11(C,A,E,5,D,2,6,7,4,B,1)
00000011:[ ][ ][ ]{0043229B->37 }[0012fd28][ ][ ]|0040|VM_PUSH_ESP
00000012:[0012fd28][ ][ ]{0043229C->61 }[2ef761c2][ ][ ]|0040|VM_MOV_B_SSA
00000013:[2ef761c2][2ef761c2][ ]{0043229D->10 }[d1089e3d][ ][ ]|0044|VM_NOR
VMM_NOT [esp](2ef761c2)= d1089e3d
00000014:[ ][ ][ ]{0043229E->8b e199c1f4}[e199c1f4][ ][ ]|0040|VM_PUSH_IMM
00000015:[e199c1f4][d1089e3d][ ]{004322A3->12 }[b2a26031][ ][ ]|0044|VM_ADD
00000016:[b2a26031][ ][ ]{004322A4->95 03 }[ ][ ][ ]|0048|VM_POP_CT
VMM_ADD e199c1f4,[esp]( d1089e3d)= b2a26031
VMM_POP CT03(b2a26031)
00000017:[ ][ ][ ]{004322A6->3e 14 }[ 0014][ ][ ]|0046|VM_PUSHW_IMMB
00000018:[ ][ ][ ]{004322A8->79 03 }[b2a26031][ ][ ]|0042|VM_PUSH_CT
00000019:[ ][ ][ ]{004322AA->79 03 }[b2a26031][ ][ ]|0038|VM_PUSH_CT
00000020:[b2a26031][b2a26031][ 0014]{004322AC->f2 }[ 0202][031b2a26][ ]|0042|VM_SHLD_F
00000021:[ 0202][ ][ ]{004322AD->5a 00 }[ ][ ][ ]|0044|VM_POPW_CTW
VMM_SHLD_F CT03(b2a26031),0014h=031b2a26
VMM_POPFW_CT00W
00000022:[ ][ ][ ]{004322AF->8b a70618da}[a70618da][ ][ ]|0040|VM_PUSH_IMM
00000023:[a70618da][031b2a26][ ]{004322B4->12 }[aa214300][ ][ ]|0044|VM_ADD
VMM_ADD a70618da, [esp]031b2a26= aa214300
00000024:[ ][ ][ ]{004322B5->37 }[0012fd28][ ][ ]|0040|VM_PUSH_ESP
00000025:[0012fd28][ ][ ]{004322B6->61 }[aa214300][ ][ ]|0040|VM_MOV_B_SSA
00000026:[aa214300][aa214300][ ]{004322B7->10 }[55debcff][ ][ ]|0044|VM_NOR
VMM_NOT [esp] aa214300=55debcff
00000027:[ ][ ][ ]{004322B8->1f 01 }[00000001][ ][ ]|0040|VM_PUSH_IMMB
00000028:[00000001][55debcff][ ]{004322BA->12 }[55debd00][ ][ ]|0044|VM_ADD
00000029:[ ][ ][ ]{004322BB->1f ff }[ffffffff][ ][ ]|0040|VM_PUSH_IMMB
00000030:[ffffffff][55debd00][ ]{004322BD->12 }[55debcff][ ][ ]|0044|VM_ADD
VMM_NOP=VMM_INC,VMM_DEC
00000031:[55debcff][ ][ ]{004322BE->95 03 }[ ][ ][ ]|0048|VM_POP_CT
VMM_POP CT03(55debcff)
00000032:[ ][ ][ ]{004322C0->3e 08 }[ 0008][ ][ ]|0046|VM_PUSHW_IMMB
00000033:[ ][ ][ ]{004322C2->79 03 }[55debcff][ ][ ]|0042|VM_PUSH_CT
00000034:[ bcff][ ][ ]{004322C4->2a }[ ][ ][ ]|0044|VM_POPW_DX
00000035:[ ][ ][ ]{004322C5->37 }[0012fd28][ ][ ]|0040|VM_PUSH_ESP
00000036:[0012fd28][ ][ ]{004322C6->d6 }[ 55de][ ][ ]|0042|VM_MOVW_B_SSA
00000037:[ 55de][ 55de][ 0008]{004322C7->4b }[de55de00][ ][ ]|0044|VM_SHL
00000038:[ ][ ][ ]{004322C8->3e 08 }[ 0008][ ][ ]|0042|VM_PUSHW_IMMB
00000039:[ ][ ][ ]{004322CA->01 03 }[ bcff][ ][ ]|0040|VM_PUSHW_CTW
00000040:[ ][ ][ ]{004322CC->01 03 }[ bcff][ ][ ]|0038|VM_PUSHW_CTW
00000041:[ bcff][ bcff][ 0008]{004322CE->4b }[ffbcff00][ ][ ]|0040|VM_SHL
00000042:[ ff00][ ][ ]{004322CF->2a }[ ][ ][ ]|0042|VM_POPW_DX
00000043:[ ][ ][ ]{004322D0->37 }[0012fd26][ ][ ]|0038|VM_PUSH_ESP
00000044:[ ][ ][ ]{004322D1->1f 04 }[00000004][ ][ ]|0034|VM_PUSH_IMMB
00000045:[00000004][0012fd26][ ]{004322D3->12 }[0012fd2a][ ][ ]|0038|VM_ADD
00000046:[0012fd2a][ ][ ]{004322D4->d6 }[ de55][ ][ ]|0040|VM_MOVW_B_SSA
00000047:[ffbcde55][ ][ ]{004322D5->d0 03 }[ ][ ][ ]|0044|VM_POP_CT
VMM_BSWAP CT03(55debcff)= ffbcde55
00000048:[de55de00][ ][ ]{004322D7->48 }[ ][ ][ ]|0048|VM_POP_ECX
VMM_POP ECX (de55de00)
00000049:[ ][ ][ ]{004322D8->79 03 }[ffbcde55][ ][ ]|0044|VM_PUSH_CT
00000050:[ ][ ][ ]{004322DA->37 }[0012fd28][ ][ ]|0040|VM_PUSH_ESP
00000051:[0012fd28][ ][ ]{004322DB->61 }[ffbcde55][ ][ ]|0040|VM_MOV_B_SSA
00000052:[ffbcde55][ffbcde55][ ]{004322DC->10 }[004321aa][ ][ ]|0044|VM_NOR
00000053:[004321aa][ ][ ]{004322DD->d0 03 }[ ][ ][ ]|0048|VM_POP_CT
VMM_NOT CT03(ffbcde55)= 004321aa
00000054:[ ][ ][ ]{004322DF->79 06 }[0012fe04][ ][ ]|0044|VM_PUSH_CT
00000055:[ ][ ][ ]{004322E1->79 0b }[771a3dbf][ ][ ]|0040|VM_PUSH_CT
00000056:[ ][ ][ ]{004322E3->79 04 }[771a3dbf][ ][ ]|0036|VM_PUSH_CT
00000057:[ ][ ][ ]{004322E5->79 07 }[00429500][ ][ ]|0032|VM_PUSH_CT
00000058:[ ][ ][ ]{004322E7->79 06 }[0012fe04][ ][ ]|0028|VM_PUSH_CT
00000059:[ ][ ][ ]{004322E9->79 02 }[00000212][ ][ ]|0024|VM_PUSH_CT
00000060:[ ][ ][ ]{004322EB->79 0d }[0012fe04][ ][ ]|0020|VM_PUSH_CT
00000061:[ ][ ][ ]{004322ED->79 05 }[cccccccc][ ][ ]|0016|VM_PUSH_CT
00000062:[ ][ ][ ]{004322EF->79 0e }[7ffde000][ ][ ]|0012|VM_PUSH_CT
00000063:[ ][ ][ ]{004322F1->79 0a }[00000001][ ][ ]|0008|VM_PUSH_CT
00000064:[ ][ ][ ]{004322F3->79 0c }[00000000][ ][ ]|0004|VM_PUSH_CT
VMM_PUSH_CT 11(6,B,4,7,6,2,D,5,E,A,C)
00000065:[ ][ ][ ]{004322F5->79 03 }[004321aa][ ][ ]|0000|VM_PUSH_CT
00000066:[ ][ ][ ]{004322F7->1c }[ ][ ][ ]|0004|VM_JMP
VMM_JMP CT03
同样,我们把伪指令宏摘出来,结果如下:
VMM_POP_CT 11(C,A,E,5,D,2,6,7,4,B,1)
VMM_NOT [esp](2ef761c2)= d1089e3d
VMM_ADD e199c1f4,[esp]( d1089e3d)= b2a26031
VMM_POP CT03(b2a26031)
VMM_SHLD_F CT03(b2a26031),0014h=031b2a26
VMM_POPFW_CT00W
VMM_ADD a70618da, [esp]031b2a26= aa214300
VMM_NOT [esp] aa214300=55debcff
VMM_POP CT03(55debcff)
VMM_BSWAP CT03(55debcff)= ffbcde55
VMM_POP ECX (de55de00)
VMM_NOT CT03(ffbcde55)= 004321aa
VMM_PUSH_CT 11(6,B,4,7,6,2,D,5,E,A,C)
VMM_JMP CT03
首先我们看一下CT03这个位置,它是VM_Context这个结构的第三个字节,仔细观察发现,它像是个临时寄存器,用于保存中间数据。
再看一下第二个伪指令宏的输入参数2ef761c2,这是进入虚拟机引擎时,压入栈的第一个参数,我把它成为虚拟机入口参数,(参看第一节的虚拟机框架图示)。可以把它看作是把开启虚拟机引擎的点火器。
最后看一下最后一句VMM_JMP,它的跳转地址是CT03里面的数据。
整个伪指令块VMInsBuff_00简单分析一下,可以看出,它完成的就是对入口参数进行一次变换,生成一个地址,以便VMM_JMP调用。如果这个伪指令块看作一个函数,那么它的输入参数就是2ef761c2,返回值是004321aa。所以我猜测,这是个地址解密功能块,它只起到一个控制程序流向的作用,可以视为一个调度功能模块,我把它叫做VMB_dipatcher。
再看一下第二次进入这个伪指令块的那部分代码,验证了上面的猜测,此时它的输入参数是1ef75ce2,返回值是004322f8。
这样,我们可以把这两个块也咔嚓掉(我们暂不管它是如何实现解密变换的,因为每次不同的加密都有些不同,只要知道其输入输出就好了),用两个伪指令块助记符分别表示为:
[00000000-00000066]:VMB_dipatcher(2ef761c2)= 004321aa
[00000065-00000065]:VMM_JMP CT03(004321aa)
……
[00000196-00000260]:VMB_dipatcher(1ef75ce2)= 004322f8
[00000261-00000262]:VMM_JMP CT03(004322f8)
二、VMInsBuff_01(cmp和jmp)
因为我们已经分析了V MInsBuff_00, VMInsBuff_03,只差VMInsBuff_01这个伪指令块了。而我们未识别的代码只有下面这两句没有找到了:
// if(v>50)
00411A53 837D0832 cmp dword ptr [ebp+08], 32
00411A57 7E0A jle 00411A63
使用排除法,它们必定隐藏在VMInsBuff_01中。事实上我不是看出来的,是这样猜出来的,因为里面的一些标志位的复杂的逻辑运算我没大看懂。
我们使用同样的伪指令宏替代的方法,来看下这个代码块:
00000067:[00000000][ ][ ]{004321AA->d0 0c }[ ][ ][ ]|0008|VM_POP_CT
00000068:[00000001][ ][ ]{004321AC->95 0a }[ ][ ][ ]|0012|VM_POP_CT
00000069:[7ffde000][ ][ ]{004321AE->d0 0e }[ ][ ][ ]|0016|VM_POP_CT
00000070:[cccccccc][ ][ ]{004321B0->95 05 }[ ][ ][ ]|0020|VM_POP_CT
00000071:[0012fe04][ ][ ]{004321B2->d0 0d }[ ][ ][ ]|0024|VM_POP_CT
00000072:[00000212][ ][ ]{004321B4->d0 02 }[ ][ ][ ]|0028|VM_POP_CT
00000073:[0012fe04][ ][ ]{004321B6->d0 06 }[ ][ ][ ]|0032|VM_POP_CT
00000074:[00429500][ ][ ]{004321B8->95 07 }[ ][ ][ ]|0036|VM_POP_CT
00000075:[771a3dbf][ ][ ]{004321BA->d0 04 }[ ][ ][ ]|0040|VM_POP_CT
00000076:[771a3dbf][ ][ ]{004321BC->95 0b }[ ][ ][ ]|0044|VM_POP_CT
00000077:[0012fe04][ ][ ]{004321BE->d0 00 }[ ][ ][ ]|0048|VM_POP_CT
VMM_POP_CT 11(C,A,E,5,D,2,6,7,4,B,0)
00000078:[ ][ ][ ]{004321C0->1f 32 }[00000032][ ][ ]|0044|VM_PUSH_IMMB
VMM_PUSH 00000032
00000079:[ ][ ][ ]{004321C2->79 06 }[0012fe04][ ][ ]|0040|VM_PUSH_CT
00000080:[ ][ ][ ]{004321C4->1f 08 }[00000008][ ][ ]|0036|VM_PUSH_IMMB
00000081:[00000008][0012fe04][ ]{004321C6->12 }[0012fe0c][ ][ ]|0040|VM_ADD
VMM_ADD 08h,CT06(0012fe04)= 0012fe0c
00000082:[0012fe0c][ ][ ]{004321C7->61 }[0000000a][ ][ ]|0040|VM_MOV_B_SSA
VMM_PUSH [CT06+08h](0012fe0c)
00000083:[ ][ ][ ]{004321C8->37 }[0012fd24][ ][ ]|0036|VM_PUSH_ESP
00000084:[0012fd24][ ][ ]{004321C9->61 }[0000000a][ ][ ]|0036|VM_MOV_B_SSA
00000085:[0000000a][0000000a][ ]{004321CA->10 }[fffffff5][ ][ ]|0040|VM_NOR
VMM_NOT [CT06+08H] (0000000a)= fffffff5
00000086:[fffffff5][00000032][ ]{004321CB->b6 }[ 0207][00000027][ ]|0042|VM_ADD_F
VMM_SUB 00000032, [CT06+08H](0000000a)=00000027,FLAG=0207
00000087:[ ][ ][ ]{004321CC->4e fbff }[ fbff][ ][ ]|0040|VM_PUSHW_IMMW
00000088:[ ][ ][ ]{004321CF->01 02 }[ 0212][ ][ ]|0038|VM_PUSHW_CTW
00000089:[ ][ ][ ]{004321D1->37 }[0012fd22][ ][ ]|0034|VM_PUSH_ESP
00000090:[0012fd22][ ][ ]{004321D2->d6 }[ 0212][ ][ ]|0036|VM_MOVW_B_SSA
00000091:[ 0212][ 0212][ ]{004321D3->5b }[ fded][ ][ ]|0038|VM_NORW
00000092:[ fded][ fbff][ ]{004321D4->5b }[ 0000][ ][ ]|0040|VM_NORW
VMM_AND CTW02(0212),0400(DF)=0000;获得原DF标志位
00000093:[ 0000][ 0207][ ]{004321D5->7d }[ 0207][ ][ ]|0042|VM_ADDW
VMM_ADD 0207,0000=0207
00000094:[ 0207][ ][ ]{004321D6->5a 02 }[ ][ ][ ]|0044|VM_POPW_CTW
VMM_POPW_CT02W(0207)
00000095:[ ][ ][ ]{004321D8->37 }[0012fd28][ ][ ]|0040|VM_PUSH_ESP
00000096:[0012fd28][ ][ ]{004321D9->61 }[00000027][ ][ ]|0040|VM_MOV_B_SSA
00000097:[00000027][00000027][ ]{004321DA->c8 }[ 0286][ffffffd8][ ]|0042|VM_NOR_F
VMM_NOT [esp](00000027)= ffffffd8,FLAG=0286
00000098:[ ][ ][ ]{004321DB->37 }[0012fd26][ ][ ]|0038|VM_PUSH_ESP
00000099:[0012fd26][ ][ ]{004321DC->d6 }[ 0286][ ][ ]|0040|VM_MOVW_B_SSA
00000100:[ 0286][ 0286][ ]{004321DD->5b }[ fd79][ ][ ]|0042|VM_NORW
VMM_NOTW W[esp](0286)=fd79
00000101:[ ][ ][ ]{004321DE->4e 0815 }[ 0815][ ][ ]|0040|VM_PUSHW_IMMW
00000102:[ 0815][ fd79][ ]{004321E1->5b }[ 0282][ ][ ]|0042|VM_NORW
VMM_AND f7ea,286=0282(maskout OF,AF,PF,CF)
00000103:[ ][ ][ ]{004321E2->01 02 }[ 0207][ ][ ]|0040|VM_PUSHW_CTW
00000104:[ ][ ][ ]{004321E4->01 02 }[ 0207][ ][ ]|0038|VM_PUSHW_CTW
00000105:[ 0207][ 0207][ ]{004321E6->5b }[ fdf8][ ][ ]|0040|VM_NORW
00000106:[ ][ ][ ]{004321E7->4e f3ea }[ f3ea][ ][ ]|0038|VM_PUSHW_IMMW
00000107:[ f3ea][ fdf8][ ]{004321EA->5b }[ 0005][ ][ ]|0040|VM_NORW
VMM_AND 0c15,0207=0005(mask OF,DF,AF,PF,CF)
00000108:[ 0005][ 0282][ ]{004321EB->7d }[ 0287][ ][ ]|0042|VM_ADDW
VMM_ADD 0005,0282=0287
00000109:[ 0287][ ][ ]{004321EC->5a 02 }[ ][ ][ ]|0044|VM_POPW_CTW
VMM_POPW_CT02W(0287);get VMM_SUB flags
00000110:[ffffffd8][ ][ ]{004321EE->48 }[ ][ ][ ]|0048|VM_POP_ECX
VMM_POP_ECX(ffffffd8);for stack balance?
00000111:[ ][ ][ ]{004321EF->8b 3ef75f22}[3ef75f22][ ][ ]|0044|VM_PUSH_IMM
00000112:[ ][ ][ ]{004321F4->8b 1ef75ce2}[1ef75ce2][ ][ ]|0040|VM_PUSH_IMM
VMM_PUSH 3ef75f22;加了密的跳转地址 jmpaddr0
VMM_PUSH 1ef75ce2;加了密的跳转地址jmpaddr1
00000113:[ ][ ][ ]{004321F9->01 02 }[ 0287][ ][ ]|0038|VM_PUSHW_CTW
00000114:[ ][ ][ ]{004321FB->01 02 }[ 0287][ ][ ]|0036|VM_PUSHW_CTW
00000115:[ 0287][ 0287][ ]{004321FD->5b }[ fd78][ ][ ]|0038|VM_NORW
VMM_NOTW CT02W(0287)=fd78
00000116:[ ][ ][ ]{004321FE->4e ff7f }[ ff7f][ ][ ]|0036|VM_PUSHW_IMMW
00000117:[ ff7f][ fd78][ ]{00432201->b8 }[ 0202][ 0080][ ]|0036|VM_NORW_F
VMM_AND_F CT02W(0287),0080(SF)=0080;取符号标志位
00000118:[ 0202][ ][ ]{00432202->b4 03 }[ ][ ][ ]|0038|VM_POPW_CTB0
VMM_POPW_CT03B0(0202);获取符号标志位时的FLAG
00000119:[ 0080][ ][ ]{00432204->2a }[ ][ ][ ]|0040|VM_POPW_DX
VMM_POPW_DX(0080) ;for stack balance?
00000120:[ ][ ][ ]{00432205->4e f7ff }[ f7ff][ ][ ]|0038|VM_PUSHW_IMMW
00000121:[ ][ ][ ]{00432208->01 02 }[ 0287][ ][ ]|0036|VM_PUSHW_CTW
00000122:[ ][ ][ ]{0043220A->01 02 }[ 0287][ ][ ]|0034|VM_PUSHW_CTW
00000123:[ 0287][ 0287][ ]{0043220C->5b }[ fd78][ ][ ]|0036|VM_NORW
00000124:[ fd78][ f7ff][ ]{0043220D->b8 }[ 0246][ 0000][ ]|0036|VM_NORW_F
VMM_ANDW_F 0287,0800(DF)=0000,flag=0246;取方向标志位,
00000125:[ 0246][ ][ ]{0043220E->31 03 }[ ][ ][ ]|0038|VM_POPW_CTB1
VMM_POPW_CT03B1(46);获取方向标志位时的FLAG
00000126:[ 0000][ ][ ]{00432210->5a 00 }[ ][ ][ ]|0040|VM_POPW_CTW
VMM_POPW_CT00W(0000);保存了方向标志位
00000127:[ ][ ][ ]{00432212->ef 03 }[ 0002][ ][ ]|0038|VM_PUSHW_CTB0
00000128:[ ][ ][ ]{00432214->cd 03 }[ 0046][ ][ ]|0036|VM_PUSHW_CTB1
00000129:[ 0046][ 0002][ ]{00432216->87 }[ 00b9][ ][ ]|0038|VM_NORB
VMM_NORB CT02B0(0002),CT02B1(0046)=00b9
00000130:[ ][ ][ ]{00432217->cd 03 }[ 0046][ ][ ]|0036|VM_PUSHW_CTB1
00000131:[ ][ ][ ]{00432219->cd 03 }[ 0046][ ][ ]|0034|VM_PUSHW_CTB1
00000132:[ 0046][ 0046][ ]{0043221B->71 }[ 00b9][ ][ ]|0036|VM_NORB
VMM_NOTB CT03B1(0046)=00b9
00000133:[ ][ ][ ]{0043221C->ef 03 }[ 0002][ ][ ]|0034|VM_PUSHW_CTB0
00000134:[ ][ ][ ]{0043221E->ef 03 }[ 0002][ ][ ]|0032|VM_PUSHW_CTB0
00000135:[ 0002][ 0002][ ]{00432220->71 }[ 00fd][ ][ ]|0034|VM_NORB
VMM_NOTB CT03B0(0002)=00fd
00000136:[ 00fd][ 00b9][ ]{00432221->71 }[ 0002][ ][ ]|0036|VM_NORB
VMM_ANDB CT03B1,CT03B0=0002
00000137:[ 0002][ 00b9][ ]{00432222->87 }[ 0044][ ][ ]|0038|VM_NORB
VMM_XORB CT03B1(46),CT03B0(02)=0044(ZF,PF)
00000138:[ ][ ][ ]{00432223->37 }[0012fd22][ ][ ]|0034|VM_PUSH_ESP
00000139:[0012fd22][ ][ ]{00432224->f8 }[ 44][ ][ ]|0036|VM_MOVB_B_SSA
00000140:[ 0044][ ][ ]{00432225->b4 03 }[ ][ ][ ]|0038|VM_POPW_CTB0
VMM_MOV CT03B0,[esp](0044)
00000141:[ ][ ][ ]{00432227->37 }[0012fd22][ ][ ]|0034|VM_PUSH_ESP
00000142:[0012fd22][ ][ ]{00432228->f8 }[ 44][ ][ ]|0036|VM_MOVB_B_SSA
00000143:[ 0044][ 0044][ ]{00432229->87 }[ 00bb][ ][ ]|0038|VM_NORB
VMM_NOTB B[esp](44)=00bb
00000144:[ 00bb][ ][ ]{0043222A->b4 03 }[ ][ ][ ]|0040|VM_POPW_CTB0
VMM_POPW_CT03B0(00bb)
00000145:[ ][ ][ ]{0043222C->01 02 }[ 0287][ ][ ]|0038|VM_PUSHW_CTW
00000146:[ ][ ][ ]{0043222E->37 }[0012fd22][ ][ ]|0034|VM_PUSH_ESP
00000147:[0012fd22][ ][ ]{0043222F->d6 }[ 0287][ ][ ]|0036|VM_MOVW_B_SSA
00000148:[ 0287][ 0287][ ]{00432230->5b }[ fd78][ ][ ]|0038|VM_NORW
VMM_NOT CT02W(0287)=fd78
00000149:[ ][ ][ ]{00432231->4e ffbf }[ ffbf][ ][ ]|0036|VM_PUSHW_IMMW
00000150:[ ffbf][ fd78][ ]{00432234->b8 }[ 0246][ 0000][ ]|0036|VM_NORW_F
VMM_AND 0287,0040(PF)=0000;取奇偶标志位,
00000151:[ 0246][ ][ ]{00432235->31 03 }[ ][ ][ ]|0038|VM_POPW_CTB1
VMM_POPW_CT03B1(0246) ;取奇偶标志位的flag
00000152:[ 0000][ ][ ]{00432237->5a 00 }[ ][ ][ ]|0040|VM_POPW_CTW
VMM_POPW_CT00W(0000);保存奇偶标志位结果到CT00W
00000153:[ ][ ][ ]{00432239->51 bb }[ 00bb][ ][ ]|0038|VM_PUSHW_CTB0
VMM_PUSHW_CT03B0(00bb)
00000154:[ ][ ][ ]{0043223B->37 }[0012fd22][ ][ ]|0034|VM_PUSH_ESP
00000155:[0012fd22][ ][ ]{0043223C->f8 }[ bb][ ][ ]|0036|VM_MOVB_B_SSA
00000156:[ 00bb][ 00bb][ ]{0043223D->87 }[ 0044][ ][ ]|0038|VM_NORB
VMM_NOT CT03B0(00bb)=0044
00000157:[ ][ ][ ]{0043223E->cd 03 }[ 0046][ ][ ]|0036|VM_PUSHW_CTB1
00000158:[ ][ ][ ]{00432240->cd 03 }[ 0046][ ][ ]|0034|VM_PUSHW_CTB1
00000159:[ 0046][ 0046][ ]{00432242->71 }[ 00b9][ ][ ]|0036|VM_NORB
VMM_NOT CT03B1(0046)=00b9
00000160:[ 00b9][ 0044][ ]{00432243->87 }[ 0002][ ][ ]|0038|VM_NORB
VMM_ANDB CT03B0(00bb),CT03B1(0046)=0002
00000161:[ 0002][ ][ ]{00432244->b4 03 }[ ][ ][ ]|0040|VM_POPW_CTB0
VMM_POPW_CT03B0=0002
00000162:[ ][ ][ ]{00432246->4e ffbf }[ ffbf][ ][ ]|0038|VM_PUSHW_IMMW
00000163:[ ][ ][ ]{00432249->01 03 }[ 4602][ ][ ]|0036|VM_PUSHW_CTW
00000164:[ ][ ][ ]{0043224B->01 03 }[ 4602][ ][ ]|0034|VM_PUSHW_CTW
00000165:[ 4602][ 4602][ ]{0043224D->5b }[ b9fd][ ][ ]|0036|VM_NORW
VMM_NOTW CT03W(4602)=b9fd
00000166:[ b9fd][ ffbf][ ]{0043224E->5b }[ 0000][ ][ ]|0038|VM_NORW
VMM_ANDW CT03W(4602),0040(PF)=0000
00000167:[ 0000][ ][ ]{0043224F->5a 03 }[ ][ ][ ]|0040|VM_POPW_CTW
VMM_POPW_CT03W(0000)
00000168:[ ][ ][ ]{00432251->3e 04 }[ 0004][ ][ ]|0038|VM_PUSHW_IMMB
00000169:[ ][ ][ ]{00432253->01 03 }[ 0000][ ][ ]|0036|VM_PUSHW_CTW
00000170:[ 00][ 00][ 0004]{00432255->44 }[ 0000][ ][ ]|0038|VM_SHRW
00000171:[ 0000][ ][ ]{00432256->5a 03 }[ ][ ][ ]|0040|VM_POPW_CTW
VMM_SHRW CT03W(0000),0004=0000
00000172:[ ][ ][ ]{00432258->37 }[0012fd24][ ][ ]|0036|VM_PUSH_ESP
00000173:[ ][ ][ ]{00432259->3e 00 }[ 0000][ ][ ]|0034|VM_PUSHW_IMMB
00000174:[ ][ ][ ]{0043225B->01 03 }[ 0000][ ][ ]|0032|VM_PUSHW_CTW
00000175:[00000000][0012fd24][ ]{0043225D->12 }[0012fd24][ ][ ]|0036|VM_ADD
VMM_ADD esp,(CT03W,0000)= 0012fd24
00000176:[0012fd24][ ][ ]{0043225E->61 }[1ef75ce2][ ][ ]|0036|VM_MOV_B_SSA
VMM_PUSH [esp+CT03W,0000]=VMM_PUSH_SSA(1ef75ce2)
00000177:[1ef75ce2][ ][ ]{0043225F->95 03 }[ ][ ][ ]|0040|VM_POP_CT
VMM_POP_CT03(1ef75ce2)
00000178:[1ef75ce2][ ][ ]{00432261->48 }[ ][ ][ ]|0044|VM_POP_ECX
VMM_POP_ECX(1ef75ce2)
00000179:[3ef75f22][ ][ ]{00432262->d0 00 }[ ][ ][ ]|0048|VM_POP_CT
VMM_POP_CT00(3ef75f22)
00000180:[ ][ ][ ]{00432264->79 03 }[1ef75ce2][ ][ ]|0044|VM_PUSH_CT
VMM_PUSH_CT03(1ef75ce2)
00000181:[ ][ ][ ]{00432266->8b 00432285}[00432285][ ][ ]|0040|VM_PUSH_IMM
00000182:[00432285][ ][ ]{0043226B->d0 04 }[ ][ ][ ]|0044|VM_POP_CT
VMM_MOV CT04, 00432285;VMM_dipather
00000183:[ ][ ][ ]{0043226D->79 06 }[0012fe04][ ][ ]|0040|VM_PUSH_CT
00000184:[ ][ ][ ]{0043226F->79 0b }[771a3dbf][ ][ ]|0036|VM_PUSH_CT
00000185:[ ][ ][ ]{00432271->79 05 }[cccccccc][ ][ ]|0032|VM_PUSH_CT
00000186:[ ][ ][ ]{00432273->79 0e }[7ffde000][ ][ ]|0028|VM_PUSH_CT
00000187:[ ][ ][ ]{00432275->79 0a }[00000001][ ][ ]|0024|VM_PUSH_CT
00000188:[ ][ ][ ]{00432277->79 02 }[00000287][ ][ ]|0020|VM_PUSH_CT
00000189:[ ][ ][ ]{00432279->79 0d }[0012fe04][ ][ ]|0016|VM_PUSH_CT
00000190:[ ][ ][ ]{0043227B->37 }[0012fd0c][ ][ ]|0012|VM_PUSH_ESP
00000191:[ ][ ][ ]{0043227C->79 07 }[00429500][ ][ ]|0008|VM_PUSH_CT
00000192:[ ][ ][ ]{0043227E->79 06 }[0012fe04][ ][ ]|0004|VM_PUSH_CT
00000193:[ ][ ][ ]{00432280->79 0c }[00000000][ ][ ]|0000|VM_PUSH_CT
VMM_PUSH_CT 11(6,B,5,E,A,2,D,ESP,7,6,C)
00000194:[ ][ ][ ]{00432282->79 04 }[00432285][ ][ ]|-004|VM_PUSH_CT
00000195:[ ][ ][ ]{00432284->1c }[ ][ ][ ]|0000|VM_JMP
VMM_JMP CT04(00432285)
同样把简化完成的伪指令宏摘录出来,结果如下,为便于说明,我给每个宏编了序号:
1 VMM_POP_CT 11(C,A,E,5,D,2,6,7,4,B,0)
2 VMM_SUB 32, [CT06+08H](0a)=27 ;FLAG=0207
3 VMM_AND CTW02(0212),0400(DF)=0000 ;获得原DF标志位
4 VMM_ADD 0207,0000=0207
5 VMM_POPW_CT02W(0207)
6 VMM_NOT [esp](00000027)= ffffffd8 ;FLAG=0286
7 VMM_AND f7ea,286=0282 ;maskout OF,AF,PF,CF
8 VMM_AND 0c15,0207=0005 ;mask OF,DF,AF,PF,CF
9 VMM_POPW_CT02W(0287) ;get VMM_SUB flags
10 VMM_PUSH 3ef75f22 ;加了密的跳转地址 jmpaddr0
11 VMM_PUSH 1ef75ce2 ;加了密的跳转地址jmpaddr1
12 VMM_AND_F CT02W(0287),0080(SF)=0080 ;取符号标志位
13 VMM_POPW_CT03B0(0202) ;获取符号标志位时的FLAG
14 VMM_ANDW_F 0287,0800(DF)=0000,flag=0246 ;取方向标志位,
15 VMM_POPW_CT03B1(46) ;获取方向标志位时的FLAG
16 VMM_POPW_CT00W(0000) ;保存了方向标志位
17 VMM_XORB CT03B1(46),CT03B0(02)=0044 ;(ZF,PF)
18 VMM_MOV CT03B0,[esp](0044)
19 VMM_NOTB B[esp](44)=00bb
20 VMM_POPW_CT03B0(00bb)
21 VMM_AND 0287,0040(PF)=0000 ;取奇偶标志位,
22 VMM_POPW_CT03B1(0246) ;取奇偶标志位的flag
23 VMM_POPW_CT00W(0000) ;保存奇偶标志位结果到CT00W
24 VMM_ANDB CT03B0(00bb),CT03B1(0046)=0002
25 VMM_POPW_CT03B0=0002
26 VMM_ANDW CT03W(4602),0040(PF)=0000
27 VMM_POPW_CT03W(0000)
28 VMM_SHRW CT03W(0000),0004=0000
29 VMM_PUSH [esp+CT03W,0000] ;=VMM_PUSH_SSA(1ef75ce2)
30 VMM_POP_CT03(1ef75ce2)
31 VMM_POP_ECX(1ef75ce2)
32 VMM_POP_CT00(3ef75f22)
33 VMM_PUSH_CT03(1ef75ce2)
34 VMM_MOV CT04, 00432285;VMB_dispatcher
35 VMM_PUSH_CT 11(6,B,5,E,A,2,D,ESP,7,6,C)
36 VMM_JMP CT04(00432285) ;跳转到VMB_dispatcher
分析如下:
1、第2条是SUB 32h,[CT06+08H](0a)完成CMP功能,
2、3-9条获得CMP的标志位
3、10条和11条,分别是条件跳转两个分支的地址(加了密的,需使用VMB_dispatcher功能块解密处实际跳转地址)
4、12条到33条,根据前面生成的CMP标志位,在10和11条的两个地址中二选一,并将该地址压栈。
5、34-36调用VMB_dispatcher进行地址解密。
综上分析,可看出这里就是
00411A53 837D0832 cmp dword ptr [ebp+08], 32
00411A57 7E0A jle 00411A63
先看CMP的具体实现,它先使用VMM_SUB宏,然后生成该CMP的标志寄存器(有点复杂,只能看出大体生成方法,细节没搞懂),并保存到CONTEXT里。
条件跳转的实现,是根据标志位在两个跳转地址中二选一,然后送给地址解密功能块(VMB_dispatcher),再跳到相应伪指令块中。
在本例,我们的“伪指令记录插件”只能跟踪到进一个分支(bughoho提示),这是tracer的缺点。不过我们已经算是找到cmp和jmp了。如果想爆破,或是想使用插件跟踪到另一分支,控制程序的流向,可使用下面方法:
1、使用插件运行到VMM_SUB 32h, [CT06+08H](0a)处,修改寄存器的数值,比如修改32h为09h,或修改0ah为33h。
2、或是直接该跳转地址,将1ef75ce2这个压入栈的数据修改为3ef75f22,就可以了。
三、猜测
精力和能力有限,我没有跟踪太多的程序,做个猜测,希望大家帮忙验证:
VMB_dispather这个伪指令块控制程序的流向,通过jmp文件记录通常可以看出程序大致的流向,也基本可以确定哪些伪指令块是完成这个功能的,我想应该是那些最常出现的,位于多个伪指令块之首的那个。也可能是所有的第1,3,5….的伪指令块,也就是说可能每个具体的功能块之前都有这么一个VMB_dispatcher。
VMB_disaptcher内容不复杂,我跟了几个VMB_dispatcher内容大同小异同,如果真的如上猜测,可能爆破VMProtect就简单了。