updated to vmprofiler v1.5, preparing for JCC stuff...

merge-requests/1/head v1.4
_xeroxz 3 years ago
parent 887caa294a
commit 184e7e6ff6

@ -0,0 +1,18 @@
---
BasedOnStyle: Microsoft
AlignAfterOpenBracket: Align
AllowAllArgumentsOnNextLine: 'true'
AllowAllParametersOfDeclarationOnNextLine: 'true'
AllowShortIfStatementsOnASingleLine: Never
BreakBeforeBraces: Allman
IndentWidth: '4'
Language: Cpp
NamespaceIndentation: All
SpacesInAngles: 'true'
SpacesInCStyleCastParentheses: 'true'
SpacesInContainerLiterals: 'true'
SpacesInParentheses: 'true'
SpacesInSquareBrackets: 'true'
UseTab: Never
...

@ -1 +1 @@
Subproject commit 50fd6c75b41e3a1ae8e4061c6c31c26298902cfa Subproject commit 8ffe1cac5017b0258a44c1bbe9254621be771147

@ -1 +1 @@
Subproject commit 09d0342da61c74b08a95ee284a8b25c742ca89c1 Subproject commit 7c32517322c29a866cbb1e67fb9051efa2e05553

@ -2,14 +2,15 @@
#include <fstream> #include <fstream>
#include <unicorn/unicorn.h> #include <unicorn/unicorn.h>
#include <cli-parser.hpp> #include <cli-parser.hpp>
#include <xtils.hpp>
#include "vmemu_t.hpp" #include "vmemu_t.hpp"
int __cdecl main(int argc, const char* argv[]) int __cdecl main(int argc, const char* argv[])
{ {
argparse::argument_parser_t parser("uc-tracer", argparse::argument_parser_t parser( "VMEmu", "VMProtect 2 Static VM Handler Emulator" );
"VMProtect 2 Virtual Instruction Tracer Using Unicorn");
parser.add_argument() parser.add_argument()
.name("--vmentry").required(true) .name("--vmentry").required(true)
.description("relative virtual address to a vm entry..."); .description("relative virtual address to a vm entry...");
@ -17,18 +18,10 @@ int __cdecl main(int argc, const char* argv[])
.name("--vmpbin").required(true) .name("--vmpbin").required(true)
.description("path to unpacked virtualized binary..."); .description("path to unpacked virtualized binary...");
parser.add_argument()
.name("--imagebase").required(true)
.description("image base from optional PE header...");
parser.add_argument() parser.add_argument()
.name("--out").required(true) .name("--out").required(true)
.description("output file name for trace file..."); .description("output file name for trace file...");
parser.add_argument()
.name("--advancement").required(true)
.description("the way in which the virtual instruction pointer advances... 'forward' or 'backward'...");
parser.enable_help(); parser.enable_help();
auto result = parser.parse(argc, argv); auto result = parser.parse(argc, argv);
@ -49,13 +42,46 @@ int __cdecl main(int argc, const char* argv[])
const auto vm_entry_rva = std::strtoull( const auto vm_entry_rva = std::strtoull(
parser.get<std::string>("vmentry").c_str(), nullptr, 16); parser.get<std::string>("vmentry").c_str(), nullptr, 16);
const auto image_base = std::strtoull( const auto image_base =
parser.get<std::string>("imagebase").c_str(), nullptr, 16); xtils::um_t::get_instance()->image_base(
parser.get< std::string >( "vmpbin" ).c_str() );
const auto module_base = reinterpret_cast<std::uintptr_t>( const auto module_base = reinterpret_cast<std::uintptr_t>(
LoadLibraryExA(parser.get<std::string>("vmpbin").c_str(), LoadLibraryExA(parser.get<std::string>("vmpbin").c_str(),
NULL, DONT_RESOLVE_DLL_REFERENCES)); NULL, DONT_RESOLVE_DLL_REFERENCES));
zydis_routine_t vm_entry, calc_jmp;
if ( !vm::util::flatten( vm_entry, vm_entry_rva + module_base ) )
{
std::printf( "> failed to flatten vm entry...\n" );
return -1;
}
vm::util::deobfuscate( vm_entry );
std::printf( "> flattened vm entry...\n" );
std::printf( "> deobfuscated vm entry...\n" );
std::printf( "==================================================================================\n" );
vm::util::print( vm_entry );
if ( !vm::calc_jmp::get( vm_entry, calc_jmp ) )
{
std::printf( "> failed to get calc_jmp...\n" );
return -1;
}
vm::util::deobfuscate( calc_jmp );
std::printf( "> calc_jmp extracted from vm_entry... calc_jmp:\n" );
std::printf( "==================================================================================\n" );
vm::util::print( calc_jmp );
const auto advancment = vm::calc_jmp::get_advancement( calc_jmp );
if ( !advancment.has_value() )
{
std::printf( "> failed to determine advancment...\n" );
return -1;
}
std::vector<vmp2::entry_t> entries; std::vector<vmp2::entry_t> entries;
vm::emu_t emu(vm_entry_rva, image_base, module_base); vm::emu_t emu(vm_entry_rva, image_base, module_base);
@ -80,8 +106,7 @@ int __cdecl main(int argc, const char* argv[])
file_header.epoch_time = time(nullptr); file_header.epoch_time = time(nullptr);
file_header.entry_offset = sizeof file_header; file_header.entry_offset = sizeof file_header;
file_header.advancement = parser.get<std::string>("advancement") == file_header.advancement = advancment.value();
"forward" ? vmp2::exec_type_t::forward : vmp2::exec_type_t::backward;
file_header.version = vmp2::version_t::v1; file_header.version = vmp2::version_t::v1;
file_header.module_base = module_base; file_header.module_base = module_base;
@ -96,5 +121,4 @@ int __cdecl main(int argc, const char* argv[])
output.close(); output.close();
std::printf("> finished writing trace to disk...\n"); std::printf("> finished writing trace to disk...\n");
std::getchar();
} }

