diff --git a/README.md b/README.md index aa020ed..b664141 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,118 @@ -# VMProfiler - Library To Profile VMProtect 2 Virtual Machines +### VMProfiler - Library To Profile VMProtect 2 Virtual Machines -vmprofiler is a c++ library which is used to statically analyze VMProtect 2 polymorphic virtual machines. This project is inherited in vmprofiler-qt, vmprofiler-cli, and vmemu. This is the base project for all other VMProtect 2 projects inside of this group on githacks. \ No newline at end of file +vmprofiler is a c++ library which is used to statically analyze VMProtect 2 polymorphic virtual machines. This project is inherited in vmprofiler-qt, vmprofiler-cli, and vmemu. This is the base project for all other VMProtect 2 projects inside of this group on githacks. + +### Credit & Contributors + +* [VTIL](https://github.com/vtil-project/VTIL-Core) - Virtual-machine Translation Intermediate Language +* [Zydis](https://github.com/zyantific/zydis) - Fast and lightweight x86/x86-64 disassembler library +* [irql0](https://github.com/irql0) - helped with the first version of vm handler pattern matching + +### Basic Usage - Creating a vm::ctx_t Object + +The `vm::ctx_t` class is a small container-like class which is simply used to contain all information for a given vm entry. This class contains the following useful information: + +* all vm handlers for a given vm entry +* the linear virtual address of the module base in memory +* the image base address +* the image size in virtual memory +* which way VIP advances (exec_type) +* vm entry relative virtual address +* vm entry deobfuscated and flattened +* calc jmp deobfuscated and flattened + +All of the above information is generated by executing the `vm::ctx_t::init` member function. Below is a C++ example of how to create a `vm::ctx_t` object. + +```cpp +const auto module_base = reinterpret_cast< std::uintptr_t >( + LoadLibraryExA( parser.get< std::string >( "bin" ).c_str(), + NULL, DONT_RESOLVE_DLL_REFERENCES ) ); + +const auto vm_entry_rva = std::strtoull( parser.get< std::string >( "vmentry" ).c_str(), nullptr, 16 ); +const auto image_base = umtils->image_base( parser.get< std::string >( "bin" ).c_str() ); +const auto image_size = NT_HEADER( module_base )->OptionalHeader.SizeOfImage; +vm::ctx_t vmctx( module_base, image_base, image_size, vm_entry_rva ); + +if ( !vmctx.init() ) +{ + std::printf( "[!] failed to init vm::ctx_t... make sure all cli arguments are correct!\n" ); + return -1; +} +``` + +### Using vm::ctx_t Object + +Once you have instantiated `vm::ctx_t` and called `vm::ctx_t::init` with success, you now can directly access the data members of `vm::ctx_t`. Most importantly, `vm::ctx_t::calc_jmp`, `vm::ctx_t::vm_entry`, and `vm::ctx_t::vm_handlers`. An example usage of this data could be dumping the native x86_64 instructions which make up `vm::ctx_t::vm_entry`. Example c++ code for this is displayed below. + +```cpp +std::puts( "======================== [vm entry] ========================\n" ); +vm::util::print( vmctx.vm_entry ); +``` + +***Output*** + +``` +======================== [vm entry] ======================== +> 0x00007FF7911A822C push 0xFFFFFFFF890001FA +> 0x00007FF7911A7FC9 push 0x45D3BF1F +> 0x00007FF7911A48E4 push r13 +> 0x00007FF7911A4690 push rsi +> 0x00007FF7911A4E53 push r14 +> 0x00007FF7911A74FB push rcx +> 0x00007FF7911A607C push rsp +> 0x00007FF7911A4926 pushfq +> 0x00007FF7911A4DC2 push rbp +> 0x00007FF7911A5C8C push r12 +> 0x00007FF7911A52AC push r10 +> 0x00007FF7911A51A5 push r9 +> 0x00007FF7911A5189 push rdx +> 0x00007FF7911A7D5F push r8 +> 0x00007FF7911A4505 push rdi +> 0x00007FF7911A4745 push r11 +> 0x00007FF7911A478B push rax +> 0x00007FF7911A7A53 push rbx +> 0x00007FF7911A500D push r15 +> 0x00007FF7911A6030 push [0x00007FF7911A7912] +> 0x00007FF7911A593A mov rax, 0x7FF6511A0000 +> 0x00007FF7911A5955 mov r13, rax +> 0x00007FF7911A595F test dl, al +> 0x00007FF7911A5965 push rax +> 0x00007FF7911A5969 btr si, bx +> 0x00007FF7911A596F mov esi, [rsp+0xA0] +> 0x00007FF7911A5979 not esi +> 0x00007FF7911A5985 neg esi +> 0x00007FF7911A598D ror esi, 0x1A +> 0x00007FF7911A599E mov rbp, rsp +> 0x00007FF7911A59A8 sub rsp, 0x140 +> 0x00007FF7911A59B5 and rsp, 0xFFFFFFFFFFFFFFF0 +> 0x00007FF7911A59BE inc ax +> 0x00007FF7911A59C1 mov rdi, rsp +> 0x00007FF7911A59C7 bsr r12, rax +> 0x00007FF7911A59CB lea r12, [0x00007FF7911A6473] +> 0x00007FF7911A59DF mov rax, 0x100000000 +> 0x00007FF7911A59EC add rsi, rax +> 0x00007FF7911A59F3 mov rbx, rsi +> 0x00007FF7911A59FA add rsi, [rbp] +> 0x00007FF7911A5A03 rcr dl, cl +> 0x00007FF7911A5A05 mov al, [rsi] +> 0x00007FF7911A5A0A xor al, bl +> 0x00007FF7911A5A11 neg al +> 0x00007FF7911A5A19 rol al, 0x05 +> 0x00007FF7911A5A26 inc al +> 0x00007FF7911A5A2F xor bl, al +> 0x00007FF7911A5A34 movzx rax, al +> 0x00007FF7911A5A41 mov rdx, [r12+rax*8] +> 0x00007FF7911A5A49 xor rdx, 0x7F3D2149 +> 0x00007FF7911A5507 inc rsi +> 0x00007FF7911A7951 add rdx, r13 +> 0x00007FF7911A7954 jmp rdx +``` + +### License & Copyright + +Copyright (c) 2021 _xeroxz, Independent Researcher @back.engineering + +Licensed under the MIT License \ No newline at end of file diff --git a/doxygen/html/index.html b/doxygen/html/index.html index 83b21d1..4b6ef2b 100644 --- a/doxygen/html/index.html +++ b/doxygen/html/index.html @@ -68,9 +68,110 @@ $(function() {
VMProfiler Documentation
-

