先简单说一下 vm逆向题。vm是什么?
原本的指令用另一种方式实现。比如我看到哪个特征,我就去执行那部分的内容,而这部分的内容会对应一条指令。大致便是这样的意思。无限套娃。
先讲一道相对简单的题目 WxyVM1
根据 switch case到的值:v0是决定操作方式;result决定操作输入的哪位;v3决定进行运算的值。
这道题目有大佬已经说得挺详细的了。
!通过idapython直接写的脚本读取的地址,学习。!
__int64 sub_4005B6()
{
unsigned int v0; // ST04_4
__int64 result; // rax
signed int i; // [rsp+0h] [rbp-10h]
char v3; // [rsp+8h] [rbp-8h]
for ( i = 0; i <= 14999; i += 3 )
{
v0 = byte_6010C0[i]; // 循环上每次加3,取到的值包括 1 2 3.用脚本取值,再用脚本判断这么多值里有哪些 发现是 123
v3 = byte_6010C0[i + 2];
result = v0; // 指示运算方式
switch ( v0 ) // v0决定操作方式
// result决定操作输入的哪一位
// v3决定操作的值
{
case 1u:
result = byte_6010C0[i + 1]; // 指示操作的哪一位
*(&input + result) += v3; // 指示运算数
break;
case 2u:
result = byte_6010C0[i + 1];
*(&input + result) -= v3;
break;
case 3u:
result = byte_6010C0[i + 1];
*(&input + result) ^= v3;
break;
case 4u:
result = byte_6010C0[i + 1];
*(&input + result) *= v3;
break;
case 5u:
result = byte_6010C0[i + 1];
*(&input + result) ^= *(&input + byte_6010C0[i + 2]);
break;
default:
continue;
}
}
return result;
}
idapython脚本
# 大佬的代码
str_list=[4294967236,52,34,4294967217,4294967251,17,4294967191,7,4294967259,55,4294967236,6,29,4294967292,91,4294967277,4294967192,4294967263,4294967188,4294967256,4294967219,4294967172,4294967244,8]
addr = 0x6010C0
for i in range(len(str_list)):
str_list[i] &= 0xffffffff
for i in range(14997,-1,-3):
v0 = Byte(addr+i)
v3 = Byte(addr+i+2)
result = Byte(addr + i + 1) # 这个是从result = byte_6010C0[i + 1];来的。不是result = v0;
# result = v0
if v0 == 1:
str_list[result] -= v3
if v0 == 2:
str_list[result] += v3
if v0 == 3:
str_list[result] ^=v3
for i in range(len(str_list)):
str_list[i] &= 0xff
print(''.join(map(chr, str_list)))