elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.

 

 


Tema destacado: Rompecabezas de Bitcoin, Medio millón USD en premios


+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse, K-YreX)
| | |-+  Ejemplo de virtualización de código con CPU imaginaria
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Ejemplo de virtualización de código con CPU imaginaria  (Leído 3,282 veces)
BloodSharp


Desconectado Desconectado

Mensajes: 803


El Messi-Vegeta :D


Ver Perfil
Ejemplo de virtualización de código con CPU imaginaria
« en: 27 Octubre 2021, 17:18 pm »

Buenas gente del foro, hice este código simple en un par de horas en C++ para 32 bits en Windows y lo quería compartir para que pueda servirle a alguién o quién quiera colaborar en este proyecto y podemos hacerlo completo... :P

La idea de virtualización de código es hacer complicado el análisis de ingeniería inversa de cualquier programa, creando una CPU imaginaria con sus propios conjunto de instrucciones y reemplazando el código original de assembler de la CPU real por la CPU imaginaria.

Código
  1. #include <iostream>
  2. #include "BloodVM.h"
  3.  
  4. int __declspec(naked) __stdcall Sumar()
  5. {
  6.    __asm
  7.    {
  8.        call BloodVM_Init;
  9.  
  10.        //MOV_R_N => mov eax, 4;
  11.        _emit 0x02; //OPCODE::MOV_R_N
  12.        _emit 0x05; //EAX offset
  13.        _emit 0x04; //number 4 bytes
  14.        _emit 0x00;
  15.        _emit 0x00;
  16.        _emit 0x00;
  17.        //ADD_R_N => add eax, 5;
  18.        _emit 0x04; //OPCODE::ADD_R_N
  19.        _emit 0x05; //EAX offset
  20.        _emit 0x05; //number 4 bytes
  21.        _emit 0x00;
  22.        _emit 0x00;
  23.        _emit 0x00;
  24.        //ADD_R_R => add eax, eax;
  25.        _emit 0x03; //OPCODE::ADD_R_R
  26.        _emit 0x05; //EAX offset
  27.        _emit 0x05; //EAX offset
  28.        //QUIT => Exit VM
  29.        _emit 0x00;
  30.  
  31.        call BloodVM_End;
  32.        ret;
  33.    }
  34. }
  35.  
  36. int main()
  37. {
  38.    std::cout << "Suma virtualizada (4 + 5) + (4 + 5) = " << Sumar() << std::endl;
  39.    std::cin.ignore();
  40. }



El código de ejemplo tiene apenas 5 instrucciones pero se podría implementar más. Al verse en un desamblador la función virtualizada se vería algo como esto:



Lo cuál forzaría al que quiera ver como funciona realmente el programa a analizar toda la CPU imaginaria siendo usualmente una tarea bastante compleja. Se podría crear también un programa que detecte las llamadas del inicio y fin de la virtualización y reemplazar el código real por el imaginario pero esa es una tarea bastante compleja que llevaría mucho tiempo.

Dejo el resto del código por si a alguien le interesa:

BloodVM.cpp
Código
  1. #include "BloodVM.h"
  2.  
  3. BloodVM gBloodVM;
  4.  
  5. uint32_t __declspec(naked) __stdcall GetCaller()//uint32_t dwESP)
  6. {
  7.    //return *(uint32_t*)(dwESP+4);
  8.    __asm
  9.    {
  10.        mov eax, [esp + 4];
  11.        ret;
  12.    }
  13. }
  14.  
  15. void __declspec(naked) __stdcall BloodVM_Init()
  16. {
  17.    __asm
  18.    {
  19.        pushad;
  20.        pop gBloodVM.EDI;
  21.        pop gBloodVM.ESI;
  22.        pop gBloodVM.EBP;
  23.        pop gBloodVM.ESP;
  24.        pop gBloodVM.EBX;
  25.        pop gBloodVM.EDX;
  26.        pop gBloodVM.ECX;
  27.        pop gBloodVM.EAX;
  28.  
  29.        //push gBloodVM.ESP;
  30.        call GetCaller;
  31.        mov gBloodVM.EIP, eax;
  32.        lea ecx, gBloodVM;
  33.        call BloodVM::RunVirtualMachine;
  34.        mov eax, gBloodVM.EIP;
  35.        mov [esp], eax;
  36.        ret;
  37.    }
  38. }
  39.  
  40. void __declspec(naked) __stdcall BloodVM_End()
  41. {
  42.    __asm
  43.    {
  44.        mov edi, gBloodVM.EDI;
  45.        mov esi, gBloodVM.ESI;
  46.        mov ebx, gBloodVM.EBX;
  47.        mov edx, gBloodVM.EDX;
  48.        mov ecx, gBloodVM.ECX;
  49.        mov eax, gBloodVM.EAX;
  50.        mov ebp, gBloodVM.EBP;
  51.        mov esp, gBloodVM.ESP;
  52.        ret;
  53.    }
  54. }
  55.  
  56. void BloodVM::RunVirtualMachine()
  57. {
  58.    do
  59.    {
  60.        this->currentOpcode = (uint8_t)(*((uint8_t*)this->EIP));
  61.        uint32_t nextEIP = this->vInstructions[this->currentOpcode].sizeOfInstruction;
  62.        (this->*vInstructions[this->currentOpcode].operate)();
  63.        this->EIP += nextEIP;
  64.    } while (this->currentOpcode != OPCODE::QUIT);
  65. }
  66.  
  67. void BloodVM::QUIT()
  68. {
  69.  
  70. }
  71.  
  72. void BloodVM::MOV()
  73. {
  74.    uint32_t* firstRegister;
  75.    uint32_t* secondRegister;
  76.    uint32_t firstNumber;
  77.    switch (this->currentOpcode)
  78.    {
  79.        case OPCODE::MOV_R_R:
  80.            firstRegister = &this->EDI + *(uint8_t*)(this->EIP + 1);
  81.            secondRegister = &this->EDI + *(uint8_t*)(this->EIP + 2);
  82.            *firstRegister = *secondRegister;
  83.            break;
  84.        case OPCODE::MOV_R_N:
  85.            firstRegister = &this->EDI + *(uint8_t*)(this->EIP + 1);
  86.            firstNumber = *(uint32_t*)(this->EIP + 2);
  87.            *firstRegister = firstNumber;
  88.            break;
  89.    }
  90. }
  91.  
  92. void BloodVM::ADD()
  93. {
  94.    uint32_t* firstRegister;
  95.    uint32_t* secondRegister;
  96.    uint32_t firstNumber;
  97.    switch (this->currentOpcode)
  98.    {
  99.        case OPCODE::ADD_R_R:
  100.            firstRegister = &this->EDI + *(uint8_t*)(this->EIP + 1);
  101.            secondRegister = &this->EDI + *(uint8_t*)(this->EIP + 2);
  102.            *firstRegister += *secondRegister;
  103.            break;
  104.        case OPCODE::ADD_R_N:
  105.            firstRegister = &this->EDI + *(uint8_t*)(this->EIP + 1);
  106.            firstNumber = *(uint32_t*)(this->EIP + 2);
  107.            *firstRegister += firstNumber;
  108.            break;
  109.    }
  110. }

