小弟最近看了点vm 下面是一些心得体会 跟大家分享
通俗的讲 vm就是自己设计一套指令集 和一套解析这个虚拟指令集的引擎 把原本的386代码翻译成你自己的虚拟指令 然后调用你的虚拟引擎来执行这些虚拟指令。。。
这样说不知道合适不? 欢迎一起参与讨论
本文的目的是告诉大家虚拟机并不可怕 其实我们每个人都设计一套虚拟指令 这将是Cracker的噩梦。
这里感谢 jackozoo 版主提供的一个vm CrackMe源码 作为我的参考资料
感谢 老罗的代码着色器
下面是最简单的一个vm例子 只虚拟了 push 和 call 指令
/*
VM初探
作者:blueapplez
QQ:1242721xx
Email:blueapple1987@163.com
http://bbs.pediy.com/
*/
#include "stdafx.h"
#include "windows.h"
/* 下面是虚拟指令 我们只模拟了2条指令 */
//push 0x12345678 push一个4字节的数
#define vPushData 0x10
//call 0x12345678 call一个4字节的地址
#define vCall 0x12
//结束符
#define vEnd 0xff
//一个字符串
char *str = "Hello World";
/*
这是我们构造的虚拟指令, 数据还不 在mian里面我们进行了修改
push 0
push 0
push offset str ;把字符串的地址入栈
push 0
call MessageBoxA ;
*/
BYTE bVmData[] = { vPushData, 0x00, 0x00, 0x00,0x00,
vPushData, 0x00, 0x00, 0x00,0x00,
vPushData, 0x00, 0x00, 0x00, 0x00,
vPushData, 0x00, 0x00, 0x00,0x00,
vCall, 0x00, 0x00, 0x00, 0x00,
vEnd};
//这就是简单的虚拟引擎了
_declspec(naked) void VM(PVOID pvmData)
{
__asm
{
//取vCode地址放入ecx
mov ecx, dword ptr ss:[esp+4]
__vstart:
//取第一个字节到al中
mov al, byte ptr ds:[ecx]
cmp al, vPushData
je __vPushData
cmp al, vCall
je __vCall
cmp al, vEnd
je __vEnd
int 3
__vPushData:
inc ecx
mov edx, dword ptr ds:[ecx]
push edx
add ecx, 4
jmp __vstart
__vCall:
inc ecx
mov edx, dword ptr ds:[ecx]
call edx
add ecx, 4
jmp __vstart
__vEnd:
ret
}
}
int main(int argc, char* argv[])
{
//修改虚拟指令的数据
*(DWORD *)(bVmData+10 + 1) = (DWORD)str;
*(DWORD *)(bVmData+20 + 1) = (DWORD)MessageBoxA;
//执行虚拟指令
VM(bVmData);
return 0;
}
[培训]二进制漏洞攻防(第3期);满10人开班;模糊测试与工具使用二次开发;网络协议漏洞挖掘;Linux内核漏洞挖掘与利用;AOSP漏洞挖掘与利用;代码审计。
最后于 2022-7-10 15:20
被kanxue编辑
,原因: