一、个人对于VMP的理解
1、VMP在被保护代码的地址处将原bytecode抽走,并进入到自己的解释器中解释执行自定义的bytecode(虚拟bytecode)。
2、既然是解释执行虚拟bytecode,始终就应该围绕着取指--译码--执行,这个流程。
3、进入解释器,首先要找到2块最重要的内存,也可以理解为2个数组——虚拟bytecode数组和虚拟reg数组。
4、对取指--译码--执行的细化:
(1)取指:取操作码和操作数
(1.1)、虚拟PC =虚拟bytecode数组首地址+ bytecode_index*bytecode_type(虚拟PC的更新可以分为更新下标和更新指针——更新下标:先通过bytecode数组首地址+ bytecode_index*bytecode_type得到PC,再进行取指并通过instruction_length更新bytecode_index;更新指针:直接通过PC取指,取指后通过instruction_length直接更新PC)。
(1.2)、通过虚拟PC取出操作码和操作数(此过程可以在Handler内,也可以在Handler外)。
(2)译码:
(2.1)、通过操作码找到对应的Handler。
(2.2)、通过操作数(虚拟reg数组下标)找到对应的虚拟reg。
(2.3)、通过真实的指令对虚拟reg的行为进行模拟。
(3)执行:将结果赋值给虚拟reg。
二、根据取指--译码--执行的原理(其它的细节不去赘述),对5款VMP解释器的vm_add进行分析(本文都是静态分析,若有疏漏请指点):
1、lib_Easy.so ARM架构



(1)取指:取操作码和操作数
(1.1)、虚拟PC =虚拟bytecode数组首地址+ bytecode_index*bytecode_type:

此处X5为虚拟PC

此处X8为虚拟PC
(1.2)、通过虚拟PC取出操作码和操作数:

此处X8为操作码1

此处X9为操作码2

此处
W9为操作数1
W10为操作数2
W11为操作数3
(2)译码:
(2.1)、通过操作码找到对应的Handler:

此处X8为Handler_xxx_reg1_reg2地址

此处X8为Handler_vm_add地址
(2.2)、通过操作数(虚拟reg数组下标)找到对应的虚拟reg:


此处
通过操作数1(W9)找到VM_REG1
通过操作数2(W10)找到VM_REG2
通过操作数3(W11)找到VM_REG3
(2.3)、通过真实的指令对虚拟reg的行为进行模拟:

此处ADD X9, X10, X9 即X9= VM_REG1 + VM_REG2
(3)执行:将结果赋值给虚拟reg:

此处VM_REG3 = X9。
总结:此虚拟机在Handler外取操作码1(X8),通过X8找到Handler_xxx_reg1_reg2,在Handler_xxx_reg1_reg2内取操作码2(X9),通过X9找到Handler_vm_add;在Handler内取操作码X9,通过操作码X9找到下一个Handler,并在Handler内更新PC,PC=PC+4(instruction_length为4)。
2、libsgmainso-6.7.250421.so ARM架构


地址0x000000000017E1D8为vm_add的Handler。
(1)取指:取操作码和操作数
(1.1)、虚拟PC =虚拟bytecode数组首地址+ bytecode_index*bytecode_type:
在地址0x000000000017E19C处X21为虚拟PC
(1.2)、通过虚拟PC取出操作码和操作数:
在地址0x000000000017E1A0处W0为操作码
在地址0x000000000017E1D8处W11为操作数1
在地址0x000000000017E1E0处W12为操作数2
在地址0x000000000017E1EC处W16为操作数3
(2)译码:
(2.1)、通过操作码找到对应的Handler:
在地址0x000000000017E1A4处通过X1找到对应的handler
(2.2)、通过操作数(虚拟reg数组下标)找到对应的虚拟reg:
在地址0x000000000017E1DC处通过操作数1找到VM_REG1
在地址0x000000000017E1E4处通过操作数2找到VM_REG2
在地址0x000000000017E1F0处通过操作数3找到VM_REG3
(2.3)、通过真实的指令对虚拟reg的行为进行模拟:
在地址0x000000000017E1E8处ADD X15, X13, X14即
X15 = VM_REG1 + VM_REG2
(3)执行:将结果赋值给虚拟reg:
在地址0x000000000017E1F0处VM_REG3 = X15 。
总结:此虚拟机第一次在Handler外取操作码,在Handler内取操作数;在Handler内地址0x000000000017E1F4处取出操作码W17,准备通过W17找到下一个Handler,并在地址0x000000000017E1F4同时更新PC,PC=PC+0x10(instruction_length为0x10)。
3、libmtguard.so ARM架构




地址0x0000000000138BA4开始向后都是vm_add的Handler。
(1)取指:取操作码和操作数
(1.1)、虚拟PC =虚拟bytecode数组首地址+ bytecode_index*bytecode_type:
在地址0x000000000013A5A4处X24为虚拟PC(bytecode_index为0)
[培训]传播安全知识、拓宽行业人脉——看雪讲师团队等你加入!