-VMProfiler - Library To Profile VMProtect 2 Virtual Machines

-

vmprofiler is a c++ library which is used to statically analyze VMProtect 2 polymorphic virtual machines. This project is inherited in vmprofiler-qt, vmprofiler-cli, and vmemu. This is the base project for all other VMProtect 2 projects inside of this group on githacks.

+

+VMProfiler - Library To Profile VMProtect 2 Virtual Machines

+

vmprofiler is a c++ library which is used to statically analyze VMProtect 2 polymorphic virtual machines. This project is inherited in vmprofiler-qt, vmprofiler-cli, and vmemu. This is the base project for all other VMProtect 2 projects inside of this group on githacks.

+

+Credit & Contributors

+
    +
  • VTIL - Virtual-machine Translation Intermediate Language
  • +
  • Zydis - Fast and lightweight x86/x86-64 disassembler library
  • +
  • irql0 - helped with the first version of vm handler pattern matching
  • +
+

+Basic Usage - Creating a vm::ctx_t Object

+

The vm::ctx_t class is a small container-like class which is simply used to contain all information for a given vm entry. This class contains the following useful information:

+
    +
  • all vm handlers for a given vm entry
  • +
  • the linear virtual address of the module base in memory
  • +
  • the image base address
  • +
  • the image size in virtual memory
  • +
  • which way VIP advances (exec_type)
  • +
  • vm entry relative virtual address
  • +
  • vm entry deobfuscated and flattened
  • +
  • calc jmp deobfuscated and flattened
  • +
+

All of the above information is generated by executing the vm::ctx_t::init member function. Below is a C++ example of how to create a vm::ctx_t object.

+
const auto module_base = reinterpret_cast< std::uintptr_t >(
+
LoadLibraryExA( parser.get< std::string >( "bin" ).c_str(),
+
NULL, DONT_RESOLVE_DLL_REFERENCES ) );
+
+
const auto vm_entry_rva = std::strtoull( parser.get< std::string >( "vmentry" ).c_str(), nullptr, 16 );
+
const auto image_base = umtils->image_base( parser.get< std::string >( "bin" ).c_str() );
+
const auto image_size = NT_HEADER( module_base )->OptionalHeader.SizeOfImage;
+
vm::ctx_t vmctx( module_base, image_base, image_size, vm_entry_rva );
+
+
if ( !vmctx.init() )
+
{
+
std::printf( "[!] failed to init vm::ctx_t... make sure all cli arguments are correct!\n" );
+
return -1;
+
}
+
vm::ctx_t class is used to auto generate vm_entry, calc_jmp, and other per-vm entry information....
Definition: vmctx.hpp:13
+