BloodVM.h
Código
  1. #pragma once
  2. #include <cstdint>
  3. #include <vector>
  4.  
  5. enum OPCODE
  6. {
  7. QUIT,
  8. MOV_R_R,
  9. MOV_R_N,
  10. ADD_R_R,
  11. ADD_R_N,
  12. };
  13.  
  14. class BloodVM
  15. {
  16. public:
  17. BloodVM()
  18. {
  19. vInstructions =
  20. {
  21. /*
  22. All opcodes sizes are always 1 byte
  23. All registers (R) sizes are also 1 byte
  24. All numbers (N) sizes are always 4 bytes
  25. */
  26. {OPCODE::QUIT, 1, &BloodVM::QUIT},
  27. {OPCODE::MOV_R_R, 3, &BloodVM::MOV},
  28. {OPCODE::MOV_R_N, 6, &BloodVM::MOV},
  29. {OPCODE::ADD_R_R, 3, &BloodVM::ADD},
  30. {OPCODE::ADD_R_N, 6, &BloodVM::ADD},
  31. };
  32. }
  33.        uint32_t EDI, ESI, EBX, EDX, ECX, EAX, EBP, EIP, ESP;
  34. uint8_t currentOpcode;
  35. void RunVirtualMachine();
  36.  
  37. void MOV();
  38. void ADD();
  39. void QUIT();
  40.  
  41. struct INSTRUCTION
  42. {
  43. uint8_t opcode;
  44. uint8_t sizeOfInstruction;
  45. void (BloodVM::* operate)() = nullptr;
  46. };
  47.  
  48. std::vector<INSTRUCTION> vInstructions;
  49. };
  50.  
  51. void __stdcall BloodVM_Init();
  52. void __stdcall BloodVM_End();


B#


En línea



@XSStringManolo
Hacker/Programador
Colaborador
***
Desconectado Desconectado

Mensajes: 2.397


Turn off the red ligth


Ver Perfil WWW
Re: Ejemplo de virtualización de código con CPU imaginaria
« Respuesta #1 en: 27 Octubre 2021, 20:34 pm »

Qué guapo!


En línea

Mi perfil de patrocinadores de GitHub está activo! Puedes patrocinarme para apoyar mi trabajo de código abierto 💖

MAFUS


Desconectado Desconectado

Mensajes: 1.603



Ver Perfil
Re: Ejemplo de virtualización de código con CPU imaginaria
« Respuesta #2 en: 27 Octubre 2021, 21:57 pm »

Esto me recuerda un proyecto llamado CHIP-8. Un chip virtual con sus especificaciones y con juegos diseñados para él.

Un poco de info sobre ese chip: https://github.com/mattmikolay/chip-8/wiki/
En línea

Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Ejemplo + Codigo fuente en VB.NET 2005
.NET (C#, VB.NET, ASP)
Gota 0 6,863 Último mensaje 10 Noviembre 2008, 01:16 am
por Gota
Winosck Hook Codigo de ejemplo
Programación C/C++
antrixro 0 2,018 Último mensaje 8 Febrero 2011, 19:17 pm
por antrixro
Código de ejemplo.
.NET (C#, VB.NET, ASP)
michdav44 3 2,424 Último mensaje 7 Abril 2017, 02:45 am
por Eleкtro
Ejemplo de código paradetectar macros de Office
Programación Visual Basic
Medardo 1 1,951 Último mensaje 3 Abril 2019, 18:07 pm
por Medardo
Código fuente de un ejemplo de automatización de un bot usando selenium
Java
TickTack 1 2,008 Último mensaje 5 Mayo 2019, 16:38 pm
por CalgaryCorpus
WAP2 - Aviso Legal - Powered by SMF 1.1.21 | SMF © 2006-2008, Simple Machines