@ -129,7 +129,7 @@
<ClCompile> <ClCompile>
<WarningLevel>Level3</WarningLevel> <WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS</PreprocessorDefinitions> <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS;ZYDIS_STATIC_DEFINE</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode> <ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp17</LanguageStandard> <LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile> </ClCompile>
@ -145,7 +145,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking> <FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions> <IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck> <SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS</PreprocessorDefinitions> <PreprocessorDefinitions>NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS;ZYDIS_STATIC_DEFINE</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode> <ConformanceMode>true</ConformanceMode>
<Optimization>Disabled</Optimization> <Optimization>Disabled</Optimization>
<LanguageStandard>stdcpp17</LanguageStandard> <LanguageStandard>stdcpp17</LanguageStandard>

@ -15,10 +15,7 @@ namespace vm
bool emu_t::init() bool emu_t::init()
{ {
//
// vmprofiler init stuff... // vmprofiler init stuff...
//
if (!vm::util::flatten(vm_entry, vm_entry_rva + module_base)) if (!vm::util::flatten(vm_entry, vm_entry_rva + module_base))
{ {
std::printf("[!] failed to get vm entry...\n"); std::printf("[!] failed to get vm entry...\n");
@ -42,13 +39,10 @@ namespace vm
} }
std::printf("> got all vm handlers...\n"); std::printf("> got all vm handlers...\n");
for (const vm::handler_t& vm_handler : vm_handlers) for (const vm::handler::handler_t& vm_handler : vm_handlers)
std::printf(">>> handler addr = 0x%p\n", vm_handler.address); std::printf(">>> handler addr = 0x%p\n", vm_handler.address);
//
// unicorn init stuff... // unicorn init stuff...
//
const auto image_size = const auto image_size =
NT_HEADER(module_base)->OptionalHeader.SizeOfImage; NT_HEADER(module_base)->OptionalHeader.SizeOfImage;
@ -202,7 +196,8 @@ namespace vm
ZydisDecoderInit(&decoder, ZydisDecoderInit(&decoder,
ZYDIS_MACHINE_MODE_LONG_64, ZYDIS_ADDRESS_WIDTH_64); }); ZYDIS_MACHINE_MODE_LONG_64, ZYDIS_ADDRESS_WIDTH_64); });
if (address == obj->vm_entry[obj->vm_entry.size() - 1].addr) // last instruction in vm_entry is jmp rcx/rdx...
if (address == obj->vm_entry[obj->vm_entry.size() - 1].addr)
{ {
uc_err err; uc_err err;
vmp2::entry_t new_entry; vmp2::entry_t new_entry;
@ -238,7 +233,7 @@ namespace vm
// checks to see if the address // checks to see if the address
// in JMP RDX/RCX is a vm handler address... // in JMP RDX/RCX is a vm handler address...
static const auto vm_handler_check = static const auto vm_handler_check =
[&](const vm::handler_t& vm_handler) -> bool [&](const vm::handler::handler_t& vm_handler) -> bool
{ return vm_handler.address == reg_val; }; { return vm_handler.address == reg_val; };
if (std::find_if(obj->vm_handlers.begin(), obj->vm_handlers.end(), if (std::find_if(obj->vm_handlers.begin(), obj->vm_handlers.end(),

@ -2,8 +2,8 @@
#include <exception> #include <exception>
#include <cstdint> #include <cstdint>
#include <unicorn/unicorn.h> #include <unicorn/unicorn.h>
#include <xtils/xtils.hpp> #include <xtils.hpp>
#include <vm.h> #include <vmprofiler.hpp>
#include <functional> #include <functional>
#include <mutex> #include <mutex>
#include <vmp2.hpp> #include <vmp2.hpp>
@ -35,7 +35,7 @@ namespace vm
zydis_routine_t vm_entry; zydis_routine_t vm_entry;
std::uintptr_t* vm_handler_table; std::uintptr_t* vm_handler_table;
std::vector<vm::handler_t> vm_handlers; std::vector<vm::handler::handler_t> vm_handlers;
std::vector<vmp2::entry_t>* trace_entries; std::vector<vmp2::entry_t>* trace_entries;
}; };
} }
Loading…
Cancel
Save