1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/tboox-vm86

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
Внести вклад в разработку кода
Синхронизировать код
Отмена
Подсказка: Поскольку Git не поддерживает пустые директории, создание директории приведёт к созданию пустого файла .keep.
Loading...
README.md

Vm86

The x86 Script Instruction Virtual Machine

Введение

Это очень простая и лёгкая виртуальная машина x86, которая может загружать и запускать ассемблерный код из IDA Pro напрямую.

Особенности

  • Поддерживает кроссплатформенность и может запускать ассемблерный код x86 на Linux, Windows, macOS, Android и iOS.
  • Поддерживает часто используемые инструкции ассемблера x86 (например, логические операции, goto, loop, call, операции со стеком).
  • Позволяет вызывать интерфейсы сторонних библиотек (.e.g libc).
  • Можно передавать аргументы и получать результаты после выполнения.
  • Является потокобезопасной.
  • Не поддерживает arm64 и работает только с 32-битной архитектурой.

Пример

Сначала мы получаем один ассемблерный код от IDA Pro, который вызывает API libc: 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+1832r 
        dd offset loc_58A945    ; jump table for switch statement 

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

loc_6B2B50:             ; CODE XREF: sub_6B2B40+8j
        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

Далее мы пытаемся загрузить этот ассемблерный код с помощью нашей виртуальной машины x86.

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+1832r \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+8j\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
``` ```
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+1832r 
        dd offset loc_58A945    ; jump table for switch statement 

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

loc_6B2B50:             ; CODE XREF: sub_6B2B40+8j
        push    eax 
        mov eax, [ebp+arg_0] 
        push eax 
        mov eax, offset format 
        push eax 
        call printf 
        add esp, 4 
        pop eax
``` Если предположить, что данный текст является запросом на перевод, то основной язык текста — это язык программирования C.

К сожалению, без контекста сложно понять, о чём идёт речь в запросе. Однако можно перевести код и некоторые фрагменты текста:

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 для вызова, это будет выглядеть так:

```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+1832r \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+8j\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);    
}

Результат будет таким же:

hello: 31415926
hello: 31415926

Комментарии ( 0 )

Вы можете оставить комментарий после Вход в систему

Введение

x86 ассемблерный скрипт виртуальной машины. Развернуть Свернуть
Apache-2.0
Отмена

Обновления

Пока нет обновлений

Участники

все

Недавние действия

Загрузить больше
Больше нет результатов для загрузки
1
https://api.gitlife.ru/oschina-mirror/tboox-vm86.git
git@api.gitlife.ru:oschina-mirror/tboox-vm86.git
oschina-mirror
tboox-vm86
tboox-vm86
master