From a0dca0bc5bf43147e4c4f3ef09434660d7d5f81e Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Wed, 16 Jun 2021 13:47:14 -0700 Subject: [PATCH 01/10] working on readme's and new profiles... --- ADD_VMP2_INSTR.md | 3 +++ README.md | 57 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 ADD_VMP2_INSTR.md diff --git a/ADD_VMP2_INSTR.md b/ADD_VMP2_INSTR.md new file mode 100644 index 0000000..2b3b0c4 --- /dev/null +++ b/ADD_VMP2_INSTR.md @@ -0,0 +1,3 @@ +# Introduction + +This page contains the steps needed to add additional VMProtect 2 virtual instruction profiles to VMProfiler. Understand that these instructions are for version 1.8 and may be different in later versions. \ No newline at end of file diff --git a/README.md b/README.md index 3f63fe4..e13a121 100644 --- a/README.md +++ b/README.md @@ -117,6 +117,63 @@ vm::util::print( vmctx.vm_entry ); > 0x00007FF7911A7954 jmp rdx ``` +You can also loop through all vm handlers easily. Below is an example of looping through the vm handler vector inside of `vm::ctx_t::vm_handlers`. + +```cpp +for ( auto idx = 0u; idx < vmctx.vm_handlers.size(); ++idx ) +{ + std::printf( "======================== [%s #%d] ========================\n", + vmctx.vm_handlers[ idx ].profile ? vmctx.vm_handlers[ idx ].profile->name : "UNK", idx ); + + vm::util::print( vmctx.vm_handlers[ idx ].instrs ); + + // if there is no imm then there are no transforms... + if ( !vmctx.vm_handlers[ idx ].imm_size ) + { + std::puts( "\n" ); + continue; + } + + std::puts( "======================== [transforms] ========================\n" ); + for ( auto &[ mnemonic, instr ] : vmctx.vm_handlers[ idx ].transforms ) + { + if ( instr.mnemonic == ZYDIS_MNEMONIC_INVALID ) + continue; + + vm::util::print( instr ); + } + std::puts( "\n" ); +} +``` + +***Output*** + +``` +... + +======================== [LCONSTBZXW #253] ======================== +> 0x00007FF6DEA85C2C and al, 0x45 +> 0x00007FF6DEA85C2E movzx eax, byte ptr [rsi] +> 0x00007FF6DEA85C82 add al, bl +> 0x00007FF6DEA85C85 add al, 0xD3 +> 0x00007FF6DEA86FC7 not al +> 0x00007FF6DEA84D23 inc al +> 0x00007FF6DEA85633 add bl, al +> 0x00007FF6DEA853D5 sub rsi, 0xFFFFFFFFFFFFFFFF +> 0x00007FF6DEA85CD1 sub rbp, 0x02 +> 0x00007FF6DEA862F8 mov [rbp], ax +> 0x00007FF6DEA844A7 rol ah, 0x07 +======================== [transforms] ======================== + +add al, bl +add al, 0xD3 +not al +inc al +add bl, al + +... +``` + ### License & Copyright Copyright (c) 2021 _xeroxz, Independent Researcher @back.engineering From c3c815b1d43ec86392648bcd78dd458b892933bb Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Wed, 16 Jun 2021 20:50:45 +0000 Subject: [PATCH 02/10] Update ADD_VMP2_INSTR.md --- ADD_VMP2_INSTR.md | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/ADD_VMP2_INSTR.md b/ADD_VMP2_INSTR.md index 2b3b0c4..0fbfcc3 100644 --- a/ADD_VMP2_INSTR.md +++ b/ADD_VMP2_INSTR.md @@ -1,3 +1,32 @@ # Introduction -This page contains the steps needed to add additional VMProtect 2 virtual instruction profiles to VMProfiler. Understand that these instructions are for version 1.8 and may be different in later versions. \ No newline at end of file +This page contains the steps needed to add additional VMProtect 2 virtual instruction profiles to VMProfiler. Understand that these instructions are for version 1.8 and may be different in later versions. + +# Example - Existing Profile + +Consider the `ADDQ` profile which is displayed below which can be found inside of `add.cpp` + +```cpp +vm::handler::profile_t addq = { + // ADD [RBP+8], RAX + // PUSHFQ + // POP [RBP] + "ADDQ", + ADDQ, + NULL, + { { // ADD [RBP+8], RAX + []( const zydis_decoded_instr_t &instr ) -> bool { + return instr.mnemonic == ZYDIS_MNEMONIC_ADD && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY && + instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP && + instr.operands[ 0 ].mem.disp.value == 0x8 && + instr.operands[ 1 ].type == ZYDIS_OPERAND_TYPE_REGISTER && + instr.operands[ 1 ].reg.value == ZYDIS_REGISTER_RAX; + }, + // PUSHFQ + []( const zydis_decoded_instr_t &instr ) -> bool { return instr.mnemonic == ZYDIS_MNEMONIC_PUSHFQ; }, + // POP [RBP] + []( const zydis_decoded_instr_t &instr ) -> bool { + return instr.mnemonic == ZYDIS_MNEMONIC_POP && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY && + instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP; + } } } }; +``` \ No newline at end of file From 95229b98c7736ebc0a9970857f04f7e7d261db9f Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Wed, 16 Jun 2021 20:52:46 +0000 Subject: [PATCH 03/10] Update ADD_VMP2_INSTR.md --- ADD_VMP2_INSTR.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/ADD_VMP2_INSTR.md b/ADD_VMP2_INSTR.md index 0fbfcc3..bf126c7 100644 --- a/ADD_VMP2_INSTR.md +++ b/ADD_VMP2_INSTR.md @@ -29,4 +29,32 @@ vm::handler::profile_t addq = { return instr.mnemonic == ZYDIS_MNEMONIC_POP && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_MEMORY && instr.operands[ 0 ].mem.base == ZYDIS_REGISTER_RBP; } } } }; +``` + +Inside of `vmprofiles.hpp` you can see a list of these profiles marked as `extern`. + +```cpp +namespace profile +{ + extern vm::handler::profile_t sregq; + extern vm::handler::profile_t sregdw; + extern vm::handler::profile_t sregw; + + extern vm::handler::profile_t lregq; + extern vm::handler::profile_t lregdw; + + extern vm::handler::profile_t lconstq; + extern vm::handler::profile_t lconstdw; + extern vm::handler::profile_t lconstw; + + extern vm::handler::profile_t lconstbzxw; + extern vm::handler::profile_t lconstbsxdw; + extern vm::handler::profile_t lconstbsxq; + extern vm::handler::profile_t lconstdwsxq; + extern vm::handler::profile_t lconstwsxq; + extern vm::handler::profile_t lconstwsxdw; + + extern vm::handler::profile_t addq; // as you can see a reference to addq is declared here... + ... +} ``` \ No newline at end of file From fb7f722bb702c4974aebe74fee3547105c8effe8 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Wed, 16 Jun 2021 20:53:45 +0000 Subject: [PATCH 04/10] Update ADD_VMP2_INSTR.md --- ADD_VMP2_INSTR.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ADD_VMP2_INSTR.md b/ADD_VMP2_INSTR.md index bf126c7..718521a 100644 --- a/ADD_VMP2_INSTR.md +++ b/ADD_VMP2_INSTR.md @@ -4,7 +4,7 @@ This page contains the steps needed to add additional VMProtect 2 virtual instru # Example - Existing Profile -Consider the `ADDQ` profile which is displayed below which can be found inside of `add.cpp` +Consider the `ADDQ` profile which is displayed below which can be found inside of `add.cpp`. Notice that not every single instruction of the vm handler needs to be declared inside of the zydis lambda vector, however you will be required to be as explicit as it requires for each vm handler to have a unique signature. ```cpp vm::handler::profile_t addq = { From 0a5ac162b54a4e81665dd328c99f3ffe372b288c Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Wed, 16 Jun 2021 20:55:04 +0000 Subject: [PATCH 05/10] Update ADD_VMP2_INSTR.md --- ADD_VMP2_INSTR.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/ADD_VMP2_INSTR.md b/ADD_VMP2_INSTR.md index 718521a..fb8d4cb 100644 --- a/ADD_VMP2_INSTR.md +++ b/ADD_VMP2_INSTR.md @@ -57,4 +57,6 @@ namespace profile extern vm::handler::profile_t addq; // as you can see a reference to addq is declared here... ... } -``` \ No newline at end of file +``` + +Lastly the `addq` variable is added to a vector of `vm::handler::profile_t*`'s. \ No newline at end of file From 288cff93ce45c92a5adacdecaf522e45202e7ac1 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Wed, 16 Jun 2021 20:55:23 +0000 Subject: [PATCH 06/10] Update ADD_VMP2_INSTR.md --- ADD_VMP2_INSTR.md | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/ADD_VMP2_INSTR.md b/ADD_VMP2_INSTR.md index fb8d4cb..966f9a7 100644 --- a/ADD_VMP2_INSTR.md +++ b/ADD_VMP2_INSTR.md @@ -59,4 +59,19 @@ namespace profile } ``` -Lastly the `addq` variable is added to a vector of `vm::handler::profile_t*`'s. \ No newline at end of file +Lastly the `addq` variable is added to a vector of `vm::handler::profile_t*`'s. + +```cpp + inline std::vector< vm::handler::profile_t * > all = { + &sregq, &sregdw, &sregw, &lregq, &lregdw, &lconstq, + &lconstbzxw, &lconstbsxdw, &lconstbsxq, &lconstdwsxq, &lconstwsxq, &lconstwsxdw, + &lconstdw, &lconstw, &addq, &adddw, &addw, &lvsp, + + &shlq, &shldw, &writeq, &writedw, &writeb, &nandq, + &nanddw, &nandw, &nandb, + + &shlddw, + + &shrq, &shrw, &readq, &readdw, &mulq, &pushvsp, + &divq, &jmp, &lrflags, &vmexit, &call }; +``` \ No newline at end of file From dc59a073eebd69accbbc978e9658473963d49672 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Wed, 16 Jun 2021 20:55:43 +0000 Subject: [PATCH 07/10] Update ADD_VMP2_INSTR.md --- ADD_VMP2_INSTR.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/ADD_VMP2_INSTR.md b/ADD_VMP2_INSTR.md index 966f9a7..383dc7a 100644 --- a/ADD_VMP2_INSTR.md +++ b/ADD_VMP2_INSTR.md @@ -62,16 +62,16 @@ namespace profile Lastly the `addq` variable is added to a vector of `vm::handler::profile_t*`'s. ```cpp - inline std::vector< vm::handler::profile_t * > all = { - &sregq, &sregdw, &sregw, &lregq, &lregdw, &lconstq, - &lconstbzxw, &lconstbsxdw, &lconstbsxq, &lconstdwsxq, &lconstwsxq, &lconstwsxdw, - &lconstdw, &lconstw, &addq, &adddw, &addw, &lvsp, +inline std::vector< vm::handler::profile_t * > all = { + &sregq, &sregdw, &sregw, &lregq, &lregdw, &lconstq, + &lconstbzxw, &lconstbsxdw, &lconstbsxq, &lconstdwsxq, &lconstwsxq, &lconstwsxdw, + &lconstdw, &lconstw, &addq, &adddw, &addw, &lvsp, - &shlq, &shldw, &writeq, &writedw, &writeb, &nandq, - &nanddw, &nandw, &nandb, + &shlq, &shldw, &writeq, &writedw, &writeb, &nandq, + &nanddw, &nandw, &nandb, - &shlddw, + &shlddw, - &shrq, &shrw, &readq, &readdw, &mulq, &pushvsp, - &divq, &jmp, &lrflags, &vmexit, &call }; + &shrq, &shrw, &readq, &readdw, &mulq, &pushvsp, + &divq, &jmp, &lrflags, &vmexit, &call }; ``` \ No newline at end of file From 59511365c445187fd39ba03e1709803d2318b9e9 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Wed, 16 Jun 2021 20:57:04 +0000 Subject: [PATCH 08/10] Update ADD_VMP2_INSTR.md --- ADD_VMP2_INSTR.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ADD_VMP2_INSTR.md b/ADD_VMP2_INSTR.md index 383dc7a..3ad33cc 100644 --- a/ADD_VMP2_INSTR.md +++ b/ADD_VMP2_INSTR.md @@ -6,6 +6,8 @@ This page contains the steps needed to add additional VMProtect 2 virtual instru Consider the `ADDQ` profile which is displayed below which can be found inside of `add.cpp`. Notice that not every single instruction of the vm handler needs to be declared inside of the zydis lambda vector, however you will be required to be as explicit as it requires for each vm handler to have a unique signature. +#### Step 1, Define The Profile + ```cpp vm::handler::profile_t addq = { // ADD [RBP+8], RAX @@ -33,6 +35,8 @@ vm::handler::profile_t addq = { Inside of `vmprofiles.hpp` you can see a list of these profiles marked as `extern`. +#### Step 2, Declare It Extern Inside `vmprofiles.hpp` + ```cpp namespace profile { @@ -61,6 +65,8 @@ namespace profile Lastly the `addq` variable is added to a vector of `vm::handler::profile_t*`'s. +#### Step 3, Add The Variable To `vm::handler::profile::all` + ```cpp inline std::vector< vm::handler::profile_t * > all = { &sregq, &sregdw, &sregw, &lregq, &lregdw, &lconstq, From d3cbb3318ccf35bba2b4ba871b7b2db2b6f4ddc6 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Wed, 16 Jun 2021 13:58:50 -0700 Subject: [PATCH 09/10] adding manuals... --- ADD_VMP2_INSTR.md => manual/ADD_VMP2_INSTR.md | 0 manual/ADD_VTIL_LIFTER.md | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename ADD_VMP2_INSTR.md => manual/ADD_VMP2_INSTR.md (100%) create mode 100644 manual/ADD_VTIL_LIFTER.md diff --git a/ADD_VMP2_INSTR.md b/manual/ADD_VMP2_INSTR.md similarity index 100% rename from ADD_VMP2_INSTR.md rename to manual/ADD_VMP2_INSTR.md diff --git a/manual/ADD_VTIL_LIFTER.md b/manual/ADD_VTIL_LIFTER.md new file mode 100644 index 0000000..e69de29 From 694e5fc386b88a67f3df5167131107380875d077 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Wed, 16 Jun 2021 21:10:58 +0000 Subject: [PATCH 10/10] Update ADD_VTIL_LIFTER.md --- manual/ADD_VTIL_LIFTER.md | 67 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/manual/ADD_VTIL_LIFTER.md b/manual/ADD_VTIL_LIFTER.md index e69de29..a12680e 100644 --- a/manual/ADD_VTIL_LIFTER.md +++ b/manual/ADD_VTIL_LIFTER.md @@ -0,0 +1,67 @@ +# Introduction + +This will disclose how to create a VTIL lifter for VMProfiler v1.8. The instructions may change in later versions of VMProfiler. + +# Example - Existing VTIL Lifter For LCONSTQ + +Understand that LCONSTQ loads an eight byte value onto the stack. Thus the usage of `vtil::operand` to create a 64 bit value. + +#### Step 1, Declare Lifter + +``` +vm::lifters::lifter_t lconstq = { + // push imm + vm::handler::LCONSTQ, + []( vtil::basic_block *blk, vm::instrs::virt_instr_t *vinstr, vmp2::v3::code_block_t *code_blk ) { + blk->push( vtil::operand( vinstr->operand.imm.u, 64 ) ); + } }; +``` + +#### Step 2, Declare Extern In `vmlifters.hpp` + +You can see this exact line of code [here](https://githacks.org/vmp2/vmprofiler/-/blob/8baefa1e2148111712d640ee9cb7c0b7ac329521/include/vmlifters.hpp#L22). + +```cpp +extern vm::lifters::lifter_t lconstq; +``` + +#### Step 3, Add Lifter To `vm::lifters::all` + +```cpp +inline std::vector< vm::lifters::lifter_t * > all = { + // lreg lifters... + &lregq, &lregdw, + + // add lifters... + &addq, &adddw, &addw, + + // sreg lifters... + &sregq, &sregdw, &sregw, + + // lconst lifters... + &lconstq, &lconstdw, &lconstw, &lconstbzxw, &lconstbsxdw, &lconstbsxq, &lconstdwsxq, &lconstwsxq, &lconstwsxdw, + + // nand lifters... + &nandq, &nanddw, &nandw, + + // read lifters.... + &readq, &readdw, &readw, + + // shr lifters... + &shrq, &shrw, + + // pushvsp lifter... + &pushvsp, + + // jmp lifter... + &jmp, + + // lflags lifter... + &lrflags, + + // lvsp lifter... + &lvsp, + + // vmexit lifter... + &vmexit }; +``` \ No newline at end of file