Vm86
The x86 Script Instruction Virtual Machine
Введение
Это очень простая и лёгкая виртуальная машина x86, которая может загружать и запускать ассемблерный код из IDA Pro напрямую.
Особенности
Пример
Сначала мы получаем один ассемблерный код от 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 )