diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..8063c5e --- /dev/null +++ b/.clang-format @@ -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 + +... diff --git a/dependencies/vmprofiler b/dependencies/vmprofiler index 50fd6c7..8ffe1ca 160000 --- a/dependencies/vmprofiler +++ b/dependencies/vmprofiler @@ -1 +1 @@ -Subproject commit 50fd6c75b41e3a1ae8e4061c6c31c26298902cfa +Subproject commit 8ffe1cac5017b0258a44c1bbe9254621be771147 diff --git a/dependencies/xtils b/dependencies/xtils index 09d0342..7c32517 160000 --- a/dependencies/xtils +++ b/dependencies/xtils @@ -1 +1 @@ -Subproject commit 09d0342da61c74b08a95ee284a8b25c742ca89c1 +Subproject commit 7c32517322c29a866cbb1e67fb9051efa2e05553 diff --git a/src/main.cpp b/src/main.cpp index c3daf9b..97dc22a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2,14 +2,15 @@ #include #include #include +#include + #include "vmemu_t.hpp" int __cdecl main(int argc, const char* argv[]) { - argparse::argument_parser_t parser("uc-tracer", - "VMProtect 2 Virtual Instruction Tracer Using Unicorn"); + argparse::argument_parser_t parser( "VMEmu", "VMProtect 2 Static VM Handler Emulator" ); - parser.add_argument() + parser.add_argument() .name("--vmentry").required(true) .description("relative virtual address to a vm entry..."); @@ -17,18 +18,10 @@ int __cdecl main(int argc, const char* argv[]) .name("--vmpbin").required(true) .description("path to unpacked virtualized binary..."); - parser.add_argument() - .name("--imagebase").required(true) - .description("image base from optional PE header..."); - parser.add_argument() .name("--out").required(true) .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(); 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( parser.get("vmentry").c_str(), nullptr, 16); - const auto image_base = std::strtoull( - parser.get("imagebase").c_str(), nullptr, 16); + const auto image_base = + xtils::um_t::get_instance()->image_base( + parser.get< std::string >( "vmpbin" ).c_str() ); const auto module_base = reinterpret_cast( LoadLibraryExA(parser.get("vmpbin").c_str(), 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 entries; 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.entry_offset = sizeof file_header; - file_header.advancement = parser.get("advancement") == - "forward" ? vmp2::exec_type_t::forward : vmp2::exec_type_t::backward; + file_header.advancement = advancment.value(); file_header.version = vmp2::version_t::v1; file_header.module_base = module_base; @@ -96,5 +121,4 @@ int __cdecl main(int argc, const char* argv[]) output.close(); std::printf("> finished writing trace to disk...\n"); - std::getchar(); } diff --git a/src/vmemu.vcxproj b/src/vmemu.vcxproj index 5226722..7c4ee4e 100644 --- a/src/vmemu.vcxproj +++ b/src/vmemu.vcxproj @@ -129,7 +129,7 @@ Level3 true - _DEBUG;_CONSOLE;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS + _DEBUG;_CONSOLE;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS;ZYDIS_STATIC_DEFINE true stdcpp17 @@ -145,7 +145,7 @@ true true true - NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS + NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS;ZYDIS_STATIC_DEFINE true Disabled stdcpp17 diff --git a/src/vmemu_t.cpp b/src/vmemu_t.cpp index de6e834..34f35d6 100644 --- a/src/vmemu_t.cpp +++ b/src/vmemu_t.cpp @@ -15,10 +15,7 @@ namespace vm bool emu_t::init() { - // // vmprofiler init stuff... - // - if (!vm::util::flatten(vm_entry, vm_entry_rva + module_base)) { std::printf("[!] failed to get vm entry...\n"); @@ -42,13 +39,10 @@ namespace vm } 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); - // // unicorn init stuff... - // - const auto image_size = NT_HEADER(module_base)->OptionalHeader.SizeOfImage; @@ -202,7 +196,8 @@ namespace vm ZydisDecoderInit(&decoder, 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; vmp2::entry_t new_entry; @@ -238,7 +233,7 @@ namespace vm // checks to see if the address // in JMP RDX/RCX is a vm handler address... 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; }; if (std::find_if(obj->vm_handlers.begin(), obj->vm_handlers.end(), diff --git a/src/vmemu_t.hpp b/src/vmemu_t.hpp index 6aff94a..85fe5ea 100644 --- a/src/vmemu_t.hpp +++ b/src/vmemu_t.hpp @@ -2,8 +2,8 @@ #include #include #include -#include -#include +#include +#include #include #include #include @@ -35,7 +35,7 @@ namespace vm zydis_routine_t vm_entry; std::uintptr_t* vm_handler_table; - std::vector vm_handlers; + std::vector vm_handlers; std::vector* trace_entries; }; } \ No newline at end of file