zoukankan      html  css  js  c++  java
  • VM保护技术

    1.VM技术介绍

    我发现论坛上每当谈到虚拟机技术时,鲜有几人参与讨论,因为虚拟机技术还没有普及到大家的心中。VM 其实就是Virtual Machine(虚拟机)的缩写,这里说的VM并不是像VMWare那样的虚拟机,而是将一系列的指令解释成bytecode(字节码)放在一个解释引擎中执行。

    2.目前现状的VM应用
    VM技术最早的应用我想应该是VB(PCode)吧(瞎猜的),时至今日才被人们广泛用于安全技术中。
    如今已经将虚拟机应用到商业中的保护壳现有三款:Vmprotect,themida和 execrypt,
    Themida是一款综合型强壳,资源加密、代码变形和虚拟机技术用得是面面俱到。
    Execrypt 比Themida逊色一点,不过我没研究过。
    Vmprotect是一款专门对代码加VM的加壳软件,其保护强度是3款当中最强的,最早由2005年问世起,至今尚无人公开宣称能还原其原汇编代码,可见其强度,所以VMP已逐渐被人们用来保护其产品,使Cracker们对于这个看起来毛茸茸的刺猬毫无办法。

    3.VM的一些原理
    一个虚拟机引擎由编译器、解释器和VPU Context(虚拟CPU环境)组成,再配上一个或多个指令系统。
    编译器:将一条条X86指令解释成自己的指令系统。
    解释器:解释器附加在被加壳的软件中,用来解释这些自定义的指令。
    指令系统:一套或多套自己定义的指令系统,用来虚拟执行这些bytecode。

    在设计VM时提几个建议:
    1:设计一个好的、简洁的指令系统是很有必要的,写出越少却能执行最全的指令,就说明这些指令复用性越高。
    2:在分析X86指令时最好为它们分类,注意流程指令、不可模仿指令的处理。
    3:解释器的代码设计得越少越好,换来的速度可以变形一下。

    现在讲讲虚拟机是如何运作的,首先加壳程序先把已知的X86指令解释成了字节码,放在PE文件中,然后将原处代码删掉,
    改成类似的代码进入虚拟机执行循环。
    push bytecode
    jmp VstartVM

    VstartVM是进入虚拟机的函数,它的代码大概类似这样的
    // 进入虚拟机函数,我的最初版本是写死在成种VC环境下的,不过这样处理起来很麻烦。

    void _declspec(naked) VStartVM()

    {

    _asm

    {

    // 将寄存器压入堆栈,由伪指令取出存放到VMReg中

    //可以考虑为压栈时加入一些随机性

    push eax

    push ebx

    push ecx

    push edx

    push esi

    push edi

    push ebp

    pushfd

    mov esi,[esp+0x20]

    mov ebp,esp

    sub esp,0x200

    mov edi,esp

    sub esp,0x40

    Next:

    movzx eax,byte ptr [esi]

    lea esi,[esi+1]

    jmp dword ptr [eax*4+JUMPADDR] ;跳到Handler执行处,由加壳引擎填充

    VM_END ;VM结束标记

    }

    }
    然后每读一个byte跳到目标处模拟执行代码。
    JUMPADDR就是一张函数表(让我想到了VTBL),每次从内存里读出一个command code(其实就是偏移),然后转向那个过程,如vEnter的代码:
    // enter和执行下列代码用途相同

    //push ebp

    //mov ebp,esp

    //sub esp,(L - 1) * 4 ; L > 0才有这步操作,用来存储嵌套的L - 1个子过程的栈框架指针(注意是指针)

    //push ebp ; 当前过程的栈框架指针

    //sub esp,N

    mov edx,[edi+Ebp]
    sub ebp,4
    mov dword ptr [ebp],edx
    mov edx,ebp
    mov [edi+Esp],edx
    mov edx,ebp
    lea ecx,[ecx*4];ecx是从内存读出的opcode
    sub edx,ecx
    sub edx,4
    test ecx,ecx
    cmovne ebp,edx
    mov edx,[edi+Ebp]
    sub ebp,4
    mov dword ptr [ebp],edx
    sub ebp,eax
    //。。一些修正堆栈的工作
    jmp next
    以上代码就是模拟一个enter指令的代码,我不会汇编,就只能写成这样了。

    现在再来看看它们的执行过程:
    1.首先进入虚拟机,压入寄存器,然后设计一些伪指令来将寄存器保存到虚拟机环境中去。
    2.一切工作就绪,真实寄存器存放的值是什么已经不重要了,因为我们将它存放到了虚拟环境中去了,自己可以随便使用而不用怕影响到原来的代码。
    3.这时从那句jmp table看起,从[esi]得到一个偏移,它指向的就是vEnter的地址,于是它来到了vEnter处
    4.vEnter又从内存中得到opcode,模拟出这句代码,并存放到堆栈。
    5.注意有时要修正虚拟堆栈寄存器的值,否则会挂得很惨。
    6.Jmp 到 next,这时转向第2步。



    其他指令如同vEnter一样。。。发挥你的想像力了。



    2-6就是一个虚拟机的执行过程,如果你曾经调试过VM,是否会对jmp [table+x]似曾相识呢?

    一个简单的VM引擎就是这个样子,不过一个专业化、商业化的引擎可不仅是这个样子,还要注重很多东西,比如多线程、流程化指令,虚拟-现实之间的转换,支持SEH异常(包括VB、VC的异常)。


    看到这里,你可以发现,虚拟机就是一层复杂的壳子,把原来的代码藏得毫无踪影,如果你想还原出原来的代码(基于更高级的理论来说,暂时已经不可能了),那么你需要先复习一下IA64,然后仔细研究VM执行体,逆向出Table中用到的函数,得出它正在执行哪一条语句的哪一“部分”。。。除非你要研究的程序达到了一定的价值,不然我想等你弄清楚这个程序如何执行的时候,意义已经不大了。

    4.VM的一些资料(感谢笨笨雄的整理)

    游戏维护上不去,介绍一下虚拟机技术。

    http://bbs.pediy.com/showthread.php?threadid=20792

    【原创】Asprotect 中的 X86 的VM分析
    http://bbs.pediy.com/showthread.php?threadid=36245
    Asprotect 中的 X86 虚拟机代码分析【原创】
    http://bbs.pediy.com/showthread.php?threadid=34135

    ExeCryptor v2.X.X虚拟机不完全补完(处女帖)
    http://bbs.pediy.com/showthread.php?threadid=29537
    Themida的VM分析--变形代码清理
    http://bbs.pediy.com/showthread.php?threadid=34555
    Themida虚拟机简单介绍
    http://www.pediy.com/bbshtml/bbs8/pediy8-598.htm
    Themida v1.8.0.0 Demo虚拟机分析
    http://bbs.pediy.com/showthread.php?threadid=36453
    寂寞轰炸:再次小窥 VMProtect 虚拟机
    http://bbs.pediy.com/showthread.php?threadid=37293
    【原创】VMCrackME----A Preliminary Virtual Machine From Top To Bottom
    http://bbs.pediy.com/showthread.php?...viewgoodnees=1 (http://bbs.pediy.com/showthread.php?t=40854&viewgoodnees=1)
    Defeating HyperUnpackMe2 With an IDA Processor Module
    http://www.openrce.org/articles/full_view/28

  • 相关阅读:
    [C++空间分配]new运算符、operator new、placement new的区别于联系
    [C++STL]stl源码剖析
    [C++基础]在构造函数内部调用构造函数
    Eclipse Memory Analyzer
    zookeeper 学习 zookeeper下载部署
    Doracle.jdbc.J2EE13Compliant=true
    zookeeper 学习 状态机复制的共识算法
    java -d
    轮盘选择法
    OPENJDK 源码编译
  • 原文地址:https://www.cnblogs.com/MaxWoods/p/1717014.html
Copyright © 2011-2022 走看看