1. Этот сайт использует файлы cookie. Продолжая пользоваться данным сайтом, Вы соглашаетесь на использование нами Ваших файлов cookie. Узнать больше.
Приветствуем вас,Гость, на форуме IFUD.WS. Обязательно рекомендуется к прочтению правила форума http://ifud.ws/threads/obnovleno-pravila-foruma.7759

SEH based VM Engine by Yattering

Тема в разделе "Исходные коды", создана пользователем Yatterng, 17 ноя 2016.

  1. TopicStarter Overlay
    Yatterng

    Yatterng

    Регистрация:
    17 ноя 2016
    Сообщения:
    3
    Симпатии:
    0
    Простейший движок ВМ для виртуализации x86 кода, который позволяет заменять некоторые машинные инструкции собсвенными подобными инструкциями, поэтому защищенный код не может выполняться без внешнего движка ВМ.

    Код:
    ; SEH based VM Engine by Yattering, 2016
    ; e-mail: yattering (at) sigaint (d0t) org
    ; jabber: yattering (at) xmpp (d0t) jp
    
    format MS COFF
    
    include 'sehvm.inc'
    
    extrn '__imp__MessageBoxA@16' as MessageBoxA:dword
    
    extrn '_exception_handler' as _exception_handler
    
    public _main
    
    section '.text' code readable executable
    _main:
            ; Register exception handler
            lea     eax, [_exception_handler]
            xor     ecx, ecx
            push    eax
            push    DWord [fs:ecx]
            mov     DWord [fs:ecx], esp
            ; Run unprotected code
            call _unprotected_code_function
            ; Run protecred code
            SEHVM_CALL_REL_C32 _protected_code_function
            ; Unregister exception handler
            xor     ecx, ecx
            pop     DWord [fs:ecx]
            pop     eax
            ret
    
    _protected_code_function:
        SEHVM_PUSH_C32 0
            SEHVM_PUSH_C32 _caption
            SEHVM_PUSH_C32 _messageP
            SEHVM_PUSH_C32 0
            call DWord [MessageBoxA]
            SEHVM_RET_C8 0
    
    _unprotected_code_function:
        push 0
            push _caption
            push _messageUP
            push 0
            call DWord [MessageBoxA]
        ret
    
    section '.data' data readable writeable
    
     _caption   db 'Win32 assembly',0
     _messageUP db 'MessageBox from unprotected code',0
     _messageP  db 'MessageBox from protected code',0
    
    
    Листинг дизассемлера этого примера в OllyDbg
    Код:
    00401000 >/$ 8D05 60104000  LEA EAX,DWORD PTR DS:[401060]
    00401006  |. 31C9           XOR ECX,ECX
    00401008  |. 50             PUSH EAX
    00401009  |. 64:FF31        PUSH DWORD PTR FS:[ECX]
    0040100C  |. 64:8921        MOV DWORD PTR FS:[ECX],ESP
    0040100F  |. E8 2E000000    CALL demo_fas.00401042
    00401014  |. CC             INT3
    00401015  |. 05 0D000000    ADD EAX,0D
    0040101A  |. 31C9           XOR ECX,ECX
    0040101C  |. 64:8F01        POP DWORD PTR FS:[ECX]
    0040101F  |. 58             POP EAX
    00401020  \. C3             RETN
    00401021     CC             INT3
    00401022     01             DB 01
    00401023     00             DB 00
    00401024     00             DB 00
    00401025     00             DB 00
    00401026     00             DB 00
    00401027     CC             INT3
    00401028     01             DB 01
    00401029     00304000       DD demo_fas.00403000                     ;  ASCII "Win32 assembly"
    0040102D     CC             INT3
    0040102E     01             DB 01
    0040102F     30304000       DD demo_fas.00403030                     ;  ASCII "MessageBox from protected code"
    00401033     CC             INT3
    00401034     01             DB 01
    00401035     00             DB 00
    00401036     00             DB 00
    00401037     00             DB 00
    00401038     00             DB 00
    00401039     FF             DB FF
    0040103A     15             DB 15
    0040103B     80304000       DD <&USER32.MessageBoxA>
    0040103F     CC             INT3
    00401040     00             DB 00
    00401041     00             DB 00
    00401042  /$ 6A 00          PUSH 0                                   ; /Style = MB_OK|MB_APPLMODAL
    00401044  |. 68 00304000    PUSH demo_fas.00403000                   ; |Title = "Win32 assembly"
    00401049  |. 68 0F304000    PUSH demo_fas.0040300F                   ; |Text = "MessageBox from unprotected code"
    0040104E  |. 6A 00          PUSH 0                                   ; |hOwner = NULL
    00401050  |. FF15 80304000  CALL DWORD PTR DS:[<&USER32.MessageBoxA>>; \MessageBoxA
    00401056  \. C3             RETN
    

    Список команд ВМ:
    • RET_C8
    • PUSH_R32
    • PUSH_C32
    • POP_R32
    • JMP_REL_C32
    • CALL_REL_C32
    • NOP
    Все команды ВМ начинаються с INT3 инструкции х86 процессора, благодаря чему управление передаеться на SEH обработчик, который и являеться движком ВМ. Движок написан на чистых сях.

    Код:
    /*SEH based VM Engine by Yattering, 2016
     *e-mail: yattering (at) sigaint (d0t) org
     *jabber: yattering (at) xmpp (d0t) jp
     */
    #define WIN32_LEAN_AND_MEAN
    #ifdef SELF_TEST
    #define __DEBUG__
    #endif
    
    #include <windows.h>
    #include <stdint.h>
    #include "debug_log.h"
    #include "sehvm.h"
    
    #ifdef SELF_TEST
    #pragma comment(linker, "/ENTRY:main")
    #pragma comment(linker, "/SUBSYSTEM:WINDOWS")
    #endif
    
    EXCEPTION_DISPOSITION __cdecl exception_handler(struct _EXCEPTION_RECORD *except, void * establisher_frame, struct _CONTEXT *context, void *dispatcher_context);
    
    __DEBUG_GLOBAL_VARIABLES()
    
    EXCEPTION_DISPOSITION __cdecl exception_handler(struct _EXCEPTION_RECORD *except, void * establisher_frame, struct _CONTEXT *context, void *dispatcher_context) {
      uint8_t reg;
      uint8_t *p_nnm = except->ExceptionAddress;
      __DEBUG_PUTS("\r\nEXCEPTION HANDLER\r\n");
      if (*p_nnm == SEHVM_INT3_OPCODE) {
        p_nnm++;
        switch (*p_nnm) {
          case SEHVM_TYPE_RET_C8:
            __DEBUG_PRINTF("] NANOMITE TYPE <RET_C8>\r\n]] RET 0x%X\r\n", p_nnm[1]);
            uint32_t ret_addr = *(uint32_t *)(context->Esp);
            context->Esp += 4 + p_nnm[1];
            context->Eip = ret_addr;
            __DEBUG_PAUSE();
            break;
          case SEHVM_TYPE_PUSH_C32: {
            __DEBUG_PRINTF("] NANOMITE TYPE <PUSH_C32>\r\n]] PUSH 0x%X\r\n", (*(uint32_t *)&p_nnm[1]));
            context->Esp-=4;
            *(uint32_t *) context->Esp = *(uint32_t *) &p_nnm[1];
            context->Eip += 0x6;
            __DEBUG_PAUSE();
            break;
          }
          case SEHVM_TYPE_PUSH_R32: {
            reg = p_nnm[1] & 0x7;
    #ifdef __DEBUG__
            char *reg_name = \
             ((reg == SEHVM_ARG_EAX)?("EAX"):((reg == SEHVM_ARG_EBX)?("EBX"):((reg == SEHVM_ARG_ECX)?("ECX"):\
             ((reg == SEHVM_ARG_EDX)?("EDX"):((reg == SEHVM_ARG_EDI)?("EDI"):((reg == SEHVM_ARG_ESI)?("ESI"):\
             ((reg == SEHVM_ARG_EBP)?("EBP"):"INVALID_REGISTER")))))));
            __DEBUG_PRINTF("] NANOMITE TYPE <PUSH_R32>\r\n]] PUSH %s\r\n", reg_name);
            uint32_t reg_val =
             ((reg == SEHVM_ARG_EAX)?(context->Eax):\
             ((reg == SEHVM_ARG_EBX)?(context->Ebx):\
             ((reg == SEHVM_ARG_ECX)?(context->Ecx):\
             ((reg == SEHVM_ARG_EDX)?(context->Edx):\
             ((reg == SEHVM_ARG_EDI)?(context->Edi):\
             ((reg == SEHVM_ARG_ESI)?(context->Esi):\
             ((reg == SEHVM_ARG_EBP)?(context->Ebp):\
             0xDEADBEEF)))))));
            __DEBUG_PRINTF("]]] %s = 0x%X\r\n", reg_name, reg_val);
    #endif
            context->Esp-=4;
            *(uint32_t *)(context->Esp) = \
             ((reg == SEHVM_ARG_EAX)?(context->Eax):\
             ((reg == SEHVM_ARG_EBX)?(context->Ebx):\
             ((reg == SEHVM_ARG_ECX)?(context->Ecx):\
             ((reg == SEHVM_ARG_EDX)?(context->Edx):\
             ((reg == SEHVM_ARG_EDI)?(context->Edi):\
             ((reg == SEHVM_ARG_ESI)?(context->Esi):\
             ((reg == SEHVM_ARG_EBP)?(context->Ebp):\
               0xDEADBEEF)))))));
            context->Eip += 0x3;
            __DEBUG_PAUSE();
            break;
          }
          case SEHVM_TYPE_POP_R32: {
            reg = p_nnm[1] & 0x7;
    #ifdef __DEBUG__
            char *reg_name = \
             ((reg == SEHVM_ARG_EAX)?("EAX"):((reg == SEHVM_ARG_EBX)?("EBX"):((reg == SEHVM_ARG_ECX)?("ECX"):\
             ((reg == SEHVM_ARG_EDX)?("EDX"):((reg == SEHVM_ARG_EDI)?("EDI"):((reg == SEHVM_ARG_ESI)?("ESI"):\
             ((reg == SEHVM_ARG_EBP)?("EBP"):"INVALID_REGISTER")))))));
            if (reg == SEHVM_ARG_INVALID_REGISTER) {
              __DEBUG_PRINTF("] NANOMITE TYPE <NOP1>\r\n");
            } else {
              __DEBUG_PRINTF("] NANOMITE TYPE <POP_R32>\r\n]] POP %s\r\n", reg_name);
              uint32_t reg_val =
               ((reg == SEHVM_ARG_EAX)?(context->Eax):\
               ((reg == SEHVM_ARG_EBX)?(context->Ebx):\
               ((reg == SEHVM_ARG_ECX)?(context->Ecx):\
               ((reg == SEHVM_ARG_EDX)?(context->Edx):\
               ((reg == SEHVM_ARG_EDI)?(context->Edi):\
               ((reg == SEHVM_ARG_ESI)?(context->Esi):\
               (context->Ebp)))))));
              __DEBUG_PRINTF("]]] BEFORE: %s = 0x%X ", reg_name, reg_val);
            }
    #endif
            if (reg != SEHVM_ARG_INVALID_REGISTER) {
              *((reg == SEHVM_ARG_EAX)?(&context->Eax):\
               ((reg == SEHVM_ARG_EBX)?(&context->Ebx):\
               ((reg == SEHVM_ARG_ECX)?(&context->Ecx):\
               ((reg == SEHVM_ARG_EDX)?(&context->Edx):\
               ((reg == SEHVM_ARG_EDI)?(&context->Edi):\
               ((reg == SEHVM_ARG_ESI)?(&context->Esi):\
               (&context->Ebp))))))) = *(uint32_t *)(context->Esp);
               context->Esp += 0x4;
            }
    #ifdef __DEBUG__
            if (reg != SEHVM_ARG_INVALID_REGISTER) {
              uint32_t reg_val = \
               ((reg == SEHVM_ARG_EAX)?(context->Eax):\
               ((reg == SEHVM_ARG_EBX)?(context->Ebx):\
               ((reg == SEHVM_ARG_ECX)?(context->Ecx):\
               ((reg == SEHVM_ARG_EDX)?(context->Edx):\
               ((reg == SEHVM_ARG_EDI)?(context->Edi):\
               ((reg == SEHVM_ARG_ESI)?(context->Esi):\
               (context->Ebp)))))));
              __DEBUG_PRINTF("AFTER: %s = 0x%X \r\n", reg_name, reg_val);
            }
    #endif
            context->Eip += 0x3;
            __DEBUG_PAUSE();
            break;
          }
          case SEHVM_TYPE_JMP_REL_C32:
            __DEBUG_PUTS("] NANOMITE TYPE <JMP_REL_C32>\r\n");
            __DEBUG_PRINTF("]] JMP_REL_C32 0x%X\r\n", *(uint32_t *)&p_nnm[1]);
            __DEBUG_PRINTF("]]] BEFORE: EIP = 0x%X\r\n", context->Eip);
            context->Eip += *(uint32_t *)&p_nnm[1];
            __DEBUG_PRINTF("AFTER: EIP = 0x%X\r\n", context->Eip);
            __DEBUG_PAUSE();
            break;
          case SEHVM_TYPE_CALL_REL_C32:
            __DEBUG_PUTS("] NANOMITE TYPE <CALL_REL_C32>\r\n");
            __DEBUG_PRINTF("]] JMP_CALL_C32 0x%X\r\n", *(uint32_t *)&p_nnm[1]);
            __DEBUG_PRINTF("]]] BEFORE: EIP = 0x%X\r\n", context->Eip);
            context->Esp -= 4;
            *(uint32_t *)(context->Esp) = context->Eip + 0x6;
            context->Eip += *(uint32_t *)(&p_nnm[1]);
            __DEBUG_PRINTF("AFTER: EIP = 0x%X\r\n", context->Eip);
            __DEBUG_PAUSE();
            break;
        };
      };
      return(ExceptionContinueExecution);
    }
    #ifndef SELF_TEST
    /*
    void __declspec(naked) exception_handler_end(void) {
      __asm _emit(0xCA) __asm _emit(0xFE) __asm _emit(0xDE) __asm _emit(0xAD);
    } */
    #endif
    
    #ifdef SELF_TEST
    
    int main(void) {
      __DEBUG_INIT();
      __asm {
        xor     ecx, ecx
        push    offset exception_handler
        push    DWord Ptr fs:[ecx]
        mov     DWord Ptr fs:[ecx], esp
      }
    
    __DEBUG_PUTS(" [[[ START SEH BASED VM ENGINE TESTING ]]] \r\n\r\n");
    
    __DEBUG_PUTS("TESTED COMMAND <PUSH_R32 EAX>\r\n");
      SEHVM_PUSH_R32(SEHVM_ARG_EAX);
      __asm pop eax
    __DEBUG_PUTS("TESTED COMMAND <PUSH_R32 EBX>\r\n");
      SEHVM_PUSH_R32(SEHVM_ARG_EBX)
      __asm pop eax
    __DEBUG_PUTS("TESTED COMMAND <PUSH_R32 ECX>\r\n");
      SEHVM_PUSH_R32(SEHVM_ARG_ECX)
      __asm pop eax
    __DEBUG_PUTS("TESTED COMMAND <PUSH_R32 EDX>\r\n");
      SEHVM_PUSH_R32(SEHVM_ARG_EDX)
      __asm pop eax
    __DEBUG_PUTS("TESTED COMMAND <PUSH_R32 EDI>\r\n");
      SEHVM_PUSH_R32(SEHVM_ARG_EDI)
      __asm pop eax
    __DEBUG_PUTS("TESTED COMMAND <PUSH_R32 ESI>\r\n");
      SEHVM_PUSH_R32(SEHVM_ARG_ESI)
      __asm pop eax
    __DEBUG_PUTS("TESTED COMMAND <PUSH_R32 EBP>\r\n");
      SEHVM_PUSH_R32(SEHVM_ARG_EBP)
      __asm pop eax
    __DEBUG_PUTS("TESTED COMMAND <PUSH_R32 INVALID_REGISTER>\r\n");
      SEHVM_PUSH_R32(SEHVM_ARG_INVALID_REGISTER)
      __asm pop eax
      __DEBUG_PUTS("TESTED COMMAND <POP_R32 EAX>\r\nTOS VALUE = 0xDEADBEEF\r\n");
      __asm push eax
      __asm push 0xDEADBEEF
      SEHVM_POP_R32(SEHVM_ARG_EAX)
      __asm pop eax
      __DEBUG_PUTS("TESTED COMMAND <POP_R32 EBX>\r\nTOS VALUE = 0xDEADCAFE\r\n");
      __asm push ebx
      __asm push 0xDEADCAFE
      SEHVM_POP_R32(SEHVM_ARG_EBX)
      __asm pop ebx
      __DEBUG_PUTS("TESTED COMMAND <POP_R32 ECX>\r\nTOS VALUE = 0xDEADCAFE\r\n");
      __asm push ecx
      __asm push 0xDEADCAFE
      SEHVM_POP_R32(SEHVM_ARG_ECX)
      __asm pop ecx
      __DEBUG_PUTS("TESTED COMMAND <POP_R32 EDX>\r\nTOS VALUE = 0xDEADCAFE\r\n");
      __asm push edx
      __asm push 0xDEADCAFE
      SEHVM_POP_R32(SEHVM_ARG_EDX)
      __asm pop edx
      __DEBUG_PUTS("TESTED COMMAND <POP_R32 ESI>\r\nTOS VALUE = 0xDEADCAFE\r\n");
      __asm push esi
      __asm push 0xDEADCAFE
      SEHVM_POP_R32(SEHVM_ARG_ESI)
      __asm pop esi
      __DEBUG_PUTS("TESTED COMMAND <POP_R32 EDI>\r\nTOS VALUE = 0xDEADCAFE\r\n");
      __asm push edi
      __asm push 0xDEADCAFE
      SEHVM_POP_R32(SEHVM_ARG_EDI)
      __asm pop edi
      __DEBUG_PUTS("TESTED COMMAND <POP_R32 EBP>\r\nTOS VALUE = 0xDEADCAFE\r\n");
      __asm push ebp
      __asm push 0xDEADCAFE
      SEHVM_POP_R32(SEHVM_ARG_EBP)
      __asm pop ebp
      __DEBUG_PUTS("TESTED COMMAND <NOP>\r\n");
      SEHVM_NOP();
      __DEBUG_PUTS("TESTED COMMAND <SEHVM_JMP_REL_C32>\r\n");
      SEHVM_JMP_REL_C32(0x6);
      __DEBUG_PUTS("\r\n\r\n [[[ END SEH BASED VM ENGINE TESTING ]]] \r\n\r\n");
      __DEBUG_PAUSE();
      __asm {
        pop     DWord Ptr fs:[0]
        pop     eax
      }
      return(0x0);
    };
    #endif
    
    Войти или зарегистрироваться, чтобы увидеть ссылку.

    [​IMG]
     
    Метки:

Поделиться этой страницей

Загрузка...