+Using vm::ctx_t Object

+

Once you have instantiated vm::ctx_t and called vm::ctx_t::init with success, you now can directly access the data members of vm::ctx_t. Most importantly, vm::ctx_t::calc_jmp, vm::ctx_t::vm_entry, and vm::ctx_t::vm_handlers. An example usage of this data could be dumping the native x86_64 instructions which make up vm::ctx_t::vm_entry. Example c++ code for this is displayed below.

+
std::puts( "======================== [vm entry] ========================\n" );
+
vm::util::print( vmctx.vm_entry );
+
void print(zydis_routine_t &routine)
prints a disassembly view of a routine...
Definition: vmutils.cpp:69
+

Output

+
======================== [vm entry] ========================
+
> 0x00007FF7911A822C push 0xFFFFFFFF890001FA
+
> 0x00007FF7911A7FC9 push 0x45D3BF1F
+
> 0x00007FF7911A48E4 push r13
+
> 0x00007FF7911A4690 push rsi
+
> 0x00007FF7911A4E53 push r14
+
> 0x00007FF7911A74FB push rcx
+
> 0x00007FF7911A607C push rsp
+
> 0x00007FF7911A4926 pushfq
+
> 0x00007FF7911A4DC2 push rbp
+
> 0x00007FF7911A5C8C push r12
+
> 0x00007FF7911A52AC push r10
+
> 0x00007FF7911A51A5 push r9
+
> 0x00007FF7911A5189 push rdx
+
> 0x00007FF7911A7D5F push r8
+
> 0x00007FF7911A4505 push rdi
+
> 0x00007FF7911A4745 push r11
+
> 0x00007FF7911A478B push rax
+
> 0x00007FF7911A7A53 push rbx
+
> 0x00007FF7911A500D push r15
+
> 0x00007FF7911A6030 push [0x00007FF7911A7912]
+
> 0x00007FF7911A593A mov rax, 0x7FF6511A0000
+
> 0x00007FF7911A5955 mov r13, rax
+
> 0x00007FF7911A595F test dl, al
+
> 0x00007FF7911A5965 push rax
+
> 0x00007FF7911A5969 btr si, bx
+
> 0x00007FF7911A596F mov esi, [rsp+0xA0]
+
> 0x00007FF7911A5979 not esi
+
> 0x00007FF7911A5985 neg esi
+
> 0x00007FF7911A598D ror esi, 0x1A
+
> 0x00007FF7911A599E mov rbp, rsp
+
> 0x00007FF7911A59A8 sub rsp, 0x140
+
> 0x00007FF7911A59B5 and rsp, 0xFFFFFFFFFFFFFFF0
+
> 0x00007FF7911A59BE inc ax
+
> 0x00007FF7911A59C1 mov rdi, rsp
+
> 0x00007FF7911A59C7 bsr r12, rax
+
> 0x00007FF7911A59CB lea r12, [0x00007FF7911A6473]
+
> 0x00007FF7911A59DF mov rax, 0x100000000
+
> 0x00007FF7911A59EC add rsi, rax
+
> 0x00007FF7911A59F3 mov rbx, rsi
+
> 0x00007FF7911A59FA add rsi, [rbp]
+
> 0x00007FF7911A5A03 rcr dl, cl
+
> 0x00007FF7911A5A05 mov al, [rsi]
+
> 0x00007FF7911A5A0A xor al, bl
+
> 0x00007FF7911A5A11 neg al
+
> 0x00007FF7911A5A19 rol al, 0x05
+
> 0x00007FF7911A5A26 inc al
+
> 0x00007FF7911A5A2F xor bl, al
+
> 0x00007FF7911A5A34 movzx rax, al
+
> 0x00007FF7911A5A41 mov rdx, [r12+rax*8]
+
> 0x00007FF7911A5A49 xor rdx, 0x7F3D2149
+
> 0x00007FF7911A5507 inc rsi
+
> 0x00007FF7911A7951 add rdx, r13
+
> 0x00007FF7911A7954 jmp rdx
+

+License & Copyright

+

Copyright (c) 2021 _xeroxz, Independent Researcher @back.engineering

+

Licensed under the MIT License