汇编指令脚本虚拟机 vm86

码农软件 · 软件分类 · 汇编开发工具 · 2019-12-12 20:42:54

软件介绍

x86汇编指令脚本虚拟机

简介:

这是一个可以直接解释执行从ida pro里面提取出来的x86汇编代码的虚拟机。

非常精简,整体架构上不能跟那些成熟的虚拟机相比,主要目标是够用、能用、轻量就行。

项目主页

特性:

  • 跨平台运行支持,可以在windows、linux、macosx以及android, ios上运行x86的汇编代码。。

  • 支持常用x86汇编指令(例如,逻辑操作,跳转,循环,调用,压栈等指令)

  • 支持函数间跳转,以及第三方api调用

  • 支持参数传入,以及运行结束后,返回值的获取

  • 虚拟机的运行粒度为单个函数,函数间的跳转可以通过多个虚拟机实例来完成(轻量的,性能影响不大)

  • 支持线程安全

  • 暂时不支持arm64,只能在32位下运行(有兴趣的同学可以自行修改)

例子

我们先从ida中提取一段汇编代码,这段汇编主要是printf库函数打印外部传入的数值

sub_hello   proc near 
arg_0       = dword ptr  8 
.data 
        format db \"hello: %x\", 0ah, 0dh, 0 

off_5A74B0  dd offset loc_6B2B50    ; DATA XREF: sub_589100+1832�r 
        dd offset loc_58A945    ; jump table for switch statement 

.code 
        ; hi
        push    ebp ;hello 
        mov ebp, esp 

    loc_6B2B50:             ; CODE XREF: sub_6B2B40+8�j
        push    eax 
        mov eax, [ebp+arg_0] 
        push eax 
        mov eax, offset format 
        push eax 
        call printf 
        add esp, 4 
        pop eax 

        mov ecx, 1
        jmp ds:off_5A74B0[ecx*4]

loc_58A945:
        push    eax 
        mov eax, [ebp+arg_0] 
        push eax 
        mov eax, offset format 
        push eax 
        call printf 
        add esp, 4 
        pop eax 

  end:
        mov esp, ebp 
        pop ebp 
        retn 
sub_hello    endp

如果用c来调用的话,就是"

sub_hello(31415926);

输出结果:

hello: 31415926
hello: 31415926

接下来我们把这段汇编直接放到我们的虚拟机里面执行:

static tb_void_t vm86_demo_proc_exec_hello(tb_uint32_t value)
{
    // 上述汇编代码的字符串表示
    static tb_char_t const s_code_sub_hello[] = 
    {
"sub_hello  proc near \n\
arg_0       = dword ptr  8 \n\
.data \n\
        format db \"hello: %x\", 0ah, 0dh, 0 \n\
 \n\
off_5A74B0  dd offset loc_6B2B50    ; DATA XREF: sub_589100+1832�r \n\
        dd offset loc_58A945    ; jump table for switch statement \n\
 \n\
.code \n\
        ; hi\n\
        push    ebp ;hello \n\
        mov ebp, esp \n\
 \n\
    loc_6B2B50:             ; CODE XREF: sub_6B2B40+8�j\n\
        push    eax \n\
        mov eax, [ebp+arg_0] \n\
        push eax \n\
        mov eax, offset format \n\
        push eax \n\
        call printf \n\
        add esp, 4 \n\
        pop eax \n\
        \n\
        mov ecx, 1\n\
        jmp ds:off_5A74B0[ecx*4]\n\
 \n\
loc_58A945:\n\
        push    eax \n\
        mov eax, [ebp+arg_0] \n\
        push eax \n\
        mov eax, offset format \n\
        push eax \n\
        call printf \n\
        add esp, 4 \n\
        pop eax \n\
        \n\
  end:\n\
        mov esp, ebp \n\
        pop ebp \n\
        retn \n\
sub_hello    endp \n\
    "
    };

    // 定义一个虚拟机
    vm86_machine_ref_t machine = vm86_machine();
    if (machine)
    {
        // 锁定虚拟机,保证线程安全(这个根据需要,可选)
        tb_spinlock_ref_t lock = vm86_machine_lock(machine);
        tb_spinlock_enter(lock);

        // 获取虚拟机的堆栈
        vm86_stack_ref_t stack = vm86_machine_stack(machine);

        // 编译上面的汇编代码,并生成一个过程对象的引用
        vm86_proc_ref_t proc = vm86_text_compile(vm86_machine_text(machine), s_code_sub_hello, sizeof(s_code_sub_hello));
        if (proc)
        {
            // 添加汇编里面需要调用到的外部库函数
            vm86_machine_function_set(machine, "printf", vm86_demo_proc_func_printf);

            // 初始化调用参数
            vm86_stack_push(stack, value);

            // 执行这个汇编代码
            vm86_proc_done(proc);

            // 恢复堆栈,获取返回值(这里是void的,传null就行了)
            vm86_stack_pop(stack, tb_null);
        }

        // 解锁虚拟机
        tb_spinlock_leave(lock);
    } 
}

int main(int argc, char** argv)
{
    // 执行这个汇编函数:sub_hello(0x31415926)
    vm86_demo_proc_exec_hello(0x31415926);    
}

ok,那么输出结果当然也是:

hello: 31415926
hello: 31415926

编译

需要先安装xmake

在 macosx 上编译

$ sudo brew install xmake
$ xmake f -a i386
$ xmake

在 linux 上编译

$ git clone https://github.com/waruqi/xmake.git
$ cd xmake
$ sudo ./install
$
$ cd vm86
$ xmake f -a i386
$ xmake

在 windows 上编译

下载 https://github.com/waruqi/xmake/archive/master.zip

解压运行里面的 install.bat 安装xmake后进行编译:

$ xmake

编译android版本

$ cd vm86
$ xmake f -p android --ndk=/xxx/ndk
$ xmake

运行

运行测试程序:

$ xmake r demo

后话

最后,在项目的idc目录下,有两个脚本工具:export_function.idc 和 export_data.idc 可以用来辅助我们从ida中导出指定的汇编函数和数据

本文地址:https://codercto.com/soft/d/21015.html

Purely Functional Data Structures

Purely Functional Data Structures

Chris Okasaki / Cambridge University Press / 1999-6-13 / USD 49.99

Most books on data structures assume an imperative language such as C or C++. However, data structures for these languages do not always translate well to functional languages such as Standard ML, Ha......一起来看看 《Purely Functional Data Structures》 这本书的介绍吧!

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

MD5 加密
MD5 加密

MD5 加密工具

html转js在线工具
html转js在线工具

html转js在线工具