From 320c7e96384d10e479d50bb4399ff24ca15b08d7 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Fri, 30 Jul 2021 14:03:42 -0700 Subject: [PATCH 01/12] removed vtil, preparing to recode and add dump support... --- .gitignore | 1 + .gitmodules | 3 - CMakeLists.txt | 84 +++++ cmake.toml | 23 ++ cmkr.cmake | 162 +++++++++ dependencies/CMakeLists.txt | 46 +++ dependencies/cmake.toml | 6 + dependencies/vmprofiler | 2 +- dependencies/xtils | 1 - include/unpacker.hpp | 0 include/vmemu_t.hpp | 15 + src/main.cpp | 12 +- src/unpacker.cpp | 0 src/vmemu_t.cpp | 382 +-------------------- src/vmemu_t.hpp | 47 --- vmemu.sln | 662 ------------------------------------ vmemu.vcxproj | 181 ---------- vmemu.vcxproj.filters | 230 ------------- 18 files changed, 350 insertions(+), 1507 deletions(-) create mode 100644 CMakeLists.txt create mode 100644 cmake.toml create mode 100644 cmkr.cmake create mode 100644 dependencies/CMakeLists.txt create mode 100644 dependencies/cmake.toml delete mode 160000 dependencies/xtils create mode 100644 include/unpacker.hpp create mode 100644 include/vmemu_t.hpp create mode 100644 src/unpacker.cpp delete mode 100644 src/vmemu_t.hpp delete mode 100644 vmemu.sln delete mode 100644 vmemu.vcxproj delete mode 100644 vmemu.vcxproj.filters diff --git a/.gitignore b/.gitignore index 72de34f..984df86 100644 --- a/.gitignore +++ b/.gitignore @@ -17,6 +17,7 @@ mono_crash.* # Build results +build/ [Dd]ebug/ [Dd]ebugPublic/ [Rr]elease/ diff --git a/.gitmodules b/.gitmodules index 73639d7..a8831ac 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,3 @@ -[submodule "dependencies/xtils"] - path = dependencies/xtils - url = https://githacks.org/_xeroxz/xtils.git [submodule "dependencies/unicorn"] path = dependencies/unicorn url = https://github.com/unicorn-engine/unicorn.git diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..73e3fce --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,84 @@ +# This file is automatically generated from cmake.toml - DO NOT EDIT +# See https://github.com/build-cpp/cmkr for more information + +cmake_minimum_required(VERSION 3.15) + +# Regenerate CMakeLists.txt automatically in the root project +set(CMKR_ROOT_PROJECT OFF) +if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR) + set(CMKR_ROOT_PROJECT ON) + + # Bootstrap cmkr + include(cmkr.cmake OPTIONAL RESULT_VARIABLE CMKR_INCLUDE_RESULT) + if(CMKR_INCLUDE_RESULT) + cmkr() + endif() + + # Enable folder support + set_property(GLOBAL PROPERTY USE_FOLDERS ON) +endif() + +# Create a configure-time dependency on cmake.toml to improve IDE support +if(CMKR_ROOT_PROJECT) + configure_file(cmake.toml cmake.toml COPYONLY) +endif() + +project(vmemu) + +# dependencies +set(CMKR_CMAKE_FOLDER ${CMAKE_FOLDER}) +if(CMAKE_FOLDER) + set(CMAKE_FOLDER "${CMAKE_FOLDER}/dependencies") +else() + set(CMAKE_FOLDER dependencies) +endif() +add_subdirectory(dependencies) +set(CMAKE_FOLDER ${CMKR_CMAKE_FOLDER}) + +# Target vmemu +set(CMKR_TARGET vmemu) +set(vmemu_SOURCES "") + +list(APPEND vmemu_SOURCES + "src/main.cpp" + "src/unpacker.cpp" + "src/vmemu_t.cpp" + "include/unpacker.hpp" + "include/vmemu_t.hpp" +) + +list(APPEND vmemu_SOURCES + cmake.toml +) + +set(CMKR_SOURCES ${vmemu_SOURCES}) +add_executable(vmemu) + +if(vmemu_SOURCES) + target_sources(vmemu PRIVATE ${vmemu_SOURCES}) +endif() + +get_directory_property(CMKR_VS_STARTUP_PROJECT DIRECTORY ${PROJECT_SOURCE_DIR} DEFINITION VS_STARTUP_PROJECT) +if(NOT CMKR_VS_STARTUP_PROJECT) + set_property(DIRECTORY ${PROJECT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT vmemu) +endif() + +source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} FILES ${vmemu_SOURCES}) + +target_compile_definitions(vmemu PRIVATE + NOMINMAX +) + +target_include_directories(vmemu PRIVATE + include +) + +target_link_libraries(vmemu PRIVATE + vmprofiler + unicorn + cli-parser +) + +unset(CMKR_TARGET) +unset(CMKR_SOURCES) + diff --git a/cmake.toml b/cmake.toml new file mode 100644 index 0000000..7ef4ac5 --- /dev/null +++ b/cmake.toml @@ -0,0 +1,23 @@ +[project] +name = "vmemu" + +[subdir.dependencies] + +[target.vmemu] +type = "executable" + +sources = [ + "src/**.cpp", + "include/**.hpp", +] +include-directories = [ + "include", +] +link-libraries = [ + "vmprofiler", + "unicorn", + "cli-parser", +] +compile-definitions = [ + "NOMINMAX" +] \ No newline at end of file diff --git a/cmkr.cmake b/cmkr.cmake new file mode 100644 index 0000000..cc90624 --- /dev/null +++ b/cmkr.cmake @@ -0,0 +1,162 @@ +include_guard() + +# Change these defaults to point to your infrastructure if desired +set(CMKR_REPO "https://github.com/build-cpp/cmkr" CACHE STRING "cmkr git repository" FORCE) +set(CMKR_TAG "archive_264e4ace" CACHE STRING "cmkr git tag (this needs to be available forever)" FORCE) + +# Set these from the command line to customize for development/debugging purposes +set(CMKR_EXECUTABLE "" CACHE FILEPATH "cmkr executable") +set(CMKR_SKIP_GENERATION OFF CACHE BOOL "skip automatic cmkr generation") + +# Disable cmkr if generation is disabled +if(DEFINED ENV{CI} OR CMKR_SKIP_GENERATION) + message(STATUS "[cmkr] Skipping automatic cmkr generation") + macro(cmkr) + endmacro() + return() +endif() + +# Disable cmkr if no cmake.toml file is found +if(NOT EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/cmake.toml") + message(AUTHOR_WARNING "[cmkr] Not found: ${CMAKE_CURRENT_SOURCE_DIR}/cmake.toml") + macro(cmkr) + endmacro() + return() +endif() + +# Convert a Windows native path to CMake path +if(CMKR_EXECUTABLE MATCHES "\\\\") + string(REPLACE "\\" "/" CMKR_EXECUTABLE_CMAKE "${CMKR_EXECUTABLE}") + set(CMKR_EXECUTABLE "${CMKR_EXECUTABLE_CMAKE}" CACHE FILEPATH "" FORCE) + unset(CMKR_EXECUTABLE_CMAKE) +endif() + +# Helper macro to execute a process (COMMAND_ERROR_IS_FATAL ANY is 3.19 and higher) +function(cmkr_exec) + execute_process(COMMAND ${ARGV} RESULT_VARIABLE CMKR_EXEC_RESULT) + if(NOT CMKR_EXEC_RESULT EQUAL 0) + message(FATAL_ERROR "cmkr_exec(${ARGV}) failed (exit code ${CMKR_EXEC_RESULT})") + endif() +endfunction() + +# Windows-specific hack (CMAKE_EXECUTABLE_PREFIX is not set at the moment) +if(WIN32) + set(CMKR_EXECUTABLE_NAME "cmkr.exe") +else() + set(CMKR_EXECUTABLE_NAME "cmkr") +endif() + +# Use cached cmkr if found +set(CMKR_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/_cmkr_${CMKR_TAG}") +set(CMKR_CACHED_EXECUTABLE "${CMKR_DIRECTORY}/bin/${CMKR_EXECUTABLE_NAME}") + +if(NOT CMKR_CACHED_EXECUTABLE STREQUAL CMKR_EXECUTABLE AND CMKR_EXECUTABLE MATCHES "^${CMAKE_CURRENT_BINARY_DIR}/_cmkr") + message(AUTHOR_WARNING "[cmkr] Upgrading '${CMKR_EXECUTABLE}' to '${CMKR_CACHED_EXECUTABLE}'") + unset(CMKR_EXECUTABLE CACHE) +endif() + +if(CMKR_EXECUTABLE AND EXISTS "${CMKR_EXECUTABLE}") + message(VERBOSE "[cmkr] Found cmkr: '${CMKR_EXECUTABLE}'") +elseif(CMKR_EXECUTABLE AND NOT CMKR_EXECUTABLE STREQUAL CMKR_CACHED_EXECUTABLE) + message(FATAL_ERROR "[cmkr] '${CMKR_EXECUTABLE}' not found") +else() + set(CMKR_EXECUTABLE "${CMKR_CACHED_EXECUTABLE}" CACHE FILEPATH "Full path to cmkr executable" FORCE) + message(VERBOSE "[cmkr] Bootstrapping '${CMKR_EXECUTABLE}'") + + message(STATUS "[cmkr] Fetching cmkr...") + if(EXISTS "${CMKR_DIRECTORY}") + cmkr_exec("${CMAKE_COMMAND}" -E rm -rf "${CMKR_DIRECTORY}") + endif() + find_package(Git QUIET REQUIRED) + cmkr_exec("${GIT_EXECUTABLE}" + clone + --config advice.detachedHead=false + --branch ${CMKR_TAG} + --depth 1 + ${CMKR_REPO} + "${CMKR_DIRECTORY}" + ) + message(STATUS "[cmkr] Building cmkr...") + cmkr_exec("${CMAKE_COMMAND}" + --no-warn-unused-cli + "${CMKR_DIRECTORY}" + "-B${CMKR_DIRECTORY}/build" + "-DCMAKE_BUILD_TYPE=Release" + "-DCMAKE_INSTALL_PREFIX=${CMKR_DIRECTORY}" + "-DCMKR_GENERATE_DOCUMENTATION=OFF" + ) + cmkr_exec("${CMAKE_COMMAND}" + --build "${CMKR_DIRECTORY}/build" + --config Release + --parallel + ) + cmkr_exec("${CMAKE_COMMAND}" + --install "${CMKR_DIRECTORY}/build" + --config Release + --prefix "${CMKR_DIRECTORY}" + --component cmkr + ) + if(NOT EXISTS ${CMKR_EXECUTABLE}) + message(FATAL_ERROR "[cmkr] Failed to bootstrap '${CMKR_EXECUTABLE}'") + endif() + cmkr_exec("${CMKR_EXECUTABLE}" version) + message(STATUS "[cmkr] Bootstrapped ${CMKR_EXECUTABLE}") +endif() +execute_process(COMMAND "${CMKR_EXECUTABLE}" version + RESULT_VARIABLE CMKR_EXEC_RESULT +) +if(NOT CMKR_EXEC_RESULT EQUAL 0) + message(FATAL_ERROR "[cmkr] Failed to get version, try clearing the cache and rebuilding") +endif() + +# This is the macro that contains black magic +macro(cmkr) + # When this macro is called from the generated file, fake some internal CMake variables + get_source_file_property(CMKR_CURRENT_LIST_FILE "${CMAKE_CURRENT_LIST_FILE}" CMKR_CURRENT_LIST_FILE) + if(CMKR_CURRENT_LIST_FILE) + set(CMAKE_CURRENT_LIST_FILE "${CMKR_CURRENT_LIST_FILE}") + get_filename_component(CMAKE_CURRENT_LIST_DIR "${CMAKE_CURRENT_LIST_FILE}" DIRECTORY) + endif() + + # File-based include guard (include_guard is not documented to work) + get_source_file_property(CMKR_INCLUDE_GUARD "${CMAKE_CURRENT_LIST_FILE}" CMKR_INCLUDE_GUARD) + if(NOT CMKR_INCLUDE_GUARD) + set_source_files_properties("${CMAKE_CURRENT_LIST_FILE}" PROPERTIES CMKR_INCLUDE_GUARD TRUE) + + file(SHA256 "${CMAKE_CURRENT_LIST_FILE}" CMKR_LIST_FILE_SHA256_PRE) + + # Generate CMakeLists.txt + cmkr_exec("${CMKR_EXECUTABLE}" gen + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + ) + + file(SHA256 "${CMAKE_CURRENT_LIST_FILE}" CMKR_LIST_FILE_SHA256_POST) + + # Delete the temporary file if it was left for some reason + set(CMKR_TEMP_FILE "${CMAKE_CURRENT_SOURCE_DIR}/CMakerLists.txt") + if(EXISTS "${CMKR_TEMP_FILE}") + file(REMOVE "${CMKR_TEMP_FILE}") + endif() + + if(NOT CMKR_LIST_FILE_SHA256_PRE STREQUAL CMKR_LIST_FILE_SHA256_POST) + # Copy the now-generated CMakeLists.txt to CMakerLists.txt + # This is done because you cannot include() a file you are currently in + configure_file(CMakeLists.txt "${CMKR_TEMP_FILE}" COPYONLY) + + # Add the macro required for the hack at the start of the cmkr macro + set_source_files_properties("${CMKR_TEMP_FILE}" PROPERTIES + CMKR_CURRENT_LIST_FILE "${CMAKE_CURRENT_LIST_FILE}" + ) + + # 'Execute' the newly-generated CMakeLists.txt + include("${CMKR_TEMP_FILE}") + + # Delete the generated file + file(REMOVE "${CMKR_TEMP_FILE}") + + # Do not execute the rest of the original CMakeLists.txt + return() + endif() + # Resume executing the unmodified CMakeLists.txt + endif() +endmacro() diff --git a/dependencies/CMakeLists.txt b/dependencies/CMakeLists.txt new file mode 100644 index 0000000..0586732 --- /dev/null +++ b/dependencies/CMakeLists.txt @@ -0,0 +1,46 @@ +# This file is automatically generated from cmake.toml - DO NOT EDIT +# See https://github.com/build-cpp/cmkr for more information + +# Create a configure-time dependency on cmake.toml to improve IDE support +if(CMKR_ROOT_PROJECT) + configure_file(cmake.toml cmake.toml COPYONLY) +endif() + +# vmprofiler +set(CMKR_CMAKE_FOLDER ${CMAKE_FOLDER}) +if(CMAKE_FOLDER) + set(CMAKE_FOLDER "${CMAKE_FOLDER}/vmprofiler") +else() + set(CMAKE_FOLDER vmprofiler) +endif() +add_subdirectory(vmprofiler) +set(CMAKE_FOLDER ${CMKR_CMAKE_FOLDER}) + +# unicorn +set(CMKR_CMAKE_FOLDER ${CMAKE_FOLDER}) +if(CMAKE_FOLDER) + set(CMAKE_FOLDER "${CMAKE_FOLDER}/unicorn") +else() + set(CMAKE_FOLDER unicorn) +endif() +add_subdirectory(unicorn) +set(CMAKE_FOLDER ${CMKR_CMAKE_FOLDER}) + +# Target cli-parser +set(CMKR_TARGET cli-parser) +set(cli-parser_SOURCES "") + +set(CMKR_SOURCES ${cli-parser_SOURCES}) +add_library(cli-parser INTERFACE) + +if(cli-parser_SOURCES) + target_sources(cli-parser INTERFACE ${cli-parser_SOURCES}) +endif() + +target_include_directories(cli-parser INTERFACE + cli-parser +) + +unset(CMKR_TARGET) +unset(CMKR_SOURCES) + diff --git a/dependencies/cmake.toml b/dependencies/cmake.toml new file mode 100644 index 0000000..b32a172 --- /dev/null +++ b/dependencies/cmake.toml @@ -0,0 +1,6 @@ +[subdir.vmprofiler] +[subdir.unicorn] + +[target.cli-parser] +type = "interface" +include-directories = ["cli-parser"] diff --git a/dependencies/vmprofiler b/dependencies/vmprofiler index e75104f..99f1f69 160000 --- a/dependencies/vmprofiler +++ b/dependencies/vmprofiler @@ -1 +1 @@ -Subproject commit e75104fbb3b07540be51fcef169e9eaffd1cfee2 +Subproject commit 99f1f695ed0e10c278076b037edd399965563140 diff --git a/dependencies/xtils b/dependencies/xtils deleted file mode 160000 index 99a1fc7..0000000 --- a/dependencies/xtils +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 99a1fc74e16af3261e7cfff4e03d470a7a05feb0 diff --git a/include/unpacker.hpp b/include/unpacker.hpp new file mode 100644 index 0000000..e69de29 diff --git a/include/vmemu_t.hpp b/include/vmemu_t.hpp new file mode 100644 index 0000000..784d00e --- /dev/null +++ b/include/vmemu_t.hpp @@ -0,0 +1,15 @@ +#pragma once +#include + +namespace vm +{ + class emu_t + { + public: + explicit emu_t( vm::ctx_t *vm_ctx ); + ~emu_t(); + + bool init(); + bool get_trace( std::vector< vm::instrs::code_block_t > &code_blocks ); + }; +} // namespace vm \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 3530354..d91b5e1 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,10 +1,10 @@ -#define NOMINMAX +#include +#include "vmemu_t.hpp" + #include #include #include -#include #include -#include "vmemu_t.hpp" int __cdecl main( int argc, const char *argv[] ) { @@ -15,8 +15,9 @@ int __cdecl main( int argc, const char *argv[] ) .required( true ) .description( "relative virtual address to a vm entry..." ); - parser.add_argument().name( "--vmpbin" ).required( true ).description( "path to unpacked virtualized binary..." ); + parser.add_argument().name( "--bin" ).required( true ).description( "path to unpacked virtualized binary..." ); parser.add_argument().name( "--out" ).required( true ).description( "output file name for trace file..." ); + parser.add_argument().name( "--unpack" ).description( "unpack a vmp2 binary..." ); parser.enable_help(); auto result = parser.parse( argc, argv ); @@ -72,6 +73,7 @@ int __cdecl main( int argc, const char *argv[] ) std::printf( "[!] something failed during tracing, review the console for more information...\n" ); std::printf( "> number of blocks = %d\n", code_blocks.size() ); + for ( auto &code_block : code_blocks ) { std::printf( "> code block starts at = %p\n", code_block.vip_begin ); @@ -121,4 +123,4 @@ int __cdecl main( int argc, const char *argv[] ) output.close(); std::printf( "> finished..." ); -} +} \ No newline at end of file diff --git a/src/unpacker.cpp b/src/unpacker.cpp new file mode 100644 index 0000000..e69de29 diff --git a/src/vmemu_t.cpp b/src/vmemu_t.cpp index e991f06..b6570f1 100644 --- a/src/vmemu_t.cpp +++ b/src/vmemu_t.cpp @@ -2,393 +2,21 @@ namespace vm { - emu_t::emu_t( vm::ctx_t *vmctx ) : uc( nullptr ), vmctx( vmctx ) + emu_t::emu_t( vm::ctx_t *vmctx ) { } - bool emu_t::init() - { - uc_err err; - std::uintptr_t stack_base = 0x1000000; - std::uintptr_t stack_addr = ( stack_base + ( 0x1000 * 20 ) ) - 0x6000; - const auto rip = vmctx->module_base + vmctx->vm_entry_rva; - - if ( ( err = uc_open( UC_ARCH_X86, UC_MODE_64, &uc ) ) ) - { - std::printf( "failed on uc_mem_map() with error returned %u: %s\n", err, uc_strerror( err ) ); - - return false; - } - - if ( ( err = uc_mem_map( uc, vmctx->module_base, vmctx->image_size, UC_PROT_ALL ) ) ) - { - std::printf( "failed on uc_mem_map() with error returned %u: %s\n", err, uc_strerror( err ) ); - - return false; - } - - if ( ( err = uc_mem_map( uc, UC_STACK_ADDR, sizeof vm::cpu_ctx::stack, UC_PROT_ALL ) ) ) - { - std::printf( "failed on uc_mem_map() with error returned %u: %s\n", err, uc_strerror( err ) ); - - return false; - } - - if ( ( err = uc_mem_write( uc, vmctx->module_base, reinterpret_cast< void * >( vmctx->module_base ), - vmctx->image_size ) ) ) - { - std::printf( "failed on uc_mem_write() with error returned %u: %s\n", err, uc_strerror( err ) ); - - return false; - } - - if ( ( err = uc_reg_write( uc, UC_X86_REG_RIP, &rip ) ) ) - { - std::printf( "failed on uc_reg_write() with error returned %u: %s\n", err, uc_strerror( err ) ); - - return false; - } - - if ( ( err = uc_reg_write( uc, UC_X86_REG_RSP, &stack_addr ) ) ) - { - std::printf( "failed on uc_reg_write() with error returned %u: %s\n", err, uc_strerror( err ) ); - - return false; - } - - if ( ( err = uc_hook_add( uc, &trace, UC_HOOK_CODE, &vm::emu_t::hook_code, this, vmctx->module_base, - vmctx->module_base + vmctx->image_size ) ) ) - { - std::printf( "failed on uc_hook_add() with error returned %u: %s\n", err, uc_strerror( err ) ); - - return false; - } - - if ( ( err = uc_hook_add( uc, &trace1, UC_HOOK_MEM_READ_UNMAPPED | UC_HOOK_MEM_WRITE_UNMAPPED, - vm::emu_t::hook_mem_invalid, this, 1, 0 ) ) ) - { - std::printf( "failed on uc_hook_add() with error returned %u: %s\n", err, uc_strerror( err ) ); - - return false; - } - return true; - } - emu_t::~emu_t() { - if ( uc ) - uc_close( uc ); } - bool emu_t::get_trace( std::vector< vm::instrs::code_block_t > &entries ) - { - uc_err err; - code_blocks.push_back( { vm::instrs::code_block_t{ 0u }, { nullptr } } ); - - if ( ( err = uc_emu_start( uc, vmctx->vm_entry_rva + vmctx->module_base, NULL, NULL, NULL ) ) ) - { - std::printf( "failed on uc_emu_start() with error returned %u: %s\n", err, uc_strerror( err ) ); - - return false; - } - - static const auto _already_traced = [ & ]( std::uintptr_t code_block_addr ) -> bool { - return std::find_if( code_blocks.begin(), code_blocks.end(), [ & ]( const auto code_block_data ) -> bool { - return code_block_data.first.vip_begin == code_block_addr || - // sometimes the code block address is displaced by 1... and another byte for the - // opcode... - code_block_data.first.vip_begin == code_block_addr - 2 || - code_block_data.first.vip_begin == code_block_addr - 1; - } ) != code_blocks.end(); - }; - - static const auto _traced_all_paths = - [ & ]( const std::vector< std::pair< vm::instrs::code_block_t, std::shared_ptr< cpu_ctx > > > &code_blocks ) - -> bool { - return std::find_if( - code_blocks.begin(), code_blocks.end(), - []( const std::pair< vm::instrs::code_block_t, std::shared_ptr< cpu_ctx > > &code_block_data ) - -> bool { - return code_block_data.first.jcc.has_jcc && - ( !_already_traced( code_block_data.first.jcc.block_addr[ 0 ] ) || - !_already_traced( code_block_data.first.jcc.block_addr[ 1 ] ) ); - } ) == code_blocks.end(); - }; - - static const auto _trace_branch = [ & ]( vm::instrs::code_block_t &code_block, - std::shared_ptr< cpu_ctx > &context, - std::uintptr_t branch_addr ) -> bool { - if ( !context ) - return {}; - - // restore context to virtual jmp... changing branch... - uc_context_restore( uc, context->context ); - - // restore entire stack.... - uc_mem_write( uc, UC_STACK_ADDR, context->stack, sizeof vm::cpu_ctx::stack ); - - std::uintptr_t rip = 0u; - uc_reg_read( uc, UC_X86_REG_RIP, &rip ); - - // change the top qword on the stack to the branch rva... - // the rva is image base'ed and only the bottom 32bits... - std::uintptr_t branch_rva = ( ( branch_addr - vmctx->module_base ) + vmctx->image_base ) & 0xFFFFFFFFull; - - uc_mem_write( uc, code_block.vinstrs.back().trace_data.regs.rbp, &branch_rva, sizeof branch_rva ); - code_blocks.push_back( { vm::instrs::code_block_t{ 0u }, { nullptr } } ); - - skip_current_jmp = true; - if ( ( err = uc_emu_start( uc, rip, NULL, NULL, NULL ) ) ) - { - std::printf( "failed on uc_emu_start() with error returned %u: %s\n", err, uc_strerror( err ) ); - return false; - } - return true; - }; - - while ( !_traced_all_paths( code_blocks ) ) - { - for ( auto &[ code_block, uc_code_block_context ] : code_blocks ) - { - if ( code_block.jcc.has_jcc ) - { - if ( !_already_traced( code_block.jcc.block_addr[ 0 ] ) ) - { - _trace_branch( code_block, uc_code_block_context, code_block.jcc.block_addr[ 0 ] ); - break; - } - - if ( !_already_traced( code_block.jcc.block_addr[ 1 ] ) ) - { - _trace_branch( code_block, uc_code_block_context, code_block.jcc.block_addr[ 1 ] ); - break; - } - } - } - } - - for ( auto &[ code_block, uc_code_block_context ] : code_blocks ) - entries.push_back( code_block ); - - return true; - } - - uc_err emu_t::create_entry( vmp2::v2::entry_t *entry ) + bool emu_t::init() { - uc_reg_read( uc, UC_X86_REG_R15, &entry->regs.r15 ); - uc_reg_read( uc, UC_X86_REG_R14, &entry->regs.r14 ); - uc_reg_read( uc, UC_X86_REG_R13, &entry->regs.r13 ); - uc_reg_read( uc, UC_X86_REG_R12, &entry->regs.r12 ); - uc_reg_read( uc, UC_X86_REG_R11, &entry->regs.r11 ); - uc_reg_read( uc, UC_X86_REG_R10, &entry->regs.r10 ); - uc_reg_read( uc, UC_X86_REG_R9, &entry->regs.r9 ); - uc_reg_read( uc, UC_X86_REG_R8, &entry->regs.r8 ); - uc_reg_read( uc, UC_X86_REG_RBP, &entry->regs.rbp ); - uc_reg_read( uc, UC_X86_REG_RDI, &entry->regs.rdi ); - uc_reg_read( uc, UC_X86_REG_RSI, &entry->regs.rsi ); - uc_reg_read( uc, UC_X86_REG_RDX, &entry->regs.rdx ); - uc_reg_read( uc, UC_X86_REG_RCX, &entry->regs.rcx ); - uc_reg_read( uc, UC_X86_REG_RBX, &entry->regs.rbx ); - uc_reg_read( uc, UC_X86_REG_RAX, &entry->regs.rax ); - uc_reg_read( uc, UC_X86_REG_EFLAGS, &entry->regs.rflags ); - - entry->vip = entry->regs.rsi; - entry->handler_idx = entry->regs.rax; - entry->decrypt_key = entry->regs.rbx; - - uc_err err; - if ( ( err = uc_mem_read( uc, entry->regs.rdi, entry->vregs.raw, sizeof entry->vregs.raw ) ) ) - return err; - - // copy virtual stack values... - for ( auto idx = 0u; idx < sizeof( entry->vsp ) / 8; ++idx ) - if ( ( err = uc_mem_read( uc, entry->regs.rbp + ( idx * 8 ), &entry->vsp.qword[ idx ], - sizeof entry->vsp.qword[ idx ] ) ) ) - return err; - - return UC_ERR_OK; + return {}; } - void emu_t::hook_code( uc_engine *uc, uint64_t address, uint32_t size, vm::emu_t *obj ) - { - // std::printf( ">>> Tracing instruction at 0x%p, instruction size = 0x%x\n", - //( address - obj->vmctx->module_base ) + obj->vmctx->image_base, size ); - - // bad code... but i need to skip JMP instructions when tracing branches since i save context - // on the jmp instruction... so it needs to be skipped... - if ( obj->skip_current_jmp ) - { - obj->skip_current_jmp = false; - return; - } - - // grab JMP RDX/RCX <-- this register... - static const auto jmp_reg = obj->vmctx->vm_entry[ obj->vmctx->vm_entry.size() ].instr.operands[ 0 ].reg.value; - - static ZydisDecoder decoder; - static ZydisDecodedInstruction instr; - static std::uintptr_t reg_val = 0u, rsi = 0u; - - // init zydis decoder only a single time... - if ( static std::atomic< bool > once = true; once.exchange( false ) ) - ZydisDecoderInit( &decoder, ZYDIS_MACHINE_MODE_LONG_64, ZYDIS_ADDRESS_WIDTH_64 ); - - if ( ZYAN_SUCCESS( - ZydisDecoderDecodeBuffer( &decoder, reinterpret_cast< void * >( address ), size, &instr ) ) && - instr.mnemonic == ZYDIS_MNEMONIC_JMP && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER && - instr.operands[ 0 ].reg.value == jmp_reg ) - { - uc_err err; - vmp2::v2::entry_t new_entry; - std::optional< vm::instrs::virt_instr_t > virt_instr; - vm::handler::profile_t *vm_handler_profile = nullptr; - - switch ( jmp_reg ) - { - case ZYDIS_REGISTER_RDX: - uc_reg_read( uc, UC_X86_REG_RDX, ®_val ); - break; - case ZYDIS_REGISTER_RCX: - uc_reg_read( uc, UC_X86_REG_RCX, ®_val ); - break; - default: - std::printf( "[!] invalid jump register... = %d\n", jmp_reg ); - exit( 0 ); - } - - // checks to see if the address - // in JMP RDX/RCX is a vm handler address... - static const auto vm_handler_check = [ & ]( const vm::handler::handler_t &vm_handler ) -> bool { - return vm_handler.address == reg_val; - }; - - if ( std::find_if( obj->vmctx->vm_handlers.begin(), obj->vmctx->vm_handlers.end(), vm_handler_check ) == - obj->vmctx->vm_handlers.end() ) - return; - - if ( ( err = obj->create_entry( &new_entry ) ) ) - { - std::printf( "[!] failed to create new entry... reason = %u, %s\n", err, uc_strerror( err ) ); - - exit( 0 ); - } - - if ( !obj->code_blocks.back().first.vip_begin ) - // -1 because the first byte is the opcode... - obj->code_blocks.back().first.vip_begin = new_entry.vip - 1; - - if ( obj->code_blocks.back().first.vinstrs.size() > 500 ) - { - obj->code_blocks.back().first.jcc.has_jcc = false; - uc_emu_stop( obj->uc ); - return; - } - - if ( virt_instr = vm::instrs::get( *obj->vmctx, new_entry ); !virt_instr.has_value() ) - { - std::printf( "[!] failed to create vm::instrs::virt_instr_t...\n" ); - - exit( 0 ); - } - - obj->code_blocks.back().first.vinstrs.push_back( virt_instr.value() ); - uc_reg_read( obj->uc, UC_X86_REG_RSI, &rsi ); - std::printf( "> %s handler = 0x%p vip = 0x%p\n", - obj->vmctx->vm_handlers[ new_entry.handler_idx ].profile - ? obj->vmctx->vm_handlers[ new_entry.handler_idx ].profile->name - : "UNK", - ( reg_val - obj->vmctx->module_base ) + obj->vmctx->image_base, - ( rsi - obj->vmctx->module_base ) + obj->vmctx->image_base ); - - // if there is a virtual JMP instruction then we need to grab jcc data for the current code_block_t - // and then create a new code_block_t... - if ( ( vm_handler_profile = obj->vmctx->vm_handlers[ new_entry.handler_idx ].profile ) && - vm_handler_profile->mnemonic == vm::handler::mnemonic_t::JMP ) - { - const auto code_block_address = vm::instrs::code_block_addr( *obj->vmctx, new_entry ); - auto jcc = vm::instrs::get_jcc_data( *obj->vmctx, obj->code_blocks.back().first ); - - if ( jcc.has_value() ) - { - obj->code_blocks.back().first.jcc = jcc.value(); - } - else // the branch(s) dont start with SREGQ... stopping... - { - uc_emu_stop( uc ); - return; - } - - // save cpu state as well as stack... - obj->code_blocks.back().second = std::make_shared< cpu_ctx >(); - - if ( ( err = uc_context_alloc( uc, &obj->code_blocks.back().second->context ) ) ) - { - std::printf( "[!] failed to allocate context space...\n" ); - exit( 0 ); - } - - if ( ( err = uc_context_save( uc, obj->code_blocks.back().second->context ) ) ) - { - std::printf( "[!] failed to save cpu context...\n" ); - exit( 0 ); - } - - if ( ( err = uc_mem_read( uc, UC_STACK_ADDR, obj->code_blocks.back().second->stack, - sizeof vm::cpu_ctx::stack ) ) ) - { - std::printf( "[!] failed to read stack into backup buffer...\n" ); - exit( 0 ); - } - - // if the next code block has already been traced then stop emulation... - if ( auto already_traced = std::find_if( obj->code_blocks.begin(), obj->code_blocks.end(), - [ & ]( const auto &code_block_data ) -> bool { - return code_block_data.first.vip_begin == - code_block_address; - } ); - already_traced != obj->code_blocks.end() ) - { - uc_emu_stop( uc ); - } - else // else set the next code block up... - { - obj->code_blocks.push_back( { vm::instrs::code_block_t{ 0u }, {} } ); - } - } - } - else if ( instr.mnemonic == ZYDIS_MNEMONIC_RET ) // finish tracing... - { - uc_emu_stop( uc ); - // vmexit's cannot have a branch... - obj->code_blocks.back().first.jcc.has_jcc = false; - } - else if ( instr.mnemonic == ZYDIS_MNEMONIC_CALL && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER ) - { - const auto rip = address + instr.length; - uc_reg_write( obj->uc, UC_X86_REG_RIP, &rip ); - } - } - - bool emu_t::hook_mem_invalid( uc_engine *uc, uc_mem_type type, uint64_t address, int size, int64_t value, - vm::emu_t *obj ) + bool emu_t::get_trace( std::vector< vm::instrs::code_block_t > &entries ) { - uc_err err; - if ( ( err = uc_mem_map( obj->uc, address & ~0xFFFull, 0x1000, UC_PROT_ALL ) ) ) - std::printf( "failed on uc_mem_map() with error returned %u: %s\n", err, uc_strerror( err ) ); - - switch ( type ) - { - case UC_MEM_WRITE_UNMAPPED: - printf( ">>> Missing memory is being WRITE at 0x%p, data size = %u, data value = 0x%p\n", address, size, - value ); - return true; - case UC_MEM_READ_UNMAPPED: - printf( ">>> Missing memory is being READ at 0x%p, data size = %u, data value = 0x%p\n", address, size, - value ); - return true; - default: - printf( ">>> Missing memory at 0x%p, data size = %u, data value = 0x%p\n", address, size, value ); - return true; - } + return {}; } } // namespace vm \ No newline at end of file diff --git a/src/vmemu_t.hpp b/src/vmemu_t.hpp deleted file mode 100644 index 191cfeb..0000000 --- a/src/vmemu_t.hpp +++ /dev/null @@ -1,47 +0,0 @@ -#pragma once -#define NOMINMAX -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define UC_STACK_ADDR 0x1000000 - -namespace vm -{ - struct cpu_ctx - { - uc_context *context; - std::uint8_t stack[ PAGE_4K * 100 ]; - }; - - class emu_t - { - using callback_t = std::function< void( uc_engine *, uint64_t, uint32_t, void * ) >; - - public: - explicit emu_t( vm::ctx_t *vmctx ); - ~emu_t(); - - bool init(); - bool get_trace( std::vector< vm::instrs::code_block_t > &entries ); - - private: - uc_err create_entry( vmp2::v2::entry_t *entry ); - static void hook_code( uc_engine *uc, uint64_t address, uint32_t size, vm::emu_t *obj ); - static bool hook_mem_invalid( uc_engine *uc, uc_mem_type type, uint64_t address, int size, int64_t value, - vm::emu_t *obj ); - - uc_engine *uc; - uc_hook trace, trace1; - - bool skip_current_jmp; - vm::ctx_t *vmctx; - std::vector< std::pair< vm::instrs::code_block_t, std::shared_ptr > > code_blocks; - }; -} // namespace vm \ No newline at end of file diff --git a/vmemu.sln b/vmemu.sln deleted file mode 100644 index 4e702ff..0000000 --- a/vmemu.sln +++ /dev/null @@ -1,662 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.30907.101 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Zydis", "dependencies\vmprofiler\dependencies\zydis\msvc\zydis\Zydis.vcxproj", "{88A23124-5640-35A0-B890-311D7A67A7D2}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vmprofiler", "dependencies\vmprofiler\vmprofiler.vcxproj", "{D0B6092A-9944-4F24-9486-4B7DAE372619}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vmemu", "vmemu.vcxproj", "{F0D51879-E659-4BD3-B688-7864DB3C82AA}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "dependencies", "dependencies", "{7EE14D03-ED3D-4FA2-8974-8A285C974E3D}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VTIL", "dependencies\vmprofiler\dependencies\vtil\VTIL\VTIL.vcxproj", "{8163E74C-DDE4-4507-BD3D-064CD95FF33B}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VTIL-Architecture", "dependencies\vmprofiler\dependencies\vtil\VTIL-Architecture\VTIL-Architecture.vcxproj", "{A79E2869-7626-4801-B09D-5C12F5163BA3}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VTIL-Common", "dependencies\vmprofiler\dependencies\vtil\VTIL-Common\VTIL-Common.vcxproj", "{EC6B8F7F-730C-4086-B143-4664CC16DF8F}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VTIL-Compiler", "dependencies\vmprofiler\dependencies\vtil\VTIL-Compiler\VTIL-Compiler.vcxproj", "{F960486B-2DB4-44AF-91BB-0F19F228ABCF}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "VTIL-SymEx", "dependencies\vmprofiler\dependencies\vtil\VTIL-SymEx\VTIL-SymEx.vcxproj", "{FE3202CE-D05C-4E04-AE9B-D30305D8CE31}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "keystone", "dependencies\vmprofiler\dependencies\vtil\dependencies\keystone\msvc\llvm\keystone\keystone.vcxproj", "{E4754E3E-2503-307A-8076-8AC2AD8B75B2}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "capstone-static", "dependencies\vmprofiler\dependencies\vtil\dependencies\capstone\msvc\capstone-static.vcxproj", "{A0471FDD-F210-3D7E-B4EA-20543BC10911}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - DBG|x64 = DBG|x64 - DBG|x86 = DBG|x86 - Debug Kernel|x64 = Debug Kernel|x64 - Debug Kernel|x86 = Debug Kernel|x86 - Debug MD DLL|x64 = Debug MD DLL|x64 - Debug MD DLL|x86 = Debug MD DLL|x86 - Debug MD|x64 = Debug MD|x64 - Debug MD|x86 = Debug MD|x86 - Debug MT DLL|x64 = Debug MT DLL|x64 - Debug MT DLL|x86 = Debug MT DLL|x86 - Debug MT|x64 = Debug MT|x64 - Debug MT|x86 = Debug MT|x86 - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - MinSizeRel|x64 = MinSizeRel|x64 - MinSizeRel|x86 = MinSizeRel|x86 - Release Kernel|x64 = Release Kernel|x64 - Release Kernel|x86 = Release Kernel|x86 - Release MD DLL|x64 = Release MD DLL|x64 - Release MD DLL|x86 = Release MD DLL|x86 - Release MD|x64 = Release MD|x64 - Release MD|x86 = Release MD|x86 - Release MT DLL|x64 = Release MT DLL|x64 - Release MT DLL|x86 = Release MT DLL|x86 - Release MT|x64 = Release MT|x64 - Release MT|x86 = Release MT|x86 - Release|x64 = Release|x64 - Release|x86 = Release|x86 - RelWithDebInfo|x64 = RelWithDebInfo|x64 - RelWithDebInfo|x86 = RelWithDebInfo|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {88A23124-5640-35A0-B890-311D7A67A7D2}.DBG|x64.ActiveCfg = Debug MT|x64 - {88A23124-5640-35A0-B890-311D7A67A7D2}.DBG|x64.Build.0 = Debug MT|x64 - {88A23124-5640-35A0-B890-311D7A67A7D2}.DBG|x86.ActiveCfg = Debug MT|Win32 - {88A23124-5640-35A0-B890-311D7A67A7D2}.DBG|x86.Build.0 = Debug MT|Win32 - {88A23124-5640-35A0-B890-311D7A67A7D2}.Debug Kernel|x64.ActiveCfg = Debug Kernel|x64 - {88A23124-5640-35A0-B890-311D7A67A7D2}.Debug Kernel|x64.Build.0 = Debug Kernel|x64 - {88A23124-5640-35A0-B890-311D7A67A7D2}.Debug Kernel|x64.Deploy.0 = Debug Kernel|x64 - {88A23124-5640-35A0-B890-311D7A67A7D2}.Debug Kernel|x86.ActiveCfg = Debug Kernel|Win32 - {88A23124-5640-35A0-B890-311D7A67A7D2}.Debug Kernel|x86.Build.0 = Debug Kernel|Win32 - {88A23124-5640-35A0-B890-311D7A67A7D2}.Debug Kernel|x86.Deploy.0 = Debug Kernel|Win32 - {88A23124-5640-35A0-B890-311D7A67A7D2}.Debug MD DLL|x64.ActiveCfg = Debug MD DLL|x64 - {88A23124-5640-35A0-B890-311D7A67A7D2}.Debug MD DLL|x64.Build.0 = Debug MD DLL|x64 - {88A23124-5640-35A0-B890-311D7A67A7D2}.Debug MD DLL|x86.ActiveCfg = Debug MD DLL|Win32 - {88A23124-5640-35A0-B890-311D7A67A7D2}.Debug MD DLL|x86.Build.0 = Debug MD DLL|Win32 - {88A23124-5640-35A0-B890-311D7A67A7D2}.Debug MD|x64.ActiveCfg = Debug MD|x64 - {88A23124-5640-35A0-B890-311D7A67A7D2}.Debug MD|x64.Build.0 = Debug MD|x64 - {88A23124-5640-35A0-B890-311D7A67A7D2}.Debug MD|x86.ActiveCfg = Debug MD|Win32 - {88A23124-5640-35A0-B890-311D7A67A7D2}.Debug MD|x86.Build.0 = Debug MD|Win32 - {88A23124-5640-35A0-B890-311D7A67A7D2}.Debug MT DLL|x64.ActiveCfg = Debug MT DLL|x64 - {88A23124-5640-35A0-B890-311D7A67A7D2}.Debug MT DLL|x64.Build.0 = Debug MT DLL|x64 - {88A23124-5640-35A0-B890-311D7A67A7D2}.Debug MT DLL|x86.ActiveCfg = Debug MT DLL|Win32 - {88A23124-5640-35A0-B890-311D7A67A7D2}.Debug MT DLL|x86.Build.0 = Debug MT DLL|Win32 - {88A23124-5640-35A0-B890-311D7A67A7D2}.Debug MT|x64.ActiveCfg = Debug MT|x64 - {88A23124-5640-35A0-B890-311D7A67A7D2}.Debug MT|x64.Build.0 = Debug MT|x64 - {88A23124-5640-35A0-B890-311D7A67A7D2}.Debug MT|x86.ActiveCfg = Debug MT|Win32 - {88A23124-5640-35A0-B890-311D7A67A7D2}.Debug MT|x86.Build.0 = Debug MT|Win32 - {88A23124-5640-35A0-B890-311D7A67A7D2}.Debug|x64.ActiveCfg = Debug MD DLL|x64 - {88A23124-5640-35A0-B890-311D7A67A7D2}.Debug|x64.Build.0 = Debug MD DLL|x64 - {88A23124-5640-35A0-B890-311D7A67A7D2}.Debug|x86.ActiveCfg = Debug MD DLL|Win32 - {88A23124-5640-35A0-B890-311D7A67A7D2}.Debug|x86.Build.0 = Debug MD DLL|Win32 - {88A23124-5640-35A0-B890-311D7A67A7D2}.MinSizeRel|x64.ActiveCfg = Debug MD DLL|x64 - {88A23124-5640-35A0-B890-311D7A67A7D2}.MinSizeRel|x64.Build.0 = Debug MD DLL|x64 - {88A23124-5640-35A0-B890-311D7A67A7D2}.MinSizeRel|x86.ActiveCfg = Debug MD DLL|Win32 - {88A23124-5640-35A0-B890-311D7A67A7D2}.MinSizeRel|x86.Build.0 = Debug MD DLL|Win32 - {88A23124-5640-35A0-B890-311D7A67A7D2}.Release Kernel|x64.ActiveCfg = Release Kernel|x64 - {88A23124-5640-35A0-B890-311D7A67A7D2}.Release Kernel|x64.Build.0 = Release Kernel|x64 - {88A23124-5640-35A0-B890-311D7A67A7D2}.Release Kernel|x64.Deploy.0 = Release Kernel|x64 - {88A23124-5640-35A0-B890-311D7A67A7D2}.Release Kernel|x86.ActiveCfg = Release Kernel|Win32 - {88A23124-5640-35A0-B890-311D7A67A7D2}.Release Kernel|x86.Build.0 = Release Kernel|Win32 - {88A23124-5640-35A0-B890-311D7A67A7D2}.Release Kernel|x86.Deploy.0 = Release Kernel|Win32 - {88A23124-5640-35A0-B890-311D7A67A7D2}.Release MD DLL|x64.ActiveCfg = Release MD DLL|x64 - {88A23124-5640-35A0-B890-311D7A67A7D2}.Release MD DLL|x64.Build.0 = Release MD DLL|x64 - {88A23124-5640-35A0-B890-311D7A67A7D2}.Release MD DLL|x86.ActiveCfg = Release MD DLL|Win32 - {88A23124-5640-35A0-B890-311D7A67A7D2}.Release MD DLL|x86.Build.0 = Release MD DLL|Win32 - {88A23124-5640-35A0-B890-311D7A67A7D2}.Release MD|x64.ActiveCfg = Release MD|x64 - {88A23124-5640-35A0-B890-311D7A67A7D2}.Release MD|x64.Build.0 = Release MD|x64 - {88A23124-5640-35A0-B890-311D7A67A7D2}.Release MD|x86.ActiveCfg = Release MD|Win32 - {88A23124-5640-35A0-B890-311D7A67A7D2}.Release MD|x86.Build.0 = Release MD|Win32 - {88A23124-5640-35A0-B890-311D7A67A7D2}.Release MT DLL|x64.ActiveCfg = Release MT DLL|x64 - {88A23124-5640-35A0-B890-311D7A67A7D2}.Release MT DLL|x64.Build.0 = Release MT DLL|x64 - {88A23124-5640-35A0-B890-311D7A67A7D2}.Release MT DLL|x86.ActiveCfg = Release MT DLL|Win32 - {88A23124-5640-35A0-B890-311D7A67A7D2}.Release MT DLL|x86.Build.0 = Release MT DLL|Win32 - {88A23124-5640-35A0-B890-311D7A67A7D2}.Release MT|x64.ActiveCfg = Release MT|x64 - {88A23124-5640-35A0-B890-311D7A67A7D2}.Release MT|x64.Build.0 = Release MT|x64 - {88A23124-5640-35A0-B890-311D7A67A7D2}.Release MT|x86.ActiveCfg = Release MT|Win32 - {88A23124-5640-35A0-B890-311D7A67A7D2}.Release MT|x86.Build.0 = Release MT|Win32 - {88A23124-5640-35A0-B890-311D7A67A7D2}.Release|x64.ActiveCfg = Release MT|x64 - {88A23124-5640-35A0-B890-311D7A67A7D2}.Release|x64.Build.0 = Release MT|x64 - {88A23124-5640-35A0-B890-311D7A67A7D2}.Release|x86.ActiveCfg = Release MT DLL|Win32 - {88A23124-5640-35A0-B890-311D7A67A7D2}.Release|x86.Build.0 = Release MT DLL|Win32 - {88A23124-5640-35A0-B890-311D7A67A7D2}.RelWithDebInfo|x64.ActiveCfg = Release MD DLL|x64 - {88A23124-5640-35A0-B890-311D7A67A7D2}.RelWithDebInfo|x64.Build.0 = Release MD DLL|x64 - {88A23124-5640-35A0-B890-311D7A67A7D2}.RelWithDebInfo|x86.ActiveCfg = Release MD DLL|Win32 - {88A23124-5640-35A0-B890-311D7A67A7D2}.RelWithDebInfo|x86.Build.0 = Release MD DLL|Win32 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.DBG|x64.ActiveCfg = DBG|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.DBG|x64.Build.0 = DBG|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.DBG|x86.ActiveCfg = DBG|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug Kernel|x64.ActiveCfg = DBG|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug Kernel|x64.Build.0 = DBG|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug Kernel|x86.ActiveCfg = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug Kernel|x86.Build.0 = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MD DLL|x64.ActiveCfg = DBG|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MD DLL|x64.Build.0 = DBG|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MD DLL|x86.ActiveCfg = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MD DLL|x86.Build.0 = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MD|x64.ActiveCfg = DBG|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MD|x64.Build.0 = DBG|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MD|x86.ActiveCfg = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MD|x86.Build.0 = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MT DLL|x64.ActiveCfg = DBG|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MT DLL|x64.Build.0 = DBG|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MT DLL|x86.ActiveCfg = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MT DLL|x86.Build.0 = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MT|x64.ActiveCfg = DBG|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MT|x64.Build.0 = DBG|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MT|x86.ActiveCfg = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug MT|x86.Build.0 = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug|x64.ActiveCfg = DBG|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug|x64.Build.0 = DBG|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug|x86.ActiveCfg = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Debug|x86.Build.0 = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.MinSizeRel|x64.ActiveCfg = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.MinSizeRel|x64.Build.0 = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.MinSizeRel|x86.ActiveCfg = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.MinSizeRel|x86.Build.0 = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release Kernel|x64.ActiveCfg = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release Kernel|x64.Build.0 = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release Kernel|x86.ActiveCfg = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release Kernel|x86.Build.0 = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MD DLL|x64.ActiveCfg = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MD DLL|x64.Build.0 = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MD DLL|x86.ActiveCfg = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MD DLL|x86.Build.0 = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MD|x64.ActiveCfg = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MD|x64.Build.0 = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MD|x86.ActiveCfg = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MD|x86.Build.0 = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MT DLL|x64.ActiveCfg = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MT DLL|x64.Build.0 = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MT DLL|x86.ActiveCfg = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MT DLL|x86.Build.0 = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MT|x64.ActiveCfg = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MT|x64.Build.0 = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MT|x86.ActiveCfg = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release MT|x86.Build.0 = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release|x64.ActiveCfg = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release|x64.Build.0 = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.Release|x86.ActiveCfg = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.RelWithDebInfo|x64.ActiveCfg = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.RelWithDebInfo|x64.Build.0 = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.RelWithDebInfo|x86.ActiveCfg = Release|x64 - {D0B6092A-9944-4F24-9486-4B7DAE372619}.RelWithDebInfo|x86.Build.0 = Release|x64 - {F0D51879-E659-4BD3-B688-7864DB3C82AA}.DBG|x64.ActiveCfg = Debug|x64 - {F0D51879-E659-4BD3-B688-7864DB3C82AA}.DBG|x64.Build.0 = Debug|x64 - {F0D51879-E659-4BD3-B688-7864DB3C82AA}.DBG|x86.ActiveCfg = Debug|x64 - {F0D51879-E659-4BD3-B688-7864DB3C82AA}.DBG|x86.Build.0 = Debug|x64 - {F0D51879-E659-4BD3-B688-7864DB3C82AA}.Debug Kernel|x64.ActiveCfg = Debug|x64 - {F0D51879-E659-4BD3-B688-7864DB3C82AA}.Debug Kernel|x64.Build.0 = Debug|x64 - {F0D51879-E659-4BD3-B688-7864DB3C82AA}.Debug Kernel|x86.ActiveCfg = Release|x64 - {F0D51879-E659-4BD3-B688-7864DB3C82AA}.Debug Kernel|x86.Build.0 = Release|x64 - {F0D51879-E659-4BD3-B688-7864DB3C82AA}.Debug MD DLL|x64.ActiveCfg = Debug|x64 - {F0D51879-E659-4BD3-B688-7864DB3C82AA}.Debug MD DLL|x64.Build.0 = Debug|x64 - {F0D51879-E659-4BD3-B688-7864DB3C82AA}.Debug MD DLL|x86.ActiveCfg = Release|x64 - {F0D51879-E659-4BD3-B688-7864DB3C82AA}.Debug MD DLL|x86.Build.0 = Release|x64 - {F0D51879-E659-4BD3-B688-7864DB3C82AA}.Debug MD|x64.ActiveCfg = Debug|x64 - {F0D51879-E659-4BD3-B688-7864DB3C82AA}.Debug MD|x64.Build.0 = Debug|x64 - {F0D51879-E659-4BD3-B688-7864DB3C82AA}.Debug MD|x86.ActiveCfg = Release|x64 - {F0D51879-E659-4BD3-B688-7864DB3C82AA}.Debug MD|x86.Build.0 = Release|x64 - {F0D51879-E659-4BD3-B688-7864DB3C82AA}.Debug MT DLL|x64.ActiveCfg = Debug|x64 - {F0D51879-E659-4BD3-B688-7864DB3C82AA}.Debug MT DLL|x64.Build.0 = Debug|x64 - {F0D51879-E659-4BD3-B688-7864DB3C82AA}.Debug MT DLL|x86.ActiveCfg = Release|x64 - {F0D51879-E659-4BD3-B688-7864DB3C82AA}.Debug MT DLL|x86.Build.0 = Release|x64 - {F0D51879-E659-4BD3-B688-7864DB3C82AA}.Debug MT|x64.ActiveCfg = Debug|x64 - {F0D51879-E659-4BD3-B688-7864DB3C82AA}.Debug MT|x64.Build.0 = Debug|x64 - {F0D51879-E659-4BD3-B688-7864DB3C82AA}.Debug MT|x86.ActiveCfg = Release|x64 - {F0D51879-E659-4BD3-B688-7864DB3C82AA}.Debug MT|x86.Build.0 = Release|x64 - {F0D51879-E659-4BD3-B688-7864DB3C82AA}.Debug|x64.ActiveCfg = Debug|x64 - {F0D51879-E659-4BD3-B688-7864DB3C82AA}.Debug|x64.Build.0 = Debug|x64 - {F0D51879-E659-4BD3-B688-7864DB3C82AA}.Debug|x86.ActiveCfg = Debug|x64 - {F0D51879-E659-4BD3-B688-7864DB3C82AA}.MinSizeRel|x64.ActiveCfg = Release|x64 - {F0D51879-E659-4BD3-B688-7864DB3C82AA}.MinSizeRel|x64.Build.0 = Release|x64 - {F0D51879-E659-4BD3-B688-7864DB3C82AA}.MinSizeRel|x86.ActiveCfg = Release|x64 - {F0D51879-E659-4BD3-B688-7864DB3C82AA}.MinSizeRel|x86.Build.0 = Release|x64 - {F0D51879-E659-4BD3-B688-7864DB3C82AA}.Release Kernel|x64.ActiveCfg = Release|x64 - {F0D51879-E659-4BD3-B688-7864DB3C82AA}.Release Kernel|x64.Build.0 = Release|x64 - {F0D51879-E659-4BD3-B688-7864DB3C82AA}.Release Kernel|x86.ActiveCfg = Release|x64 - {F0D51879-E659-4BD3-B688-7864DB3C82AA}.Release Kernel|x86.Build.0 = Release|x64 - {F0D51879-E659-4BD3-B688-7864DB3C82AA}.Release MD DLL|x64.ActiveCfg = Release|x64 - {F0D51879-E659-4BD3-B688-7864DB3C82AA}.Release MD DLL|x64.Build.0 = Release|x64 - {F0D51879-E659-4BD3-B688-7864DB3C82AA}.Release MD DLL|x86.ActiveCfg = Release|x64 - {F0D51879-E659-4BD3-B688-7864DB3C82AA}.Release MD DLL|x86.Build.0 = Release|x64 - {F0D51879-E659-4BD3-B688-7864DB3C82AA}.Release MD|x64.ActiveCfg = Release|x64 - {F0D51879-E659-4BD3-B688-7864DB3C82AA}.Release MD|x64.Build.0 = Release|x64 - {F0D51879-E659-4BD3-B688-7864DB3C82AA}.Release MD|x86.ActiveCfg = Release|x64 - {F0D51879-E659-4BD3-B688-7864DB3C82AA}.Release MD|x86.Build.0 = Release|x64 - {F0D51879-E659-4BD3-B688-7864DB3C82AA}.Release MT DLL|x64.ActiveCfg = Release|x64 - {F0D51879-E659-4BD3-B688-7864DB3C82AA}.Release MT DLL|x64.Build.0 = Release|x64 - {F0D51879-E659-4BD3-B688-7864DB3C82AA}.Release MT DLL|x86.ActiveCfg = Release|x64 - {F0D51879-E659-4BD3-B688-7864DB3C82AA}.Release MT DLL|x86.Build.0 = Release|x64 - {F0D51879-E659-4BD3-B688-7864DB3C82AA}.Release MT|x64.ActiveCfg = Release|x64 - {F0D51879-E659-4BD3-B688-7864DB3C82AA}.Release MT|x64.Build.0 = Release|x64 - {F0D51879-E659-4BD3-B688-7864DB3C82AA}.Release MT|x86.ActiveCfg = Release|x64 - {F0D51879-E659-4BD3-B688-7864DB3C82AA}.Release MT|x86.Build.0 = Release|x64 - {F0D51879-E659-4BD3-B688-7864DB3C82AA}.Release|x64.ActiveCfg = Release|x64 - {F0D51879-E659-4BD3-B688-7864DB3C82AA}.Release|x64.Build.0 = Release|x64 - {F0D51879-E659-4BD3-B688-7864DB3C82AA}.Release|x86.ActiveCfg = Release|x64 - {F0D51879-E659-4BD3-B688-7864DB3C82AA}.RelWithDebInfo|x64.ActiveCfg = Release|x64 - {F0D51879-E659-4BD3-B688-7864DB3C82AA}.RelWithDebInfo|x64.Build.0 = Release|x64 - {F0D51879-E659-4BD3-B688-7864DB3C82AA}.RelWithDebInfo|x86.ActiveCfg = Release|x64 - {F0D51879-E659-4BD3-B688-7864DB3C82AA}.RelWithDebInfo|x86.Build.0 = Release|x64 - {8163E74C-DDE4-4507-BD3D-064CD95FF33B}.DBG|x64.ActiveCfg = Debug|x64 - {8163E74C-DDE4-4507-BD3D-064CD95FF33B}.DBG|x64.Build.0 = Debug|x64 - {8163E74C-DDE4-4507-BD3D-064CD95FF33B}.DBG|x86.ActiveCfg = Debug|x64 - {8163E74C-DDE4-4507-BD3D-064CD95FF33B}.DBG|x86.Build.0 = Debug|x64 - {8163E74C-DDE4-4507-BD3D-064CD95FF33B}.Debug Kernel|x64.ActiveCfg = Debug|x64 - {8163E74C-DDE4-4507-BD3D-064CD95FF33B}.Debug Kernel|x64.Build.0 = Debug|x64 - {8163E74C-DDE4-4507-BD3D-064CD95FF33B}.Debug Kernel|x86.ActiveCfg = Debug|x64 - {8163E74C-DDE4-4507-BD3D-064CD95FF33B}.Debug Kernel|x86.Build.0 = Debug|x64 - {8163E74C-DDE4-4507-BD3D-064CD95FF33B}.Debug MD DLL|x64.ActiveCfg = Debug|x64 - {8163E74C-DDE4-4507-BD3D-064CD95FF33B}.Debug MD DLL|x64.Build.0 = Debug|x64 - {8163E74C-DDE4-4507-BD3D-064CD95FF33B}.Debug MD DLL|x86.ActiveCfg = Debug|x64 - {8163E74C-DDE4-4507-BD3D-064CD95FF33B}.Debug MD DLL|x86.Build.0 = Debug|x64 - {8163E74C-DDE4-4507-BD3D-064CD95FF33B}.Debug MD|x64.ActiveCfg = Debug|x64 - {8163E74C-DDE4-4507-BD3D-064CD95FF33B}.Debug MD|x64.Build.0 = Debug|x64 - {8163E74C-DDE4-4507-BD3D-064CD95FF33B}.Debug MD|x86.ActiveCfg = Debug|x64 - {8163E74C-DDE4-4507-BD3D-064CD95FF33B}.Debug MD|x86.Build.0 = Debug|x64 - {8163E74C-DDE4-4507-BD3D-064CD95FF33B}.Debug MT DLL|x64.ActiveCfg = Debug|x64 - {8163E74C-DDE4-4507-BD3D-064CD95FF33B}.Debug MT DLL|x64.Build.0 = Debug|x64 - {8163E74C-DDE4-4507-BD3D-064CD95FF33B}.Debug MT DLL|x86.ActiveCfg = Debug|x64 - {8163E74C-DDE4-4507-BD3D-064CD95FF33B}.Debug MT DLL|x86.Build.0 = Debug|x64 - {8163E74C-DDE4-4507-BD3D-064CD95FF33B}.Debug MT|x64.ActiveCfg = Debug|x64 - {8163E74C-DDE4-4507-BD3D-064CD95FF33B}.Debug MT|x64.Build.0 = Debug|x64 - {8163E74C-DDE4-4507-BD3D-064CD95FF33B}.Debug MT|x86.ActiveCfg = Debug|x64 - {8163E74C-DDE4-4507-BD3D-064CD95FF33B}.Debug MT|x86.Build.0 = Debug|x64 - {8163E74C-DDE4-4507-BD3D-064CD95FF33B}.Debug|x64.ActiveCfg = Debug|x64 - {8163E74C-DDE4-4507-BD3D-064CD95FF33B}.Debug|x64.Build.0 = Debug|x64 - {8163E74C-DDE4-4507-BD3D-064CD95FF33B}.Debug|x86.ActiveCfg = Debug|x64 - {8163E74C-DDE4-4507-BD3D-064CD95FF33B}.MinSizeRel|x64.ActiveCfg = Debug|x64 - {8163E74C-DDE4-4507-BD3D-064CD95FF33B}.MinSizeRel|x64.Build.0 = Debug|x64 - {8163E74C-DDE4-4507-BD3D-064CD95FF33B}.MinSizeRel|x86.ActiveCfg = Debug|x64 - {8163E74C-DDE4-4507-BD3D-064CD95FF33B}.MinSizeRel|x86.Build.0 = Debug|x64 - {8163E74C-DDE4-4507-BD3D-064CD95FF33B}.Release Kernel|x64.ActiveCfg = Release|x64 - {8163E74C-DDE4-4507-BD3D-064CD95FF33B}.Release Kernel|x64.Build.0 = Release|x64 - {8163E74C-DDE4-4507-BD3D-064CD95FF33B}.Release Kernel|x86.ActiveCfg = Debug|x64 - {8163E74C-DDE4-4507-BD3D-064CD95FF33B}.Release Kernel|x86.Build.0 = Debug|x64 - {8163E74C-DDE4-4507-BD3D-064CD95FF33B}.Release MD DLL|x64.ActiveCfg = Release|x64 - {8163E74C-DDE4-4507-BD3D-064CD95FF33B}.Release MD DLL|x64.Build.0 = Release|x64 - {8163E74C-DDE4-4507-BD3D-064CD95FF33B}.Release MD DLL|x86.ActiveCfg = Debug|x64 - {8163E74C-DDE4-4507-BD3D-064CD95FF33B}.Release MD DLL|x86.Build.0 = Debug|x64 - {8163E74C-DDE4-4507-BD3D-064CD95FF33B}.Release MD|x64.ActiveCfg = Release|x64 - {8163E74C-DDE4-4507-BD3D-064CD95FF33B}.Release MD|x64.Build.0 = Release|x64 - {8163E74C-DDE4-4507-BD3D-064CD95FF33B}.Release MD|x86.ActiveCfg = Debug|x64 - {8163E74C-DDE4-4507-BD3D-064CD95FF33B}.Release MD|x86.Build.0 = Debug|x64 - {8163E74C-DDE4-4507-BD3D-064CD95FF33B}.Release MT DLL|x64.ActiveCfg = Release|x64 - {8163E74C-DDE4-4507-BD3D-064CD95FF33B}.Release MT DLL|x64.Build.0 = Release|x64 - {8163E74C-DDE4-4507-BD3D-064CD95FF33B}.Release MT DLL|x86.ActiveCfg = Debug|x64 - {8163E74C-DDE4-4507-BD3D-064CD95FF33B}.Release MT DLL|x86.Build.0 = Debug|x64 - {8163E74C-DDE4-4507-BD3D-064CD95FF33B}.Release MT|x64.ActiveCfg = Release|x64 - {8163E74C-DDE4-4507-BD3D-064CD95FF33B}.Release MT|x64.Build.0 = Release|x64 - {8163E74C-DDE4-4507-BD3D-064CD95FF33B}.Release MT|x86.ActiveCfg = Debug|x64 - {8163E74C-DDE4-4507-BD3D-064CD95FF33B}.Release MT|x86.Build.0 = Debug|x64 - {8163E74C-DDE4-4507-BD3D-064CD95FF33B}.Release|x64.ActiveCfg = Release|x64 - {8163E74C-DDE4-4507-BD3D-064CD95FF33B}.Release|x64.Build.0 = Release|x64 - {8163E74C-DDE4-4507-BD3D-064CD95FF33B}.Release|x86.ActiveCfg = Release|x64 - {8163E74C-DDE4-4507-BD3D-064CD95FF33B}.RelWithDebInfo|x64.ActiveCfg = Release|x64 - {8163E74C-DDE4-4507-BD3D-064CD95FF33B}.RelWithDebInfo|x64.Build.0 = Release|x64 - {8163E74C-DDE4-4507-BD3D-064CD95FF33B}.RelWithDebInfo|x86.ActiveCfg = Debug|x64 - {8163E74C-DDE4-4507-BD3D-064CD95FF33B}.RelWithDebInfo|x86.Build.0 = Debug|x64 - {A79E2869-7626-4801-B09D-5C12F5163BA3}.DBG|x64.ActiveCfg = Debug|x64 - {A79E2869-7626-4801-B09D-5C12F5163BA3}.DBG|x64.Build.0 = Debug|x64 - {A79E2869-7626-4801-B09D-5C12F5163BA3}.DBG|x86.ActiveCfg = Debug|x64 - {A79E2869-7626-4801-B09D-5C12F5163BA3}.DBG|x86.Build.0 = Debug|x64 - {A79E2869-7626-4801-B09D-5C12F5163BA3}.Debug Kernel|x64.ActiveCfg = Debug|x64 - {A79E2869-7626-4801-B09D-5C12F5163BA3}.Debug Kernel|x64.Build.0 = Debug|x64 - {A79E2869-7626-4801-B09D-5C12F5163BA3}.Debug Kernel|x86.ActiveCfg = Debug|x64 - {A79E2869-7626-4801-B09D-5C12F5163BA3}.Debug Kernel|x86.Build.0 = Debug|x64 - {A79E2869-7626-4801-B09D-5C12F5163BA3}.Debug MD DLL|x64.ActiveCfg = Debug|x64 - {A79E2869-7626-4801-B09D-5C12F5163BA3}.Debug MD DLL|x64.Build.0 = Debug|x64 - {A79E2869-7626-4801-B09D-5C12F5163BA3}.Debug MD DLL|x86.ActiveCfg = Debug|x64 - {A79E2869-7626-4801-B09D-5C12F5163BA3}.Debug MD DLL|x86.Build.0 = Debug|x64 - {A79E2869-7626-4801-B09D-5C12F5163BA3}.Debug MD|x64.ActiveCfg = Debug|x64 - {A79E2869-7626-4801-B09D-5C12F5163BA3}.Debug MD|x64.Build.0 = Debug|x64 - {A79E2869-7626-4801-B09D-5C12F5163BA3}.Debug MD|x86.ActiveCfg = Debug|x64 - {A79E2869-7626-4801-B09D-5C12F5163BA3}.Debug MD|x86.Build.0 = Debug|x64 - {A79E2869-7626-4801-B09D-5C12F5163BA3}.Debug MT DLL|x64.ActiveCfg = Debug|x64 - {A79E2869-7626-4801-B09D-5C12F5163BA3}.Debug MT DLL|x64.Build.0 = Debug|x64 - {A79E2869-7626-4801-B09D-5C12F5163BA3}.Debug MT DLL|x86.ActiveCfg = Debug|x64 - {A79E2869-7626-4801-B09D-5C12F5163BA3}.Debug MT DLL|x86.Build.0 = Debug|x64 - {A79E2869-7626-4801-B09D-5C12F5163BA3}.Debug MT|x64.ActiveCfg = Debug|x64 - {A79E2869-7626-4801-B09D-5C12F5163BA3}.Debug MT|x64.Build.0 = Debug|x64 - {A79E2869-7626-4801-B09D-5C12F5163BA3}.Debug MT|x86.ActiveCfg = Debug|x64 - {A79E2869-7626-4801-B09D-5C12F5163BA3}.Debug MT|x86.Build.0 = Debug|x64 - {A79E2869-7626-4801-B09D-5C12F5163BA3}.Debug|x64.ActiveCfg = Debug|x64 - {A79E2869-7626-4801-B09D-5C12F5163BA3}.Debug|x64.Build.0 = Debug|x64 - {A79E2869-7626-4801-B09D-5C12F5163BA3}.Debug|x86.ActiveCfg = Debug|x64 - {A79E2869-7626-4801-B09D-5C12F5163BA3}.MinSizeRel|x64.ActiveCfg = Debug|x64 - {A79E2869-7626-4801-B09D-5C12F5163BA3}.MinSizeRel|x64.Build.0 = Debug|x64 - {A79E2869-7626-4801-B09D-5C12F5163BA3}.MinSizeRel|x86.ActiveCfg = Debug|x64 - {A79E2869-7626-4801-B09D-5C12F5163BA3}.MinSizeRel|x86.Build.0 = Debug|x64 - {A79E2869-7626-4801-B09D-5C12F5163BA3}.Release Kernel|x64.ActiveCfg = Release|x64 - {A79E2869-7626-4801-B09D-5C12F5163BA3}.Release Kernel|x64.Build.0 = Release|x64 - {A79E2869-7626-4801-B09D-5C12F5163BA3}.Release Kernel|x86.ActiveCfg = Debug|x64 - {A79E2869-7626-4801-B09D-5C12F5163BA3}.Release Kernel|x86.Build.0 = Debug|x64 - {A79E2869-7626-4801-B09D-5C12F5163BA3}.Release MD DLL|x64.ActiveCfg = Release|x64 - {A79E2869-7626-4801-B09D-5C12F5163BA3}.Release MD DLL|x64.Build.0 = Release|x64 - {A79E2869-7626-4801-B09D-5C12F5163BA3}.Release MD DLL|x86.ActiveCfg = Debug|x64 - {A79E2869-7626-4801-B09D-5C12F5163BA3}.Release MD DLL|x86.Build.0 = Debug|x64 - {A79E2869-7626-4801-B09D-5C12F5163BA3}.Release MD|x64.ActiveCfg = Release|x64 - {A79E2869-7626-4801-B09D-5C12F5163BA3}.Release MD|x64.Build.0 = Release|x64 - {A79E2869-7626-4801-B09D-5C12F5163BA3}.Release MD|x86.ActiveCfg = Debug|x64 - {A79E2869-7626-4801-B09D-5C12F5163BA3}.Release MD|x86.Build.0 = Debug|x64 - {A79E2869-7626-4801-B09D-5C12F5163BA3}.Release MT DLL|x64.ActiveCfg = Release|x64 - {A79E2869-7626-4801-B09D-5C12F5163BA3}.Release MT DLL|x64.Build.0 = Release|x64 - {A79E2869-7626-4801-B09D-5C12F5163BA3}.Release MT DLL|x86.ActiveCfg = Debug|x64 - {A79E2869-7626-4801-B09D-5C12F5163BA3}.Release MT DLL|x86.Build.0 = Debug|x64 - {A79E2869-7626-4801-B09D-5C12F5163BA3}.Release MT|x64.ActiveCfg = Release|x64 - {A79E2869-7626-4801-B09D-5C12F5163BA3}.Release MT|x64.Build.0 = Release|x64 - {A79E2869-7626-4801-B09D-5C12F5163BA3}.Release MT|x86.ActiveCfg = Debug|x64 - {A79E2869-7626-4801-B09D-5C12F5163BA3}.Release MT|x86.Build.0 = Debug|x64 - {A79E2869-7626-4801-B09D-5C12F5163BA3}.Release|x64.ActiveCfg = Release|x64 - {A79E2869-7626-4801-B09D-5C12F5163BA3}.Release|x64.Build.0 = Release|x64 - {A79E2869-7626-4801-B09D-5C12F5163BA3}.Release|x86.ActiveCfg = Release|x64 - {A79E2869-7626-4801-B09D-5C12F5163BA3}.RelWithDebInfo|x64.ActiveCfg = Release|x64 - {A79E2869-7626-4801-B09D-5C12F5163BA3}.RelWithDebInfo|x64.Build.0 = Release|x64 - {A79E2869-7626-4801-B09D-5C12F5163BA3}.RelWithDebInfo|x86.ActiveCfg = Debug|x64 - {A79E2869-7626-4801-B09D-5C12F5163BA3}.RelWithDebInfo|x86.Build.0 = Debug|x64 - {EC6B8F7F-730C-4086-B143-4664CC16DF8F}.DBG|x64.ActiveCfg = Debug|x64 - {EC6B8F7F-730C-4086-B143-4664CC16DF8F}.DBG|x64.Build.0 = Debug|x64 - {EC6B8F7F-730C-4086-B143-4664CC16DF8F}.DBG|x86.ActiveCfg = Debug|x64 - {EC6B8F7F-730C-4086-B143-4664CC16DF8F}.DBG|x86.Build.0 = Debug|x64 - {EC6B8F7F-730C-4086-B143-4664CC16DF8F}.Debug Kernel|x64.ActiveCfg = Debug|x64 - {EC6B8F7F-730C-4086-B143-4664CC16DF8F}.Debug Kernel|x64.Build.0 = Debug|x64 - {EC6B8F7F-730C-4086-B143-4664CC16DF8F}.Debug Kernel|x86.ActiveCfg = Debug|x64 - {EC6B8F7F-730C-4086-B143-4664CC16DF8F}.Debug Kernel|x86.Build.0 = Debug|x64 - {EC6B8F7F-730C-4086-B143-4664CC16DF8F}.Debug MD DLL|x64.ActiveCfg = Debug|x64 - {EC6B8F7F-730C-4086-B143-4664CC16DF8F}.Debug MD DLL|x64.Build.0 = Debug|x64 - {EC6B8F7F-730C-4086-B143-4664CC16DF8F}.Debug MD DLL|x86.ActiveCfg = Debug|x64 - {EC6B8F7F-730C-4086-B143-4664CC16DF8F}.Debug MD DLL|x86.Build.0 = Debug|x64 - {EC6B8F7F-730C-4086-B143-4664CC16DF8F}.Debug MD|x64.ActiveCfg = Debug|x64 - {EC6B8F7F-730C-4086-B143-4664CC16DF8F}.Debug MD|x64.Build.0 = Debug|x64 - {EC6B8F7F-730C-4086-B143-4664CC16DF8F}.Debug MD|x86.ActiveCfg = Debug|x64 - {EC6B8F7F-730C-4086-B143-4664CC16DF8F}.Debug MD|x86.Build.0 = Debug|x64 - {EC6B8F7F-730C-4086-B143-4664CC16DF8F}.Debug MT DLL|x64.ActiveCfg = Debug|x64 - {EC6B8F7F-730C-4086-B143-4664CC16DF8F}.Debug MT DLL|x64.Build.0 = Debug|x64 - {EC6B8F7F-730C-4086-B143-4664CC16DF8F}.Debug MT DLL|x86.ActiveCfg = Debug|x64 - {EC6B8F7F-730C-4086-B143-4664CC16DF8F}.Debug MT DLL|x86.Build.0 = Debug|x64 - {EC6B8F7F-730C-4086-B143-4664CC16DF8F}.Debug MT|x64.ActiveCfg = Debug|x64 - {EC6B8F7F-730C-4086-B143-4664CC16DF8F}.Debug MT|x64.Build.0 = Debug|x64 - {EC6B8F7F-730C-4086-B143-4664CC16DF8F}.Debug MT|x86.ActiveCfg = Debug|x64 - {EC6B8F7F-730C-4086-B143-4664CC16DF8F}.Debug MT|x86.Build.0 = Debug|x64 - {EC6B8F7F-730C-4086-B143-4664CC16DF8F}.Debug|x64.ActiveCfg = Debug|x64 - {EC6B8F7F-730C-4086-B143-4664CC16DF8F}.Debug|x64.Build.0 = Debug|x64 - {EC6B8F7F-730C-4086-B143-4664CC16DF8F}.Debug|x86.ActiveCfg = Debug|x64 - {EC6B8F7F-730C-4086-B143-4664CC16DF8F}.MinSizeRel|x64.ActiveCfg = Debug|x64 - {EC6B8F7F-730C-4086-B143-4664CC16DF8F}.MinSizeRel|x64.Build.0 = Debug|x64 - {EC6B8F7F-730C-4086-B143-4664CC16DF8F}.MinSizeRel|x86.ActiveCfg = Debug|x64 - {EC6B8F7F-730C-4086-B143-4664CC16DF8F}.MinSizeRel|x86.Build.0 = Debug|x64 - {EC6B8F7F-730C-4086-B143-4664CC16DF8F}.Release Kernel|x64.ActiveCfg = Release|x64 - {EC6B8F7F-730C-4086-B143-4664CC16DF8F}.Release Kernel|x64.Build.0 = Release|x64 - {EC6B8F7F-730C-4086-B143-4664CC16DF8F}.Release Kernel|x86.ActiveCfg = Debug|x64 - {EC6B8F7F-730C-4086-B143-4664CC16DF8F}.Release Kernel|x86.Build.0 = Debug|x64 - {EC6B8F7F-730C-4086-B143-4664CC16DF8F}.Release MD DLL|x64.ActiveCfg = Release|x64 - {EC6B8F7F-730C-4086-B143-4664CC16DF8F}.Release MD DLL|x64.Build.0 = Release|x64 - {EC6B8F7F-730C-4086-B143-4664CC16DF8F}.Release MD DLL|x86.ActiveCfg = Debug|x64 - {EC6B8F7F-730C-4086-B143-4664CC16DF8F}.Release MD DLL|x86.Build.0 = Debug|x64 - {EC6B8F7F-730C-4086-B143-4664CC16DF8F}.Release MD|x64.ActiveCfg = Release|x64 - {EC6B8F7F-730C-4086-B143-4664CC16DF8F}.Release MD|x64.Build.0 = Release|x64 - {EC6B8F7F-730C-4086-B143-4664CC16DF8F}.Release MD|x86.ActiveCfg = Debug|x64 - {EC6B8F7F-730C-4086-B143-4664CC16DF8F}.Release MD|x86.Build.0 = Debug|x64 - {EC6B8F7F-730C-4086-B143-4664CC16DF8F}.Release MT DLL|x64.ActiveCfg = Release|x64 - {EC6B8F7F-730C-4086-B143-4664CC16DF8F}.Release MT DLL|x64.Build.0 = Release|x64 - {EC6B8F7F-730C-4086-B143-4664CC16DF8F}.Release MT DLL|x86.ActiveCfg = Debug|x64 - {EC6B8F7F-730C-4086-B143-4664CC16DF8F}.Release MT DLL|x86.Build.0 = Debug|x64 - {EC6B8F7F-730C-4086-B143-4664CC16DF8F}.Release MT|x64.ActiveCfg = Release|x64 - {EC6B8F7F-730C-4086-B143-4664CC16DF8F}.Release MT|x64.Build.0 = Release|x64 - {EC6B8F7F-730C-4086-B143-4664CC16DF8F}.Release MT|x86.ActiveCfg = Debug|x64 - {EC6B8F7F-730C-4086-B143-4664CC16DF8F}.Release MT|x86.Build.0 = Debug|x64 - {EC6B8F7F-730C-4086-B143-4664CC16DF8F}.Release|x64.ActiveCfg = Release|x64 - {EC6B8F7F-730C-4086-B143-4664CC16DF8F}.Release|x64.Build.0 = Release|x64 - {EC6B8F7F-730C-4086-B143-4664CC16DF8F}.Release|x86.ActiveCfg = Release|x64 - {EC6B8F7F-730C-4086-B143-4664CC16DF8F}.RelWithDebInfo|x64.ActiveCfg = Release|x64 - {EC6B8F7F-730C-4086-B143-4664CC16DF8F}.RelWithDebInfo|x64.Build.0 = Release|x64 - {EC6B8F7F-730C-4086-B143-4664CC16DF8F}.RelWithDebInfo|x86.ActiveCfg = Debug|x64 - {EC6B8F7F-730C-4086-B143-4664CC16DF8F}.RelWithDebInfo|x86.Build.0 = Debug|x64 - {F960486B-2DB4-44AF-91BB-0F19F228ABCF}.DBG|x64.ActiveCfg = Debug|x64 - {F960486B-2DB4-44AF-91BB-0F19F228ABCF}.DBG|x64.Build.0 = Debug|x64 - {F960486B-2DB4-44AF-91BB-0F19F228ABCF}.DBG|x86.ActiveCfg = Debug|x64 - {F960486B-2DB4-44AF-91BB-0F19F228ABCF}.DBG|x86.Build.0 = Debug|x64 - {F960486B-2DB4-44AF-91BB-0F19F228ABCF}.Debug Kernel|x64.ActiveCfg = Debug|x64 - {F960486B-2DB4-44AF-91BB-0F19F228ABCF}.Debug Kernel|x64.Build.0 = Debug|x64 - {F960486B-2DB4-44AF-91BB-0F19F228ABCF}.Debug Kernel|x86.ActiveCfg = Debug|x64 - {F960486B-2DB4-44AF-91BB-0F19F228ABCF}.Debug Kernel|x86.Build.0 = Debug|x64 - {F960486B-2DB4-44AF-91BB-0F19F228ABCF}.Debug MD DLL|x64.ActiveCfg = Debug|x64 - {F960486B-2DB4-44AF-91BB-0F19F228ABCF}.Debug MD DLL|x64.Build.0 = Debug|x64 - {F960486B-2DB4-44AF-91BB-0F19F228ABCF}.Debug MD DLL|x86.ActiveCfg = Debug|x64 - {F960486B-2DB4-44AF-91BB-0F19F228ABCF}.Debug MD DLL|x86.Build.0 = Debug|x64 - {F960486B-2DB4-44AF-91BB-0F19F228ABCF}.Debug MD|x64.ActiveCfg = Debug|x64 - {F960486B-2DB4-44AF-91BB-0F19F228ABCF}.Debug MD|x64.Build.0 = Debug|x64 - {F960486B-2DB4-44AF-91BB-0F19F228ABCF}.Debug MD|x86.ActiveCfg = Debug|x64 - {F960486B-2DB4-44AF-91BB-0F19F228ABCF}.Debug MD|x86.Build.0 = Debug|x64 - {F960486B-2DB4-44AF-91BB-0F19F228ABCF}.Debug MT DLL|x64.ActiveCfg = Debug|x64 - {F960486B-2DB4-44AF-91BB-0F19F228ABCF}.Debug MT DLL|x64.Build.0 = Debug|x64 - {F960486B-2DB4-44AF-91BB-0F19F228ABCF}.Debug MT DLL|x86.ActiveCfg = Debug|x64 - {F960486B-2DB4-44AF-91BB-0F19F228ABCF}.Debug MT DLL|x86.Build.0 = Debug|x64 - {F960486B-2DB4-44AF-91BB-0F19F228ABCF}.Debug MT|x64.ActiveCfg = Debug|x64 - {F960486B-2DB4-44AF-91BB-0F19F228ABCF}.Debug MT|x64.Build.0 = Debug|x64 - {F960486B-2DB4-44AF-91BB-0F19F228ABCF}.Debug MT|x86.ActiveCfg = Debug|x64 - {F960486B-2DB4-44AF-91BB-0F19F228ABCF}.Debug MT|x86.Build.0 = Debug|x64 - {F960486B-2DB4-44AF-91BB-0F19F228ABCF}.Debug|x64.ActiveCfg = Debug|x64 - {F960486B-2DB4-44AF-91BB-0F19F228ABCF}.Debug|x64.Build.0 = Debug|x64 - {F960486B-2DB4-44AF-91BB-0F19F228ABCF}.Debug|x86.ActiveCfg = Debug|x64 - {F960486B-2DB4-44AF-91BB-0F19F228ABCF}.MinSizeRel|x64.ActiveCfg = Debug|x64 - {F960486B-2DB4-44AF-91BB-0F19F228ABCF}.MinSizeRel|x64.Build.0 = Debug|x64 - {F960486B-2DB4-44AF-91BB-0F19F228ABCF}.MinSizeRel|x86.ActiveCfg = Debug|x64 - {F960486B-2DB4-44AF-91BB-0F19F228ABCF}.MinSizeRel|x86.Build.0 = Debug|x64 - {F960486B-2DB4-44AF-91BB-0F19F228ABCF}.Release Kernel|x64.ActiveCfg = Release|x64 - {F960486B-2DB4-44AF-91BB-0F19F228ABCF}.Release Kernel|x64.Build.0 = Release|x64 - {F960486B-2DB4-44AF-91BB-0F19F228ABCF}.Release Kernel|x86.ActiveCfg = Debug|x64 - {F960486B-2DB4-44AF-91BB-0F19F228ABCF}.Release Kernel|x86.Build.0 = Debug|x64 - {F960486B-2DB4-44AF-91BB-0F19F228ABCF}.Release MD DLL|x64.ActiveCfg = Release|x64 - {F960486B-2DB4-44AF-91BB-0F19F228ABCF}.Release MD DLL|x64.Build.0 = Release|x64 - {F960486B-2DB4-44AF-91BB-0F19F228ABCF}.Release MD DLL|x86.ActiveCfg = Debug|x64 - {F960486B-2DB4-44AF-91BB-0F19F228ABCF}.Release MD DLL|x86.Build.0 = Debug|x64 - {F960486B-2DB4-44AF-91BB-0F19F228ABCF}.Release MD|x64.ActiveCfg = Release|x64 - {F960486B-2DB4-44AF-91BB-0F19F228ABCF}.Release MD|x64.Build.0 = Release|x64 - {F960486B-2DB4-44AF-91BB-0F19F228ABCF}.Release MD|x86.ActiveCfg = Debug|x64 - {F960486B-2DB4-44AF-91BB-0F19F228ABCF}.Release MD|x86.Build.0 = Debug|x64 - {F960486B-2DB4-44AF-91BB-0F19F228ABCF}.Release MT DLL|x64.ActiveCfg = Release|x64 - {F960486B-2DB4-44AF-91BB-0F19F228ABCF}.Release MT DLL|x64.Build.0 = Release|x64 - {F960486B-2DB4-44AF-91BB-0F19F228ABCF}.Release MT DLL|x86.ActiveCfg = Debug|x64 - {F960486B-2DB4-44AF-91BB-0F19F228ABCF}.Release MT DLL|x86.Build.0 = Debug|x64 - {F960486B-2DB4-44AF-91BB-0F19F228ABCF}.Release MT|x64.ActiveCfg = Release|x64 - {F960486B-2DB4-44AF-91BB-0F19F228ABCF}.Release MT|x64.Build.0 = Release|x64 - {F960486B-2DB4-44AF-91BB-0F19F228ABCF}.Release MT|x86.ActiveCfg = Debug|x64 - {F960486B-2DB4-44AF-91BB-0F19F228ABCF}.Release MT|x86.Build.0 = Debug|x64 - {F960486B-2DB4-44AF-91BB-0F19F228ABCF}.Release|x64.ActiveCfg = Release|x64 - {F960486B-2DB4-44AF-91BB-0F19F228ABCF}.Release|x64.Build.0 = Release|x64 - {F960486B-2DB4-44AF-91BB-0F19F228ABCF}.Release|x86.ActiveCfg = Release|x64 - {F960486B-2DB4-44AF-91BB-0F19F228ABCF}.RelWithDebInfo|x64.ActiveCfg = Release|x64 - {F960486B-2DB4-44AF-91BB-0F19F228ABCF}.RelWithDebInfo|x64.Build.0 = Release|x64 - {F960486B-2DB4-44AF-91BB-0F19F228ABCF}.RelWithDebInfo|x86.ActiveCfg = Debug|x64 - {F960486B-2DB4-44AF-91BB-0F19F228ABCF}.RelWithDebInfo|x86.Build.0 = Debug|x64 - {FE3202CE-D05C-4E04-AE9B-D30305D8CE31}.DBG|x64.ActiveCfg = Debug|x64 - {FE3202CE-D05C-4E04-AE9B-D30305D8CE31}.DBG|x64.Build.0 = Debug|x64 - {FE3202CE-D05C-4E04-AE9B-D30305D8CE31}.DBG|x86.ActiveCfg = Debug|x64 - {FE3202CE-D05C-4E04-AE9B-D30305D8CE31}.DBG|x86.Build.0 = Debug|x64 - {FE3202CE-D05C-4E04-AE9B-D30305D8CE31}.Debug Kernel|x64.ActiveCfg = Debug|x64 - {FE3202CE-D05C-4E04-AE9B-D30305D8CE31}.Debug Kernel|x64.Build.0 = Debug|x64 - {FE3202CE-D05C-4E04-AE9B-D30305D8CE31}.Debug Kernel|x86.ActiveCfg = Debug|x64 - {FE3202CE-D05C-4E04-AE9B-D30305D8CE31}.Debug Kernel|x86.Build.0 = Debug|x64 - {FE3202CE-D05C-4E04-AE9B-D30305D8CE31}.Debug MD DLL|x64.ActiveCfg = Debug|x64 - {FE3202CE-D05C-4E04-AE9B-D30305D8CE31}.Debug MD DLL|x64.Build.0 = Debug|x64 - {FE3202CE-D05C-4E04-AE9B-D30305D8CE31}.Debug MD DLL|x86.ActiveCfg = Debug|x64 - {FE3202CE-D05C-4E04-AE9B-D30305D8CE31}.Debug MD DLL|x86.Build.0 = Debug|x64 - {FE3202CE-D05C-4E04-AE9B-D30305D8CE31}.Debug MD|x64.ActiveCfg = Debug|x64 - {FE3202CE-D05C-4E04-AE9B-D30305D8CE31}.Debug MD|x64.Build.0 = Debug|x64 - {FE3202CE-D05C-4E04-AE9B-D30305D8CE31}.Debug MD|x86.ActiveCfg = Debug|x64 - {FE3202CE-D05C-4E04-AE9B-D30305D8CE31}.Debug MD|x86.Build.0 = Debug|x64 - {FE3202CE-D05C-4E04-AE9B-D30305D8CE31}.Debug MT DLL|x64.ActiveCfg = Debug|x64 - {FE3202CE-D05C-4E04-AE9B-D30305D8CE31}.Debug MT DLL|x64.Build.0 = Debug|x64 - {FE3202CE-D05C-4E04-AE9B-D30305D8CE31}.Debug MT DLL|x86.ActiveCfg = Debug|x64 - {FE3202CE-D05C-4E04-AE9B-D30305D8CE31}.Debug MT DLL|x86.Build.0 = Debug|x64 - {FE3202CE-D05C-4E04-AE9B-D30305D8CE31}.Debug MT|x64.ActiveCfg = Debug|x64 - {FE3202CE-D05C-4E04-AE9B-D30305D8CE31}.Debug MT|x64.Build.0 = Debug|x64 - {FE3202CE-D05C-4E04-AE9B-D30305D8CE31}.Debug MT|x86.ActiveCfg = Debug|x64 - {FE3202CE-D05C-4E04-AE9B-D30305D8CE31}.Debug MT|x86.Build.0 = Debug|x64 - {FE3202CE-D05C-4E04-AE9B-D30305D8CE31}.Debug|x64.ActiveCfg = Debug|x64 - {FE3202CE-D05C-4E04-AE9B-D30305D8CE31}.Debug|x64.Build.0 = Debug|x64 - {FE3202CE-D05C-4E04-AE9B-D30305D8CE31}.Debug|x86.ActiveCfg = Debug|x64 - {FE3202CE-D05C-4E04-AE9B-D30305D8CE31}.MinSizeRel|x64.ActiveCfg = Debug|x64 - {FE3202CE-D05C-4E04-AE9B-D30305D8CE31}.MinSizeRel|x64.Build.0 = Debug|x64 - {FE3202CE-D05C-4E04-AE9B-D30305D8CE31}.MinSizeRel|x86.ActiveCfg = Debug|x64 - {FE3202CE-D05C-4E04-AE9B-D30305D8CE31}.MinSizeRel|x86.Build.0 = Debug|x64 - {FE3202CE-D05C-4E04-AE9B-D30305D8CE31}.Release Kernel|x64.ActiveCfg = Release|x64 - {FE3202CE-D05C-4E04-AE9B-D30305D8CE31}.Release Kernel|x64.Build.0 = Release|x64 - {FE3202CE-D05C-4E04-AE9B-D30305D8CE31}.Release Kernel|x86.ActiveCfg = Debug|x64 - {FE3202CE-D05C-4E04-AE9B-D30305D8CE31}.Release Kernel|x86.Build.0 = Debug|x64 - {FE3202CE-D05C-4E04-AE9B-D30305D8CE31}.Release MD DLL|x64.ActiveCfg = Release|x64 - {FE3202CE-D05C-4E04-AE9B-D30305D8CE31}.Release MD DLL|x64.Build.0 = Release|x64 - {FE3202CE-D05C-4E04-AE9B-D30305D8CE31}.Release MD DLL|x86.ActiveCfg = Debug|x64 - {FE3202CE-D05C-4E04-AE9B-D30305D8CE31}.Release MD DLL|x86.Build.0 = Debug|x64 - {FE3202CE-D05C-4E04-AE9B-D30305D8CE31}.Release MD|x64.ActiveCfg = Release|x64 - {FE3202CE-D05C-4E04-AE9B-D30305D8CE31}.Release MD|x64.Build.0 = Release|x64 - {FE3202CE-D05C-4E04-AE9B-D30305D8CE31}.Release MD|x86.ActiveCfg = Debug|x64 - {FE3202CE-D05C-4E04-AE9B-D30305D8CE31}.Release MD|x86.Build.0 = Debug|x64 - {FE3202CE-D05C-4E04-AE9B-D30305D8CE31}.Release MT DLL|x64.ActiveCfg = Release|x64 - {FE3202CE-D05C-4E04-AE9B-D30305D8CE31}.Release MT DLL|x64.Build.0 = Release|x64 - {FE3202CE-D05C-4E04-AE9B-D30305D8CE31}.Release MT DLL|x86.ActiveCfg = Debug|x64 - {FE3202CE-D05C-4E04-AE9B-D30305D8CE31}.Release MT DLL|x86.Build.0 = Debug|x64 - {FE3202CE-D05C-4E04-AE9B-D30305D8CE31}.Release MT|x64.ActiveCfg = Release|x64 - {FE3202CE-D05C-4E04-AE9B-D30305D8CE31}.Release MT|x64.Build.0 = Release|x64 - {FE3202CE-D05C-4E04-AE9B-D30305D8CE31}.Release MT|x86.ActiveCfg = Debug|x64 - {FE3202CE-D05C-4E04-AE9B-D30305D8CE31}.Release MT|x86.Build.0 = Debug|x64 - {FE3202CE-D05C-4E04-AE9B-D30305D8CE31}.Release|x64.ActiveCfg = Release|x64 - {FE3202CE-D05C-4E04-AE9B-D30305D8CE31}.Release|x64.Build.0 = Release|x64 - {FE3202CE-D05C-4E04-AE9B-D30305D8CE31}.Release|x86.ActiveCfg = Release|x64 - {FE3202CE-D05C-4E04-AE9B-D30305D8CE31}.RelWithDebInfo|x64.ActiveCfg = Release|x64 - {FE3202CE-D05C-4E04-AE9B-D30305D8CE31}.RelWithDebInfo|x64.Build.0 = Release|x64 - {FE3202CE-D05C-4E04-AE9B-D30305D8CE31}.RelWithDebInfo|x86.ActiveCfg = Debug|x64 - {FE3202CE-D05C-4E04-AE9B-D30305D8CE31}.RelWithDebInfo|x86.Build.0 = Debug|x64 - {E4754E3E-2503-307A-8076-8AC2AD8B75B2}.DBG|x64.ActiveCfg = Debug|x64 - {E4754E3E-2503-307A-8076-8AC2AD8B75B2}.DBG|x64.Build.0 = Debug|x64 - {E4754E3E-2503-307A-8076-8AC2AD8B75B2}.DBG|x86.ActiveCfg = RelWithDebInfo|x64 - {E4754E3E-2503-307A-8076-8AC2AD8B75B2}.DBG|x86.Build.0 = RelWithDebInfo|x64 - {E4754E3E-2503-307A-8076-8AC2AD8B75B2}.Debug Kernel|x64.ActiveCfg = Debug|x64 - {E4754E3E-2503-307A-8076-8AC2AD8B75B2}.Debug Kernel|x64.Build.0 = Debug|x64 - {E4754E3E-2503-307A-8076-8AC2AD8B75B2}.Debug Kernel|x86.ActiveCfg = RelWithDebInfo|x64 - {E4754E3E-2503-307A-8076-8AC2AD8B75B2}.Debug Kernel|x86.Build.0 = RelWithDebInfo|x64 - {E4754E3E-2503-307A-8076-8AC2AD8B75B2}.Debug MD DLL|x64.ActiveCfg = Debug|x64 - {E4754E3E-2503-307A-8076-8AC2AD8B75B2}.Debug MD DLL|x64.Build.0 = Debug|x64 - {E4754E3E-2503-307A-8076-8AC2AD8B75B2}.Debug MD DLL|x86.ActiveCfg = RelWithDebInfo|x64 - {E4754E3E-2503-307A-8076-8AC2AD8B75B2}.Debug MD DLL|x86.Build.0 = RelWithDebInfo|x64 - {E4754E3E-2503-307A-8076-8AC2AD8B75B2}.Debug MD|x64.ActiveCfg = Debug|x64 - {E4754E3E-2503-307A-8076-8AC2AD8B75B2}.Debug MD|x64.Build.0 = Debug|x64 - {E4754E3E-2503-307A-8076-8AC2AD8B75B2}.Debug MD|x86.ActiveCfg = RelWithDebInfo|x64 - {E4754E3E-2503-307A-8076-8AC2AD8B75B2}.Debug MD|x86.Build.0 = RelWithDebInfo|x64 - {E4754E3E-2503-307A-8076-8AC2AD8B75B2}.Debug MT DLL|x64.ActiveCfg = Debug|x64 - {E4754E3E-2503-307A-8076-8AC2AD8B75B2}.Debug MT DLL|x64.Build.0 = Debug|x64 - {E4754E3E-2503-307A-8076-8AC2AD8B75B2}.Debug MT DLL|x86.ActiveCfg = RelWithDebInfo|x64 - {E4754E3E-2503-307A-8076-8AC2AD8B75B2}.Debug MT DLL|x86.Build.0 = RelWithDebInfo|x64 - {E4754E3E-2503-307A-8076-8AC2AD8B75B2}.Debug MT|x64.ActiveCfg = Debug|x64 - {E4754E3E-2503-307A-8076-8AC2AD8B75B2}.Debug MT|x64.Build.0 = Debug|x64 - {E4754E3E-2503-307A-8076-8AC2AD8B75B2}.Debug MT|x86.ActiveCfg = RelWithDebInfo|x64 - {E4754E3E-2503-307A-8076-8AC2AD8B75B2}.Debug MT|x86.Build.0 = RelWithDebInfo|x64 - {E4754E3E-2503-307A-8076-8AC2AD8B75B2}.Debug|x64.ActiveCfg = Debug|x64 - {E4754E3E-2503-307A-8076-8AC2AD8B75B2}.Debug|x64.Build.0 = Debug|x64 - {E4754E3E-2503-307A-8076-8AC2AD8B75B2}.Debug|x86.ActiveCfg = Debug|x64 - {E4754E3E-2503-307A-8076-8AC2AD8B75B2}.MinSizeRel|x64.ActiveCfg = MinSizeRel|x64 - {E4754E3E-2503-307A-8076-8AC2AD8B75B2}.MinSizeRel|x64.Build.0 = MinSizeRel|x64 - {E4754E3E-2503-307A-8076-8AC2AD8B75B2}.MinSizeRel|x86.ActiveCfg = MinSizeRel|x64 - {E4754E3E-2503-307A-8076-8AC2AD8B75B2}.Release Kernel|x64.ActiveCfg = Release|x64 - {E4754E3E-2503-307A-8076-8AC2AD8B75B2}.Release Kernel|x64.Build.0 = Release|x64 - {E4754E3E-2503-307A-8076-8AC2AD8B75B2}.Release Kernel|x86.ActiveCfg = RelWithDebInfo|x64 - {E4754E3E-2503-307A-8076-8AC2AD8B75B2}.Release Kernel|x86.Build.0 = RelWithDebInfo|x64 - {E4754E3E-2503-307A-8076-8AC2AD8B75B2}.Release MD DLL|x64.ActiveCfg = Release|x64 - {E4754E3E-2503-307A-8076-8AC2AD8B75B2}.Release MD DLL|x64.Build.0 = Release|x64 - {E4754E3E-2503-307A-8076-8AC2AD8B75B2}.Release MD DLL|x86.ActiveCfg = RelWithDebInfo|x64 - {E4754E3E-2503-307A-8076-8AC2AD8B75B2}.Release MD DLL|x86.Build.0 = RelWithDebInfo|x64 - {E4754E3E-2503-307A-8076-8AC2AD8B75B2}.Release MD|x64.ActiveCfg = Release|x64 - {E4754E3E-2503-307A-8076-8AC2AD8B75B2}.Release MD|x64.Build.0 = Release|x64 - {E4754E3E-2503-307A-8076-8AC2AD8B75B2}.Release MD|x86.ActiveCfg = RelWithDebInfo|x64 - {E4754E3E-2503-307A-8076-8AC2AD8B75B2}.Release MD|x86.Build.0 = RelWithDebInfo|x64 - {E4754E3E-2503-307A-8076-8AC2AD8B75B2}.Release MT DLL|x64.ActiveCfg = Release|x64 - {E4754E3E-2503-307A-8076-8AC2AD8B75B2}.Release MT DLL|x64.Build.0 = Release|x64 - {E4754E3E-2503-307A-8076-8AC2AD8B75B2}.Release MT DLL|x86.ActiveCfg = RelWithDebInfo|x64 - {E4754E3E-2503-307A-8076-8AC2AD8B75B2}.Release MT DLL|x86.Build.0 = RelWithDebInfo|x64 - {E4754E3E-2503-307A-8076-8AC2AD8B75B2}.Release MT|x64.ActiveCfg = Release|x64 - {E4754E3E-2503-307A-8076-8AC2AD8B75B2}.Release MT|x64.Build.0 = Release|x64 - {E4754E3E-2503-307A-8076-8AC2AD8B75B2}.Release MT|x86.ActiveCfg = RelWithDebInfo|x64 - {E4754E3E-2503-307A-8076-8AC2AD8B75B2}.Release MT|x86.Build.0 = RelWithDebInfo|x64 - {E4754E3E-2503-307A-8076-8AC2AD8B75B2}.Release|x64.ActiveCfg = Release|x64 - {E4754E3E-2503-307A-8076-8AC2AD8B75B2}.Release|x64.Build.0 = Release|x64 - {E4754E3E-2503-307A-8076-8AC2AD8B75B2}.Release|x86.ActiveCfg = Release|x64 - {E4754E3E-2503-307A-8076-8AC2AD8B75B2}.RelWithDebInfo|x64.ActiveCfg = RelWithDebInfo|x64 - {E4754E3E-2503-307A-8076-8AC2AD8B75B2}.RelWithDebInfo|x64.Build.0 = RelWithDebInfo|x64 - {E4754E3E-2503-307A-8076-8AC2AD8B75B2}.RelWithDebInfo|x86.ActiveCfg = RelWithDebInfo|x64 - {A0471FDD-F210-3D7E-B4EA-20543BC10911}.DBG|x64.ActiveCfg = Debug|x64 - {A0471FDD-F210-3D7E-B4EA-20543BC10911}.DBG|x64.Build.0 = Debug|x64 - {A0471FDD-F210-3D7E-B4EA-20543BC10911}.DBG|x86.ActiveCfg = RelWithDebInfo|x64 - {A0471FDD-F210-3D7E-B4EA-20543BC10911}.DBG|x86.Build.0 = RelWithDebInfo|x64 - {A0471FDD-F210-3D7E-B4EA-20543BC10911}.Debug Kernel|x64.ActiveCfg = Debug|x64 - {A0471FDD-F210-3D7E-B4EA-20543BC10911}.Debug Kernel|x64.Build.0 = Debug|x64 - {A0471FDD-F210-3D7E-B4EA-20543BC10911}.Debug Kernel|x86.ActiveCfg = RelWithDebInfo|x64 - {A0471FDD-F210-3D7E-B4EA-20543BC10911}.Debug Kernel|x86.Build.0 = RelWithDebInfo|x64 - {A0471FDD-F210-3D7E-B4EA-20543BC10911}.Debug MD DLL|x64.ActiveCfg = Debug|x64 - {A0471FDD-F210-3D7E-B4EA-20543BC10911}.Debug MD DLL|x64.Build.0 = Debug|x64 - {A0471FDD-F210-3D7E-B4EA-20543BC10911}.Debug MD DLL|x86.ActiveCfg = RelWithDebInfo|x64 - {A0471FDD-F210-3D7E-B4EA-20543BC10911}.Debug MD DLL|x86.Build.0 = RelWithDebInfo|x64 - {A0471FDD-F210-3D7E-B4EA-20543BC10911}.Debug MD|x64.ActiveCfg = Debug|x64 - {A0471FDD-F210-3D7E-B4EA-20543BC10911}.Debug MD|x64.Build.0 = Debug|x64 - {A0471FDD-F210-3D7E-B4EA-20543BC10911}.Debug MD|x86.ActiveCfg = RelWithDebInfo|x64 - {A0471FDD-F210-3D7E-B4EA-20543BC10911}.Debug MD|x86.Build.0 = RelWithDebInfo|x64 - {A0471FDD-F210-3D7E-B4EA-20543BC10911}.Debug MT DLL|x64.ActiveCfg = Debug|x64 - {A0471FDD-F210-3D7E-B4EA-20543BC10911}.Debug MT DLL|x64.Build.0 = Debug|x64 - {A0471FDD-F210-3D7E-B4EA-20543BC10911}.Debug MT DLL|x86.ActiveCfg = RelWithDebInfo|x64 - {A0471FDD-F210-3D7E-B4EA-20543BC10911}.Debug MT DLL|x86.Build.0 = RelWithDebInfo|x64 - {A0471FDD-F210-3D7E-B4EA-20543BC10911}.Debug MT|x64.ActiveCfg = Debug|x64 - {A0471FDD-F210-3D7E-B4EA-20543BC10911}.Debug MT|x64.Build.0 = Debug|x64 - {A0471FDD-F210-3D7E-B4EA-20543BC10911}.Debug MT|x86.ActiveCfg = RelWithDebInfo|x64 - {A0471FDD-F210-3D7E-B4EA-20543BC10911}.Debug MT|x86.Build.0 = RelWithDebInfo|x64 - {A0471FDD-F210-3D7E-B4EA-20543BC10911}.Debug|x64.ActiveCfg = Debug|x64 - {A0471FDD-F210-3D7E-B4EA-20543BC10911}.Debug|x64.Build.0 = Debug|x64 - {A0471FDD-F210-3D7E-B4EA-20543BC10911}.Debug|x86.ActiveCfg = Debug|x64 - {A0471FDD-F210-3D7E-B4EA-20543BC10911}.MinSizeRel|x64.ActiveCfg = MinSizeRel|x64 - {A0471FDD-F210-3D7E-B4EA-20543BC10911}.MinSizeRel|x64.Build.0 = MinSizeRel|x64 - {A0471FDD-F210-3D7E-B4EA-20543BC10911}.MinSizeRel|x86.ActiveCfg = MinSizeRel|x64 - {A0471FDD-F210-3D7E-B4EA-20543BC10911}.Release Kernel|x64.ActiveCfg = Release|x64 - {A0471FDD-F210-3D7E-B4EA-20543BC10911}.Release Kernel|x64.Build.0 = Release|x64 - {A0471FDD-F210-3D7E-B4EA-20543BC10911}.Release Kernel|x86.ActiveCfg = RelWithDebInfo|x64 - {A0471FDD-F210-3D7E-B4EA-20543BC10911}.Release Kernel|x86.Build.0 = RelWithDebInfo|x64 - {A0471FDD-F210-3D7E-B4EA-20543BC10911}.Release MD DLL|x64.ActiveCfg = Release|x64 - {A0471FDD-F210-3D7E-B4EA-20543BC10911}.Release MD DLL|x64.Build.0 = Release|x64 - {A0471FDD-F210-3D7E-B4EA-20543BC10911}.Release MD DLL|x86.ActiveCfg = RelWithDebInfo|x64 - {A0471FDD-F210-3D7E-B4EA-20543BC10911}.Release MD DLL|x86.Build.0 = RelWithDebInfo|x64 - {A0471FDD-F210-3D7E-B4EA-20543BC10911}.Release MD|x64.ActiveCfg = Release|x64 - {A0471FDD-F210-3D7E-B4EA-20543BC10911}.Release MD|x64.Build.0 = Release|x64 - {A0471FDD-F210-3D7E-B4EA-20543BC10911}.Release MD|x86.ActiveCfg = RelWithDebInfo|x64 - {A0471FDD-F210-3D7E-B4EA-20543BC10911}.Release MD|x86.Build.0 = RelWithDebInfo|x64 - {A0471FDD-F210-3D7E-B4EA-20543BC10911}.Release MT DLL|x64.ActiveCfg = Release|x64 - {A0471FDD-F210-3D7E-B4EA-20543BC10911}.Release MT DLL|x64.Build.0 = Release|x64 - {A0471FDD-F210-3D7E-B4EA-20543BC10911}.Release MT DLL|x86.ActiveCfg = RelWithDebInfo|x64 - {A0471FDD-F210-3D7E-B4EA-20543BC10911}.Release MT DLL|x86.Build.0 = RelWithDebInfo|x64 - {A0471FDD-F210-3D7E-B4EA-20543BC10911}.Release MT|x64.ActiveCfg = Release|x64 - {A0471FDD-F210-3D7E-B4EA-20543BC10911}.Release MT|x64.Build.0 = Release|x64 - {A0471FDD-F210-3D7E-B4EA-20543BC10911}.Release MT|x86.ActiveCfg = RelWithDebInfo|x64 - {A0471FDD-F210-3D7E-B4EA-20543BC10911}.Release MT|x86.Build.0 = RelWithDebInfo|x64 - {A0471FDD-F210-3D7E-B4EA-20543BC10911}.Release|x64.ActiveCfg = Release|x64 - {A0471FDD-F210-3D7E-B4EA-20543BC10911}.Release|x64.Build.0 = Release|x64 - {A0471FDD-F210-3D7E-B4EA-20543BC10911}.Release|x86.ActiveCfg = Release|x64 - {A0471FDD-F210-3D7E-B4EA-20543BC10911}.RelWithDebInfo|x64.ActiveCfg = RelWithDebInfo|x64 - {A0471FDD-F210-3D7E-B4EA-20543BC10911}.RelWithDebInfo|x64.Build.0 = RelWithDebInfo|x64 - {A0471FDD-F210-3D7E-B4EA-20543BC10911}.RelWithDebInfo|x86.ActiveCfg = RelWithDebInfo|x64 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {88A23124-5640-35A0-B890-311D7A67A7D2} = {7EE14D03-ED3D-4FA2-8974-8A285C974E3D} - {D0B6092A-9944-4F24-9486-4B7DAE372619} = {7EE14D03-ED3D-4FA2-8974-8A285C974E3D} - {8163E74C-DDE4-4507-BD3D-064CD95FF33B} = {7EE14D03-ED3D-4FA2-8974-8A285C974E3D} - {A79E2869-7626-4801-B09D-5C12F5163BA3} = {7EE14D03-ED3D-4FA2-8974-8A285C974E3D} - {EC6B8F7F-730C-4086-B143-4664CC16DF8F} = {7EE14D03-ED3D-4FA2-8974-8A285C974E3D} - {F960486B-2DB4-44AF-91BB-0F19F228ABCF} = {7EE14D03-ED3D-4FA2-8974-8A285C974E3D} - {FE3202CE-D05C-4E04-AE9B-D30305D8CE31} = {7EE14D03-ED3D-4FA2-8974-8A285C974E3D} - {E4754E3E-2503-307A-8076-8AC2AD8B75B2} = {7EE14D03-ED3D-4FA2-8974-8A285C974E3D} - {A0471FDD-F210-3D7E-B4EA-20543BC10911} = {7EE14D03-ED3D-4FA2-8974-8A285C974E3D} - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {9D649C1A-9B35-44E4-BDBD-47FBE15E06DD} - EndGlobalSection -EndGlobal diff --git a/vmemu.vcxproj b/vmemu.vcxproj deleted file mode 100644 index 2ac3cac..0000000 --- a/vmemu.vcxproj +++ /dev/null @@ -1,181 +0,0 @@ - - - - - Debug - x64 - - - Release - x64 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {a79e2869-7626-4801-b09d-5c12f5163ba3} - - - {ec6b8f7f-730c-4086-b143-4664cc16df8f} - - - {f960486b-2db4-44af-91bb-0f19f228abcf} - - - {fe3202ce-d05c-4e04-ae9b-d30305d8ce31} - - - {8163e74c-dde4-4507-bd3d-064cd95ff33b} - - - {88a23124-5640-35a0-b890-311d7a67a7d2} - - - {d0b6092a-9944-4f24-9486-4b7dae372619} - - - - 16.0 - Win32Proj - {f0d51879-e659-4bd3-b688-7864db3c82aa} - vmemu - 10.0 - - - - Application - true - v142 - Unicode - - - Application - false - v142 - true - Unicode - - - - - - - - - - - - - - - true - $(ProjectDir)dependencies\unicorn\include\;$(ProjectDir)dependencies\xtils\;$(ProjectDir)dependencies\vmprofiler\include\;$(ProjectDir)dependencies\cli-parser\;$(ProjectDir)dependencies\vmprofiler\dependencies\zydis\include;$(ProjectDir)dependencies\vmprofiler\dependencies\zydis\dependencies\zycore\include;$(ProjectDir)dependencies\vmprofiler\dependencies\zydis\msvc;$(IncludePath) - - - false - $(ProjectDir)dependencies\unicorn\include\;$(ProjectDir)dependencies\xtils\;$(ProjectDir)dependencies\vmprofiler\include\;$(ProjectDir)dependencies\cli-parser\;$(ProjectDir)dependencies\vmprofiler\dependencies\zydis\include;$(ProjectDir)dependencies\vmprofiler\dependencies\zydis\dependencies\zycore\include;$(ProjectDir)dependencies\vmprofiler\dependencies\zydis\msvc;$(ProjectDir)dependencies\vmprofiler\dependencies\vtil\VTIL\includes\;$(ProjectDir)dependencies\vmprofiler\dependencies\vtil\VTIL-Architecture\includes\;$(ProjectDir)dependencies\vmprofiler\dependencies\vtil\VTIL-Common\includes\;$(ProjectDir)dependencies\vmprofiler\dependencies\vtil\VTIL-Compiler\includes\;$(ProjectDir)dependencies\vmprofiler\dependencies\vtil\VTIL-SymEx\includes\;$(ProjectDir)dependencies\vmprofiler\dependencies\vtil\dependencies\capstone\include;$(ProjectDir)dependencies\vmprofiler\dependencies\vtil\dependencies\keystone\include;$(IncludePath) - - - - Level3 - true - _DEBUG;_CONSOLE;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS;ZYDIS_STATIC_DEFINE - true - stdcpp17 - - - Console - true - $(ProjectDir)dependencies\unicorn\msvc\x64\Debug\*.lib;%(AdditionalDependencies) - - - - - Level3 - true - true - true - NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions);_CRT_SECURE_NO_WARNINGS;ZYDIS_STATIC_DEFINE - true - Disabled - stdcpplatest - - - Console - true - true - true - $(ProjectDir)dependencies\unicorn\msvc\x64\Release\*.lib;%(AdditionalDependencies) - 4194304 - 4194304 - - - - - - \ No newline at end of file diff --git a/vmemu.vcxproj.filters b/vmemu.vcxproj.filters deleted file mode 100644 index bade4e8..0000000 --- a/vmemu.vcxproj.filters +++ /dev/null @@ -1,230 +0,0 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd - - - {0e65ecf2-7cf9-449e-ac20-f6f27fa629c0} - - - {259313a0-e773-46e6-9960-61605385a4ac} - - - {08d401b5-5aae-4d6a-a074-a4777c64db3c} - - - {9daf9cd5-9ffb-44d5-9bc4-18d289129a5e} - - - {b36cf687-0a35-4dcc-8593-e6f065702197} - - - {f99ac6e7-b1d9-4877-a45b-12e422ea2003} - - - {dbddce53-e0ac-4b58-b5c9-3e3325ef5d43} - - - {19233bd7-fbee-4047-aedc-e2352cd634cb} - - - {084b3477-86b1-4088-82a3-d67a0d5f017d} - - - - - Source Files - - - Source Files - - - - - Header Files - - - Header Files\Zydis\Internal - - - Header Files\Zydis\Internal - - - Header Files\Zydis\Internal - - - Header Files\Zydis\Internal - - - Header Files\Zydis\Internal - - - Header Files\Zydis\Internal - - - Header Files\Zydis\Generated - - - Header Files\Zydis\Generated - - - Header Files\Zydis\Generated - - - Header Files\Zydis\Generated - - - Header Files\Zydis\Generated - - - Header Files\Zydis - - - Header Files\Zydis - - - Header Files\Zydis - - - Header Files\Zydis - - - Header Files\Zydis - - - Header Files\Zydis - - - Header Files\Zydis - - - Header Files\Zydis - - - Header Files\Zydis - - - Header Files\Zydis - - - Header Files\Zydis - - - Header Files\Zydis - - - Header Files\Zycore\API - - - Header Files\Zycore\API - - - Header Files\Zycore\API - - - Header Files\Zycore\API - - - Header Files\Zycore - - - Header Files\Zycore - - - Header Files\Zycore - - - Header Files\Zycore - - - Header Files\Zycore - - - Header Files\Zycore - - - Header Files\Zycore - - - Header Files\Zycore - - - Header Files\Zycore - - - Header Files\Zycore - - - Header Files\Zycore - - - Header Files\Zycore - - - Header Files\Zycore - - - Header Files\Zycore - - - Header Files\unicorn - - - Header Files\unicorn - - - Header Files\unicorn - - - Header Files\unicorn\unicorn - - - Header Files\unicorn\unicorn - - - Header Files\unicorn\unicorn - - - Header Files\unicorn\unicorn - - - Header Files\unicorn\unicorn - - - Header Files\unicorn\unicorn - - - Header Files\unicorn\unicorn - - - Header Files\unicorn\unicorn - - - Header Files\xtils - - - Header Files\vmprofiler - - - Header Files\vmprofiler - - - Header Files\vmprofiler - - - Header Files\vmprofiler - - - Header Files - - - Header Files - - - \ No newline at end of file From 3dd5f9d7caf7b75d7186095a708382451f8cb2fe Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Fri, 30 Jul 2021 17:56:14 -0700 Subject: [PATCH 02/12] porting older unpacker code to vmemu... also rewriting vmemu... --- include/unpacker.hpp | 60 +++++++++ include/vmemu_t.hpp | 4 + src/main.cpp | 209 ++++++++++++++++-------------- src/unpacker.cpp | 294 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 475 insertions(+), 92 deletions(-) diff --git a/include/unpacker.hpp b/include/unpacker.hpp index e69de29..9e817a5 100644 --- a/include/unpacker.hpp +++ b/include/unpacker.hpp @@ -0,0 +1,60 @@ +#pragma once +#include + +#include +#include +#include +#include +#include +#include + +#define PAGE_4KB 0x1000 +#define STACK_SIZE PAGE_4KB * 512 + +#define IAT_VECTOR_TABLE 0xFFFFF0000000000 +#define STACK_BASE 0xFFFF000000000000 + +#define EX_ALLOCATE_POOL_VECTOR 0 +#define EX_FREE_POOL_VECTOR 1 +#define LOCAL_ALLOC_VECTOR 2 +#define LOCAL_FREE_VECTOR 3 + +namespace engine +{ + using iat_hook_t = std::function< void( uc_engine * ) >; + + class unpack_t + { + public: + explicit unpack_t( const std::vector< std::uint8_t > &bin ); + ~unpack_t( void ); + + bool init( void ); + bool unpack( std::vector< std::uint8_t > &output ); + + private: + uc_engine *uc_ctx; + std::vector< uint8_t > bin, map_bin; + std::vector< uc_hook * > uc_hooks; + + std::uintptr_t img_base, img_size; + win::image_t<> *win_img; + + static void alloc_pool_hook( uc_engine * ); + static void free_pool_hook( uc_engine * ); + static void local_alloc_hook( uc_engine * ); + static void local_free_hook( uc_engine * ); + + static bool iat_dispatcher( uc_engine *uc, uint64_t address, uint32_t size, unpack_t *unpack ); + static bool unpack_section_callback( uc_engine *uc, uint64_t address, uint32_t size, unpack_t *unpack ); + static bool code_exec_callback( uc_engine *uc, uint64_t address, uint32_t size, unpack_t *unpack ); + static void invalid_mem( uc_engine *uc, uc_mem_type type, uint64_t address, int size, int64_t value, + unpack_t *unpack ); + + std::map< std::string, std::pair< std::uint32_t, iat_hook_t > > iat_hooks = { + { "ExAllocatePool", { EX_ALLOCATE_POOL_VECTOR, &alloc_pool_hook } }, + { "ExFreePool", { EX_FREE_POOL_VECTOR, &free_pool_hook } }, + { "LocalAlloc", { LOCAL_ALLOC_VECTOR, &local_alloc_hook } }, + { "LocalFree", { LOCAL_FREE_VECTOR, &local_free_hook } } }; + }; +} // namespace engine \ No newline at end of file diff --git a/include/vmemu_t.hpp b/include/vmemu_t.hpp index 784d00e..42fc34f 100644 --- a/include/vmemu_t.hpp +++ b/include/vmemu_t.hpp @@ -1,4 +1,5 @@ #pragma once +#include #include namespace vm @@ -11,5 +12,8 @@ namespace vm bool init(); bool get_trace( std::vector< vm::instrs::code_block_t > &code_blocks ); + + private: + uc_engine *uc_ctx; }; } // namespace vm \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index d91b5e1..0e2e832 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,4 +1,4 @@ -#include +#include "unpacker.hpp" #include "vmemu_t.hpp" #include @@ -9,14 +9,9 @@ int __cdecl main( int argc, const char *argv[] ) { argparse::argument_parser_t parser( "VMEmu", "VMProtect 2 VM Handler Emulator" ); - - parser.add_argument() - .name( "--vmentry" ) - .required( true ) - .description( "relative virtual address to a vm entry..." ); - - parser.add_argument().name( "--bin" ).required( true ).description( "path to unpacked virtualized binary..." ); - parser.add_argument().name( "--out" ).required( true ).description( "output file name for trace file..." ); + parser.add_argument().name( "--vmentry" ).description( "relative virtual address to a vm entry..." ); + parser.add_argument().name( "--bin" ).description( "path to unpacked virtualized binary..." ); + parser.add_argument().required( true ).name( "--out" ).description( "output file name..." ); parser.add_argument().name( "--unpack" ).description( "unpack a vmp2 binary..." ); parser.enable_help(); @@ -35,92 +30,122 @@ int __cdecl main( int argc, const char *argv[] ) } auto umtils = xtils::um_t::get_instance(); - const auto module_base = reinterpret_cast< std::uintptr_t >( - LoadLibraryExA( parser.get< std::string >( "vmpbin" ).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 >( "vmpbin" ).c_str() ); - const auto image_size = NT_HEADER( module_base )->OptionalHeader.SizeOfImage; - - std::printf( "> image base = %p, image size = %p, module base = %p\n", image_base, image_size, module_base ); - - if ( !image_base || !image_size || !module_base ) - { - std::printf( "[!] failed to open binary on disk...\n" ); - return -1; - } - - std::vector< vm::instrs::code_block_t > code_blocks; - vm::ctx_t vmctx( module_base, image_base, image_size, vm_entry_rva ); - if ( !vmctx.init() ) + if ( !parser.exists( "unpack" ) ) { - std::printf( "[!] failed to init vmctx... this can be for many reasons..." - " try validating your vm entry rva... make sure the binary is unpacked and is" - "protected with VMProtect 2...\n" ); - return -1; + 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 >( "vmpbin" ).c_str() ); + const auto image_size = NT_HEADER( module_base )->OptionalHeader.SizeOfImage; + + std::printf( "> image base = %p, image size = %p, module base = %p\n", image_base, image_size, module_base ); + + if ( !image_base || !image_size || !module_base ) + { + std::printf( "[!] failed to open binary on disk...\n" ); + return -1; + } + + std::vector< vm::instrs::code_block_t > code_blocks; + vm::ctx_t vmctx( module_base, image_base, image_size, vm_entry_rva ); + + if ( !vmctx.init() ) + { + std::printf( "[!] failed to init vmctx... this can be for many reasons..." + " try validating your vm entry rva... make sure the binary is unpacked and is" + "protected with VMProtect 2...\n" ); + return -1; + } + + vm::emu_t emu( &vmctx ); + + if ( !emu.init() ) + { + std::printf( "[!] failed to init emulator...\n" ); + return -1; + } + + if ( !emu.get_trace( code_blocks ) ) + std::printf( "[!] something failed during tracing, review the console for more information...\n" ); + + std::printf( "> number of blocks = %d\n", code_blocks.size() ); + + for ( auto &code_block : code_blocks ) + { + std::printf( "> code block starts at = %p\n", code_block.vip_begin ); + std::printf( "> number of virtual instructions = %d\n", code_block.vinstrs.size() ); + std::printf( "> does this code block have a jcc? %s\n", code_block.jcc.has_jcc ? "yes" : "no" ); + + if ( code_block.jcc.has_jcc ) + std::printf( "> branch 1 = %p, branch 2 = %p\n", code_block.jcc.block_addr[ 0 ], + code_block.jcc.block_addr[ 1 ] ); + } + + std::printf( "> serializing results....\n" ); + vmp2::v3::file_header file_header; + file_header.magic = VMP_MAGIC; + file_header.epoch_time = std::time( nullptr ); + file_header.version = vmp2::version_t::v3; + file_header.module_base = module_base; + file_header.image_base = image_base; + file_header.vm_entry_rva = vm_entry_rva; + file_header.module_offset = sizeof file_header; + file_header.module_size = image_size; + file_header.code_block_offset = image_size + sizeof file_header; + file_header.code_block_count = code_blocks.size(); + + std::ofstream output( parser.get< std::string >( "out" ), std::ios::binary ); + output.write( reinterpret_cast< const char * >( &file_header ), sizeof file_header ); + output.write( reinterpret_cast< const char * >( module_base ), image_size ); + + for ( const auto &code_block : code_blocks ) + { + const auto _code_block_size = + ( code_block.vinstrs.size() * sizeof vm::instrs::virt_instr_t ) + sizeof vmp2::v3::code_block_t; + + vmp2::v3::code_block_t *_code_block = + reinterpret_cast< vmp2::v3::code_block_t * >( malloc( _code_block_size ) ); + + _code_block->vip_begin = code_block.vip_begin; + _code_block->jcc = code_block.jcc; + _code_block->next_block_offset = _code_block_size; + _code_block->vinstr_count = code_block.vinstrs.size(); + + for ( auto idx = 0u; idx < code_block.vinstrs.size(); ++idx ) + _code_block->vinstr[ idx ] = code_block.vinstrs[ idx ]; + + output.write( reinterpret_cast< const char * >( _code_block ), _code_block_size ); + } + + output.close(); } - - vm::emu_t emu( &vmctx ); - - if ( !emu.init() ) + else { - std::printf( "[!] failed to init emulator...\n" ); - return -1; + std::vector< std::uint8_t > packed_bin, unpacked_bin; + if ( !umtils->open_binary_file( parser.get< std::string >( "unpack" ), packed_bin ) ) + { + std::printf( "> failed to read bin off disk...\n" ); + return -1; + } + + engine::unpack_t unpacker( packed_bin ); + + if ( !unpacker.init() ) + { + std::printf( "> failed to init unpacker...\n" ); + return -1; + } + + if ( !unpacker.unpack( unpacked_bin ) ) + { + std::printf( "> failed to unpack binary... refer to log above...\n" ); + return -1; + } + + std::ofstream output( parser.get< std::string >( "output" ), std::ios::binary ); + output.write( reinterpret_cast< char * >( unpacked_bin.data() ), unpacked_bin.size() ); + output.close(); } - - if ( !emu.get_trace( code_blocks ) ) - std::printf( "[!] something failed during tracing, review the console for more information...\n" ); - - std::printf( "> number of blocks = %d\n", code_blocks.size() ); - - for ( auto &code_block : code_blocks ) - { - std::printf( "> code block starts at = %p\n", code_block.vip_begin ); - std::printf( "> number of virtual instructions = %d\n", code_block.vinstrs.size() ); - std::printf( "> does this code block have a jcc? %s\n", code_block.jcc.has_jcc ? "yes" : "no" ); - - if ( code_block.jcc.has_jcc ) - std::printf( "> branch 1 = %p, branch 2 = %p\n", code_block.jcc.block_addr[ 0 ], - code_block.jcc.block_addr[ 1 ] ); - } - - std::printf( "> serializing results....\n" ); - vmp2::v3::file_header file_header; - file_header.magic = VMP_MAGIC; - file_header.epoch_time = std::time( nullptr ); - file_header.version = vmp2::version_t::v3; - file_header.module_base = module_base; - file_header.image_base = image_base; - file_header.vm_entry_rva = vm_entry_rva; - file_header.module_offset = sizeof file_header; - file_header.module_size = image_size; - file_header.code_block_offset = image_size + sizeof file_header; - file_header.code_block_count = code_blocks.size(); - - std::ofstream output( parser.get< std::string >( "out" ), std::ios::binary ); - output.write( reinterpret_cast< const char * >( &file_header ), sizeof file_header ); - output.write( reinterpret_cast< const char * >( module_base ), image_size ); - - for ( const auto &code_block : code_blocks ) - { - const auto _code_block_size = - ( code_block.vinstrs.size() * sizeof vm::instrs::virt_instr_t ) + sizeof vmp2::v3::code_block_t; - - vmp2::v3::code_block_t *_code_block = - reinterpret_cast< vmp2::v3::code_block_t * >( malloc( _code_block_size ) ); - - _code_block->vip_begin = code_block.vip_begin; - _code_block->jcc = code_block.jcc; - _code_block->next_block_offset = _code_block_size; - _code_block->vinstr_count = code_block.vinstrs.size(); - - for ( auto idx = 0u; idx < code_block.vinstrs.size(); ++idx ) - _code_block->vinstr[ idx ] = code_block.vinstrs[ idx ]; - - output.write( reinterpret_cast< const char * >( _code_block ), _code_block_size ); - } - - output.close(); - std::printf( "> finished..." ); } \ No newline at end of file diff --git a/src/unpacker.cpp b/src/unpacker.cpp index e69de29..812a102 100644 --- a/src/unpacker.cpp +++ b/src/unpacker.cpp @@ -0,0 +1,294 @@ +#include + +namespace engine +{ + unpack_t::unpack_t( const std::vector< std::uint8_t > &packed_bin ) : bin( packed_bin ), uc_ctx( nullptr ) + { + win_img = reinterpret_cast< win::image_t<> * >( bin.data() ); + img_base = win_img->get_nt_headers()->optional_header.image_base; + img_size = win_img->get_nt_headers()->optional_header.size_image; + std::printf( "> image base = 0x%p, image size = 0x%x\n", img_base, img_size ); + } + + unpack_t::~unpack_t( void ) + { + if ( uc_ctx ) + uc_close( uc_ctx ); + + for ( auto &ptr : uc_hooks ) + if ( ptr ) + delete ptr; + } + + bool unpack_t::init( void ) + { + uc_err err; + if ( ( err = uc_open( UC_ARCH_X86, UC_MODE_64, &uc_ctx ) ) ) + { + std::printf( "> uc_open err = %d\n", err ); + return false; + } + + if ( ( err = uc_mem_map( uc_ctx, IAT_VECTOR_TABLE, PAGE_4KB, UC_PROT_ALL ) ) ) + { + std::printf( "> uc_mem_map iat vector table err = %d\n", err ); + return false; + } + + if ( ( err = uc_mem_map( uc_ctx, STACK_BASE, STACK_SIZE, UC_PROT_ALL ) ) ) + { + std::printf( "> uc_mem_map stack err, reason = %d\n", err ); + return false; + } + + if ( ( err = uc_mem_map( uc_ctx, img_base, img_size, UC_PROT_ALL ) ) ) + { + std::printf( "> map memory failed, reason = %d\n", err ); + return false; + } + + // init iat vector table full of 'ret' instructions... + auto c3_page = malloc( PAGE_4KB ); + { + memset( c3_page, 0xC3, PAGE_4KB ); + + if ( ( err = uc_mem_write( uc_ctx, IAT_VECTOR_TABLE, c3_page, PAGE_4KB ) ) ) + { + std::printf( "> failed to init iat vector table...\n" ); + free( c3_page ); + return false; + } + } + free( c3_page ); + + map_bin.resize( img_size ); + memcpy( map_bin.data(), bin.data(), // copies pe headers (includes section headers) + win_img->get_nt_headers()->optional_header.size_headers ); + + win::section_header_t *sec_begin = win_img->get_nt_headers()->get_sections(), + *sec_end = sec_begin + win_img->get_nt_headers()->file_header.num_sections; + + // map sections... + std::for_each( sec_begin, sec_end, [ & ]( const win::section_header_t &sec_header ) { + memcpy( map_bin.data() + sec_header.virtual_address, bin.data() + sec_header.ptr_raw_data, + sec_header.size_raw_data ); + + std::printf( + "> mapped section = %s, virt address = 0x%p, virt size = 0x%x, phys offset = 0x%x, phys size = 0x%x\n", + sec_header.name.to_string().data(), sec_header.virtual_address, sec_header.virtual_size, + sec_header.ptr_raw_data, sec_header.size_raw_data ); + } ); + + auto basereloc_dir = win_img->get_directory( win::directory_id::directory_entry_basereloc ); + auto reloc_dir = reinterpret_cast< win::reloc_directory_t * >( basereloc_dir->rva + map_bin.data() ); + win::reloc_block_t *reloc_block = &reloc_dir->first_block; + + // apply relocations to all sections... + while ( reloc_block->base_rva && reloc_block->size_block ) + { + std::for_each( reloc_block->begin(), reloc_block->end(), [ & ]( win::reloc_entry_t &entry ) { + switch ( entry.type ) + { + case win::reloc_type_id::rel_based_dir64: + { + auto reloc_at = + reinterpret_cast< std::uintptr_t * >( entry.offset + reloc_block->base_rva + map_bin.data() ); + + *reloc_at = img_base + ( ( *reloc_at ) - img_base ); + break; + } + default: + break; + } + } ); + + reloc_block = reloc_block->next(); + } + + // iat hook specific function... + for ( auto import_dir = reinterpret_cast< win::import_directory_t * >( + win_img->get_directory( win::directory_id::directory_entry_import )->rva + map_bin.data() ); + import_dir->rva_name; ++import_dir ) + { + for ( auto iat_thunk = reinterpret_cast< win::image_thunk_data_t<> * >( + import_dir->rva_original_first_thunk + map_bin.data() ); + iat_thunk->address; ++iat_thunk ) + { + auto iat_name = reinterpret_cast< win::image_named_import_t * >( iat_thunk->address + map_bin.data() ); + if ( iat_hooks.find( iat_name->name ) != iat_hooks.end() ) + iat_thunk->function = iat_hooks[ iat_name->name ].first + IAT_VECTOR_TABLE; + } + } + + // map the entire map buffer into unicorn-engine since we have set everything else up... + if ( ( err = uc_mem_write( uc_ctx, img_base, map_bin.data(), map_bin.size() ) ) ) + { + std::printf( "> failed to write memory... reason = %d\n", err ); + return false; + } + + // setup unicorn-engine hooks on IAT vector table, sections with 0 raw size/ptr, and an invalid memory + // handler... + + uc_hooks.push_back( new uc_hook ); + if ( ( err = uc_hook_add( uc_ctx, uc_hooks.back(), UC_HOOK_CODE, &engine::unpack_t::iat_dispatcher, this, + IAT_VECTOR_TABLE, IAT_VECTOR_TABLE + PAGE_4KB ) ) ) + { + std::printf( "> uc_hook_add error, reason = %d\n", err ); + return false; + } + + uc_hooks.push_back( new uc_hook ); + if ( ( err = uc_hook_add( uc_ctx, uc_hooks.back(), + UC_HOOK_MEM_READ_UNMAPPED | UC_HOOK_MEM_WRITE_UNMAPPED | UC_HOOK_MEM_FETCH_UNMAPPED, + &engine::unpack_t::invalid_mem, this, true, false ) ) ) + { + std::printf( "> uc_hook_add error, reason = %d\n", err ); + return false; + } + + // execution break points on all sections that are executable but have no physical size on disk... + std::for_each( sec_begin, sec_end, [ & ]( win::section_header_t &header ) { + if ( !header.ptr_raw_data && !header.size_raw_data && header.characteristics.mem_execute && + !header.is_discardable() ) + { + uc_hooks.push_back( new uc_hook ); + if ( ( err = uc_hook_add( uc_ctx, uc_hooks.back(), UC_HOOK_CODE, + &engine::unpack_t::unpack_section_callback, this, + header.virtual_address + img_base, + header.virtual_address + header.virtual_size + img_base ) ) ) + { + std::printf( "> failed to add hook... reason = %d\n", err ); + return false; + } + + std::printf( "> adding unpack watch on section = %s\n", header.name.to_string().data() ); + } + else if ( header.characteristics.mem_execute ) + { + uc_hooks.push_back( new uc_hook ); + if ( ( err = uc_hook_add( uc_ctx, uc_hooks.back(), UC_HOOK_CODE, &engine::unpack_t::code_exec_callback, + this, header.virtual_address + img_base, + header.virtual_address + header.virtual_size + img_base ) ) ) + { + std::printf( "> failed to add hook... reason = %d\n", err ); + return false; + } + + std::printf( "> added execution callback on section = %s\n", header.name.to_string().data() ); + } + } ); + + return true; + } + + bool unpack_t::unpack( std::vector< std::uint8_t > &output ) + { + uc_err err; + auto nt_headers = win_img->get_nt_headers(); + std::uintptr_t rip = nt_headers->optional_header.entry_point + img_base, rsp = STACK_BASE + STACK_SIZE; + + if ( ( err = uc_reg_write( uc_ctx, UC_X86_REG_RSP, &rsp ) ) ) + { + std::printf( "> uc_reg_write error, reason = %d\n", err ); + return false; + } + + if ( ( err = uc_reg_write( uc_ctx, UC_X86_REG_RIP, &rip ) ) ) + { + std::printf( "> uc_reg_write error, reason = %d\n", err ); + return false; + } + + std::printf( "> beginning execution at = 0x%p\n", rip ); + if ( ( err = uc_emu_start( uc_ctx, rip, 0ull, 0ull, 0ull ) ) ) + { + std::printf( "> error starting emu... reason = %d\n", err ); + return false; + } + + return true; + } + + void unpack_t::alloc_pool_hook( uc_engine *uc_ctx ) + { + } + + void unpack_t::free_pool_hook( uc_engine *uc_ctx ) + { + } + + void unpack_t::local_alloc_hook( uc_engine *uc_ctx ) + { + } + + void unpack_t::local_free_hook( uc_engine *uc_ctx ) + { + } + + bool unpack_t::iat_dispatcher( uc_engine *uc, uint64_t address, uint32_t size, unpack_t *unpack ) + { + auto vec = address - IAT_VECTOR_TABLE; + for ( auto &[ iat_name, iat_hook_data ] : unpack->iat_hooks ) + { + if ( iat_hook_data.first == vec ) + { + std::printf( "> hooking import = %s\n", iat_name.c_str() ); + iat_hook_data.second( uc ); + return true; + } + } + return false; + } + + bool unpack_t::code_exec_callback( uc_engine *uc, uint64_t address, uint32_t size, unpack_t *unpack ) + { + static ZydisDecoder decoder; + static ZydisFormatter formatter; + static ZydisDecodedInstruction instr; + + if ( static std::atomic< bool > once{ false }; !once.exchange( true ) ) + { + ZydisDecoderInit( &decoder, ZYDIS_MACHINE_MODE_LONG_64, ZYDIS_ADDRESS_WIDTH_64 ); + ZydisFormatterInit( &formatter, ZYDIS_FORMATTER_STYLE_INTEL ); + } + + auto instr_ptr = reinterpret_cast< void * >( unpack->map_bin.data() + ( address - unpack->img_base ) ); + if ( ZYAN_SUCCESS( ZydisDecoderDecodeBuffer( &decoder, instr_ptr, PAGE_4KB, &instr ) ) ) + { + char buffer[ 0x1000 ]; + ZydisFormatterFormatInstruction( &formatter, &instr, buffer, sizeof( buffer ), address ); + std::printf( "> 0x%p ", address ); + puts( buffer ); + } + + return true; + } + + bool unpack_t::unpack_section_callback( uc_engine *uc, uint64_t address, uint32_t size, unpack_t *unpack ) + { + std::printf( "> might be dump time...\n" ); + std::getchar(); + return true; + } + + void unpack_t::invalid_mem( uc_engine *uc, uc_mem_type type, uint64_t address, int size, int64_t value, + unpack_t *unpack ) + { + switch ( type ) + { + case UC_MEM_READ_UNMAPPED: + std::printf( ">>> reading invalid memory at address = 0x%p, size = 0x%x\n", address, size ); + break; + case UC_MEM_WRITE_UNMAPPED: + std::printf( ">>> writing invalid memory at address = 0x%p, size = 0x%x, val = 0x%x\n", address, size, + value ); + break; + case UC_MEM_FETCH_UNMAPPED: + std::printf( ">>> fetching invalid instructions at address = 0x%p\n", address ); + break; + default: + break; + } + } +} // namespace engine \ No newline at end of file From 0007b4024eb854842735187b9f4c2e3d30eeb81d Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Sat, 31 Jul 2021 01:31:10 -0700 Subject: [PATCH 03/12] unpacker is working. need to add reloc stuff and it should be good.. --- include/unpacker.hpp | 31 +++++--- src/main.cpp | 3 +- src/unpacker.cpp | 173 +++++++++++++++++++++++++++++++++++++------ 3 files changed, 171 insertions(+), 36 deletions(-) diff --git a/include/unpacker.hpp b/include/unpacker.hpp index 9e817a5..db0fcc2 100644 --- a/include/unpacker.hpp +++ b/include/unpacker.hpp @@ -1,9 +1,10 @@ #pragma once +#include #include #include #include -#include +#include #include #include #include @@ -11,18 +12,18 @@ #define PAGE_4KB 0x1000 #define STACK_SIZE PAGE_4KB * 512 -#define IAT_VECTOR_TABLE 0xFFFFF0000000000 +#define IAT_VECTOR_TABLE 0xFFFFF00000000000 #define STACK_BASE 0xFFFF000000000000 +#define HEAP_BASE 0xFFF0000000000000 #define EX_ALLOCATE_POOL_VECTOR 0 #define EX_FREE_POOL_VECTOR 1 #define LOCAL_ALLOC_VECTOR 2 #define LOCAL_FREE_VECTOR 3 +#define LOAD_LIBRARY_VECTOR 4 namespace engine { - using iat_hook_t = std::function< void( uc_engine * ) >; - class unpack_t { public: @@ -33,28 +34,36 @@ namespace engine bool unpack( std::vector< std::uint8_t > &output ); private: + using iat_hook_t = std::function< void( uc_engine *, unpack_t * ) >; + uc_engine *uc_ctx; std::vector< uint8_t > bin, map_bin; std::vector< uc_hook * > uc_hooks; - std::uintptr_t img_base, img_size; + std::uintptr_t img_base, img_size, heap_offset, pack_section_offset; win::image_t<> *win_img; - static void alloc_pool_hook( uc_engine * ); - static void free_pool_hook( uc_engine * ); - static void local_alloc_hook( uc_engine * ); - static void local_free_hook( uc_engine * ); + static void alloc_pool_hook( uc_engine *, unpack_t * ); + static void free_pool_hook( uc_engine *, unpack_t * ); + static void local_alloc_hook( uc_engine *, unpack_t * ); + static void local_free_hook( uc_engine *, unpack_t * ); + static void load_library_hook( uc_engine *, unpack_t * ); + static void uc_strcpy( uc_engine *, char *buff, std::uintptr_t addr ); static bool iat_dispatcher( uc_engine *uc, uint64_t address, uint32_t size, unpack_t *unpack ); - static bool unpack_section_callback( uc_engine *uc, uint64_t address, uint32_t size, unpack_t *unpack ); + static bool unpack_section_callback( uc_engine *uc, uc_mem_type type, uint64_t address, int size, int64_t value, + unpack_t *unpack ); + static bool code_exec_callback( uc_engine *uc, uint64_t address, uint32_t size, unpack_t *unpack ); static void invalid_mem( uc_engine *uc, uc_mem_type type, uint64_t address, int size, int64_t value, unpack_t *unpack ); + std::vector< std::uintptr_t > loaded_modules; std::map< std::string, std::pair< std::uint32_t, iat_hook_t > > iat_hooks = { { "ExAllocatePool", { EX_ALLOCATE_POOL_VECTOR, &alloc_pool_hook } }, { "ExFreePool", { EX_FREE_POOL_VECTOR, &free_pool_hook } }, { "LocalAlloc", { LOCAL_ALLOC_VECTOR, &local_alloc_hook } }, - { "LocalFree", { LOCAL_FREE_VECTOR, &local_free_hook } } }; + { "LocalFree", { LOCAL_FREE_VECTOR, &local_free_hook } }, + { "LoadLibraryA", { LOAD_LIBRARY_VECTOR, &load_library_hook } } }; }; } // namespace engine \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 0e2e832..a0eb184 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -144,7 +144,8 @@ int __cdecl main( int argc, const char *argv[] ) return -1; } - std::ofstream output( parser.get< std::string >( "output" ), std::ios::binary ); + std::printf( "> writing result to = %s\n", parser.get< std::string >( "out" ).c_str() ); + std::ofstream output( parser.get< std::string >( "out" ), std::ios::binary ); output.write( reinterpret_cast< char * >( unpacked_bin.data() ), unpacked_bin.size() ); output.close(); } diff --git a/src/unpacker.cpp b/src/unpacker.cpp index 812a102..5bd9b2b 100644 --- a/src/unpacker.cpp +++ b/src/unpacker.cpp @@ -2,7 +2,8 @@ namespace engine { - unpack_t::unpack_t( const std::vector< std::uint8_t > &packed_bin ) : bin( packed_bin ), uc_ctx( nullptr ) + unpack_t::unpack_t( const std::vector< std::uint8_t > &packed_bin ) + : bin( packed_bin ), uc_ctx( nullptr ), heap_offset( 0ull ), pack_section_offset( 0ull ) { win_img = reinterpret_cast< win::image_t<> * >( bin.data() ); img_base = win_img->get_nt_headers()->optional_header.image_base; @@ -68,15 +69,9 @@ namespace engine win::section_header_t *sec_begin = win_img->get_nt_headers()->get_sections(), *sec_end = sec_begin + win_img->get_nt_headers()->file_header.num_sections; - // map sections... std::for_each( sec_begin, sec_end, [ & ]( const win::section_header_t &sec_header ) { memcpy( map_bin.data() + sec_header.virtual_address, bin.data() + sec_header.ptr_raw_data, sec_header.size_raw_data ); - - std::printf( - "> mapped section = %s, virt address = 0x%p, virt size = 0x%x, phys offset = 0x%x, phys size = 0x%x\n", - sec_header.name.to_string().data(), sec_header.virtual_address, sec_header.virtual_size, - sec_header.ptr_raw_data, sec_header.size_raw_data ); } ); auto basereloc_dir = win_img->get_directory( win::directory_id::directory_entry_basereloc ); @@ -110,8 +105,8 @@ namespace engine win_img->get_directory( win::directory_id::directory_entry_import )->rva + map_bin.data() ); import_dir->rva_name; ++import_dir ) { - for ( auto iat_thunk = reinterpret_cast< win::image_thunk_data_t<> * >( - import_dir->rva_original_first_thunk + map_bin.data() ); + for ( auto iat_thunk = + reinterpret_cast< win::image_thunk_data_t<> * >( import_dir->rva_first_thunk + map_bin.data() ); iat_thunk->address; ++iat_thunk ) { auto iat_name = reinterpret_cast< win::image_named_import_t * >( iat_thunk->address + map_bin.data() ); @@ -120,6 +115,8 @@ namespace engine } } + *reinterpret_cast< std::uintptr_t * >( map_bin.data() + 0x599038 ) = LOAD_LIBRARY_VECTOR + IAT_VECTOR_TABLE; + // map the entire map buffer into unicorn-engine since we have set everything else up... if ( ( err = uc_mem_write( uc_ctx, img_base, map_bin.data(), map_bin.size() ) ) ) { @@ -140,7 +137,8 @@ namespace engine uc_hooks.push_back( new uc_hook ); if ( ( err = uc_hook_add( uc_ctx, uc_hooks.back(), - UC_HOOK_MEM_READ_UNMAPPED | UC_HOOK_MEM_WRITE_UNMAPPED | UC_HOOK_MEM_FETCH_UNMAPPED, + UC_HOOK_MEM_READ_UNMAPPED | UC_HOOK_MEM_WRITE_UNMAPPED | UC_HOOK_MEM_FETCH_UNMAPPED | + UC_HOOK_INSN_INVALID, &engine::unpack_t::invalid_mem, this, true, false ) ) ) { std::printf( "> uc_hook_add error, reason = %d\n", err ); @@ -150,10 +148,10 @@ namespace engine // execution break points on all sections that are executable but have no physical size on disk... std::for_each( sec_begin, sec_end, [ & ]( win::section_header_t &header ) { if ( !header.ptr_raw_data && !header.size_raw_data && header.characteristics.mem_execute && - !header.is_discardable() ) + header.characteristics.mem_write && !header.is_discardable() ) { uc_hooks.push_back( new uc_hook ); - if ( ( err = uc_hook_add( uc_ctx, uc_hooks.back(), UC_HOOK_CODE, + if ( ( err = uc_hook_add( uc_ctx, uc_hooks.back(), UC_HOOK_CODE | UC_HOOK_MEM_WRITE, &engine::unpack_t::unpack_section_callback, this, header.virtual_address + img_base, header.virtual_address + header.virtual_size + img_base ) ) ) @@ -162,6 +160,7 @@ namespace engine return false; } + pack_section_offset = header.virtual_address + header.virtual_size; std::printf( "> adding unpack watch on section = %s\n", header.name.to_string().data() ); } else if ( header.characteristics.mem_execute ) @@ -201,29 +200,139 @@ namespace engine } std::printf( "> beginning execution at = 0x%p\n", rip ); + if ( ( err = uc_emu_start( uc_ctx, rip, 0ull, 0ull, 0ull ) ) ) { std::printf( "> error starting emu... reason = %d\n", err ); return false; } + output.resize( img_size ); + if ( ( err = uc_mem_read( uc_ctx, img_base, output.data(), output.size() ) ) ) + { + std::printf( "> uc_mem_read failed... err = %d\n", err ); + return false; + } + + auto img = reinterpret_cast< win::image_t<> * >( output.data() ); + auto sections = img->get_nt_headers()->get_sections(); + auto section_cnt = img->get_file_header()->num_sections; + + std::for_each( sections, sections + section_cnt, [ & ]( win::section_header_t &header ) { + header.ptr_raw_data = header.virtual_address; + header.size_raw_data = header.virtual_size; + } ); return true; } - void unpack_t::alloc_pool_hook( uc_engine *uc_ctx ) + void unpack_t::alloc_pool_hook( uc_engine *uc_ctx, unpack_t *obj ) { + // TODO } - void unpack_t::free_pool_hook( uc_engine *uc_ctx ) + void unpack_t::free_pool_hook( uc_engine *uc_ctx, unpack_t *obj ) { + // TODO } - void unpack_t::local_alloc_hook( uc_engine *uc_ctx ) + void unpack_t::local_alloc_hook( uc_engine *uc_ctx, unpack_t *obj ) { + uc_err err; + std::uintptr_t rax, rdx; + + if ( ( err = uc_reg_read( uc_ctx, UC_X86_REG_RDX, &rdx ) ) ) + { + std::printf( "> failed to read RDX... reason = %d\n", rdx ); + return; + } + + auto size = ( ( rdx + PAGE_4KB ) & ~0xFFFull ); + if ( ( err = uc_mem_map( uc_ctx, HEAP_BASE + obj->heap_offset, size, UC_PROT_ALL ) ) ) + { + std::printf( "> failed to allocate memory... reason = %d\n", err ); + return; + } + + rax = HEAP_BASE + obj->heap_offset; + obj->heap_offset += size; + + if ( ( err = uc_reg_write( uc_ctx, UC_X86_REG_RAX, &rax ) ) ) + { + std::printf( "> failed to write rax... reason = %d\n", err ); + return; + } } - void unpack_t::local_free_hook( uc_engine *uc_ctx ) + void unpack_t::local_free_hook( uc_engine *uc_ctx, unpack_t *obj ) { + // TODO + } + + void unpack_t::load_library_hook( uc_engine *uc_ctx, unpack_t *obj ) + { + uc_err err; + std::uintptr_t rcx = 0ull; + + if ( ( err = uc_reg_read( uc_ctx, UC_X86_REG_RCX, &rcx ) ) ) + { + std::printf( "> uc_reg_read error, reason = %d\n", err ); + return; + } + + char buff[ 256 ]; + uc_strcpy( uc_ctx, buff, rcx ); + std::printf( "> LoadLibraryA(\"%s\")\n", buff ); + + auto module_base = reinterpret_cast< std::uintptr_t >( LoadLibraryA( buff ) ); + + auto module_size = + reinterpret_cast< win::image_t<> * >( module_base )->get_nt_headers()->optional_header.size_image; + + if ( std::find( obj->loaded_modules.begin(), obj->loaded_modules.end(), module_base ) != + obj->loaded_modules.end() ) + { + if ( ( err = uc_reg_write( uc_ctx, UC_X86_REG_RAX, &module_base ) ) ) + { + std::printf( "> failed to set rax... reason = %d\n", err ); + return; + } + } + else + { + if ( ( err = uc_mem_map( uc_ctx, module_base, module_size, UC_PROT_ALL ) ) ) + { + std::printf( "> failed to load library... reason = %d\n", err ); + return; + } + + if ( ( err = uc_mem_write( uc_ctx, module_base, reinterpret_cast< void * >( module_base ), module_size ) ) ) + { + std::printf( "> failed to copy module into emulator... reason = %d\n", err ); + return; + } + + if ( ( err = uc_reg_write( uc_ctx, UC_X86_REG_RAX, &module_base ) ) ) + { + std::printf( "> failed to set rax... reason = %d\n", err ); + return; + } + + obj->loaded_modules.push_back( module_base ); + } + } + + void unpack_t::uc_strcpy( uc_engine *uc_ctx, char *buff, std::uintptr_t addr ) + { + uc_err err; + char i = 0u; + auto idx = 0ul; + + do + { + if ( ( err = uc_mem_read( uc_ctx, addr + idx, &i, sizeof i ) ) ) + break; + + } while ( ( buff[ idx++ ] = i ) ); } bool unpack_t::iat_dispatcher( uc_engine *uc, uint64_t address, uint32_t size, unpack_t *unpack ) @@ -234,7 +343,7 @@ namespace engine if ( iat_hook_data.first == vec ) { std::printf( "> hooking import = %s\n", iat_name.c_str() ); - iat_hook_data.second( uc ); + iat_hook_data.second( uc, unpack ); return true; } } @@ -256,19 +365,33 @@ namespace engine auto instr_ptr = reinterpret_cast< void * >( unpack->map_bin.data() + ( address - unpack->img_base ) ); if ( ZYAN_SUCCESS( ZydisDecoderDecodeBuffer( &decoder, instr_ptr, PAGE_4KB, &instr ) ) ) { - char buffer[ 0x1000 ]; - ZydisFormatterFormatInstruction( &formatter, &instr, buffer, sizeof( buffer ), address ); - std::printf( "> 0x%p ", address ); - puts( buffer ); + if ( instr.mnemonic == ZYDIS_MNEMONIC_CALL && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER && + instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RAX ) + { + std::uintptr_t rax = 0u, rip = 0u; + uc_reg_read( uc, UC_X86_REG_RAX, &rax ); + uc_reg_read( uc, UC_X86_REG_RIP, &rip ); + + if ( rax > unpack->img_base + unpack->img_size ) + { + rip += instr.length; + uc_reg_write( uc, UC_X86_REG_RIP, &rip ); + } + } } return true; } - bool unpack_t::unpack_section_callback( uc_engine *uc, uint64_t address, uint32_t size, unpack_t *unpack ) + bool unpack_t::unpack_section_callback( uc_engine *uc, uc_mem_type type, uint64_t address, int size, int64_t value, + unpack_t *unpack ) { - std::printf( "> might be dump time...\n" ); - std::getchar(); + if ( address == unpack->pack_section_offset + unpack->img_base ) + { + std::printf( "> dumping...\n" ); + uc_emu_stop( uc ); + return false; + } return true; } @@ -285,8 +408,10 @@ namespace engine value ); break; case UC_MEM_FETCH_UNMAPPED: + { std::printf( ">>> fetching invalid instructions at address = 0x%p\n", address ); break; + } default: break; } From ffb3177b0422dc197c207ecc584c726b69b7b5a9 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Sat, 31 Jul 2021 01:35:41 -0700 Subject: [PATCH 04/12] removed a line, and added a comment --- src/unpacker.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/unpacker.cpp b/src/unpacker.cpp index 5bd9b2b..8624f1d 100644 --- a/src/unpacker.cpp +++ b/src/unpacker.cpp @@ -115,8 +115,6 @@ namespace engine } } - *reinterpret_cast< std::uintptr_t * >( map_bin.data() + 0x599038 ) = LOAD_LIBRARY_VECTOR + IAT_VECTOR_TABLE; - // map the entire map buffer into unicorn-engine since we have set everything else up... if ( ( err = uc_mem_write( uc_ctx, img_base, map_bin.data(), map_bin.size() ) ) ) { @@ -372,7 +370,7 @@ namespace engine uc_reg_read( uc, UC_X86_REG_RAX, &rax ); uc_reg_read( uc, UC_X86_REG_RIP, &rip ); - if ( rax > unpack->img_base + unpack->img_size ) + if ( rax > unpack->img_base + unpack->img_size ) // skip calls to kernel32.dll... { rip += instr.length; uc_reg_write( uc, UC_X86_REG_RIP, &rip ); From f4229133ad60d6eb4f8e3e96d1cc209976c80ca6 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Sun, 1 Aug 2021 02:15:40 -0700 Subject: [PATCH 05/12] added some code for packed drivers... needs more work, also relocs... --- include/unpacker.hpp | 11 ++++- src/unpacker.cpp | 104 ++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 109 insertions(+), 6 deletions(-) diff --git a/include/unpacker.hpp b/include/unpacker.hpp index db0fcc2..316a034 100644 --- a/include/unpacker.hpp +++ b/include/unpacker.hpp @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -21,6 +22,12 @@ #define LOCAL_ALLOC_VECTOR 2 #define LOCAL_FREE_VECTOR 3 #define LOAD_LIBRARY_VECTOR 4 +#define NT_QUERY_SYSTEM_INFO_VECTOR 5 + +#define MOV_RAX_0_SIG "\x48\xB8\x00\x00\x00\x00\x00\x00\x00\x00" +#define MOV_RAX_0_MASK "xxxxxxxxxx" + +static_assert( sizeof MOV_RAX_0_SIG == sizeof MOV_RAX_0_MASK, "signature and mask sizes are wrong..." ); namespace engine { @@ -48,6 +55,7 @@ namespace engine static void local_alloc_hook( uc_engine *, unpack_t * ); static void local_free_hook( uc_engine *, unpack_t * ); static void load_library_hook( uc_engine *, unpack_t * ); + static void query_system_info_hook( uc_engine *, unpack_t * ); static void uc_strcpy( uc_engine *, char *buff, std::uintptr_t addr ); static bool iat_dispatcher( uc_engine *uc, uint64_t address, uint32_t size, unpack_t *unpack ); @@ -64,6 +72,7 @@ namespace engine { "ExFreePool", { EX_FREE_POOL_VECTOR, &free_pool_hook } }, { "LocalAlloc", { LOCAL_ALLOC_VECTOR, &local_alloc_hook } }, { "LocalFree", { LOCAL_FREE_VECTOR, &local_free_hook } }, - { "LoadLibraryA", { LOAD_LIBRARY_VECTOR, &load_library_hook } } }; + { "LoadLibraryA", { LOAD_LIBRARY_VECTOR, &load_library_hook } }, + { "NtQuerySystemInformation", { NT_QUERY_SYSTEM_INFO_VECTOR, &query_system_info_hook } } }; }; } // namespace engine \ No newline at end of file diff --git a/src/unpacker.cpp b/src/unpacker.cpp index 8624f1d..d0a1054 100644 --- a/src/unpacker.cpp +++ b/src/unpacker.cpp @@ -109,7 +109,11 @@ namespace engine reinterpret_cast< win::image_thunk_data_t<> * >( import_dir->rva_first_thunk + map_bin.data() ); iat_thunk->address; ++iat_thunk ) { + if ( iat_thunk->is_ordinal ) + continue; + auto iat_name = reinterpret_cast< win::image_named_import_t * >( iat_thunk->address + map_bin.data() ); + if ( iat_hooks.find( iat_name->name ) != iat_hooks.end() ) iat_thunk->function = iat_hooks[ iat_name->name ].first + IAT_VECTOR_TABLE; } @@ -159,7 +163,6 @@ namespace engine } pack_section_offset = header.virtual_address + header.virtual_size; - std::printf( "> adding unpack watch on section = %s\n", header.name.to_string().data() ); } else if ( header.characteristics.mem_execute ) { @@ -171,8 +174,6 @@ namespace engine std::printf( "> failed to add hook... reason = %d\n", err ); return false; } - - std::printf( "> added execution callback on section = %s\n", header.name.to_string().data() ); } } ); @@ -217,6 +218,38 @@ namespace engine auto section_cnt = img->get_file_header()->num_sections; std::for_each( sections, sections + section_cnt, [ & ]( win::section_header_t &header ) { + if ( header.characteristics.mem_execute && !header.ptr_raw_data && !header.size_raw_data ) + { + auto result = output.data() + header.virtual_address; + std::vector< std::uintptr_t > reloc_rvas; + + do + { + result = reinterpret_cast< std::uint8_t * >( xtils::um_t::get_instance()->sigscan( + result, header.virtual_size, MOV_RAX_0_SIG, MOV_RAX_0_MASK ) ); + + // offset from section begin... + auto reloc_offset = ( reinterpret_cast< std::uintptr_t >( result ) + 2 ) - + reinterpret_cast< std::uintptr_t >( output.data() + header.virtual_address ); + + reloc_rvas.push_back( reloc_offset ); + } while ( result ); + + auto basereloc_dir = img->get_directory( win::directory_id::directory_entry_basereloc ); + auto reloc_dir = reinterpret_cast< win::reloc_directory_t * >( basereloc_dir->rva + output.data() ); + win::reloc_block_t *reloc_block = &reloc_dir->first_block; + + // + // assuming that the .reloc section is the last section in the entire module... + // + + while ( reloc_block->base_rva && reloc_block->size_block ) + reloc_block = reloc_block->next(); + + reloc_block->base_rva = header.virtual_address; + reloc_block->size_block = reloc_rvas.size() * sizeof win::reloc_entry_t; + } + header.ptr_raw_data = header.virtual_address; header.size_raw_data = header.virtual_size; } ); @@ -225,7 +258,30 @@ namespace engine void unpack_t::alloc_pool_hook( uc_engine *uc_ctx, unpack_t *obj ) { - // TODO + uc_err err; + std::uintptr_t rax, rdx; + + if ( ( err = uc_reg_read( uc_ctx, UC_X86_REG_RDX, &rdx ) ) ) + { + std::printf( "> failed to read RDX... reason = %d\n", rdx ); + return; + } + + auto size = ( ( rdx + PAGE_4KB ) & ~0xFFFull ); + if ( ( err = uc_mem_map( uc_ctx, HEAP_BASE + obj->heap_offset, size, UC_PROT_ALL ) ) ) + { + std::printf( "> failed to allocate memory... reason = %d\n", err ); + return; + } + + rax = HEAP_BASE + obj->heap_offset; + obj->heap_offset += size; + + if ( ( err = uc_reg_write( uc_ctx, UC_X86_REG_RAX, &rax ) ) ) + { + std::printf( "> failed to write rax... reason = %d\n", err ); + return; + } } void unpack_t::free_pool_hook( uc_engine *uc_ctx, unpack_t *obj ) @@ -263,7 +319,14 @@ namespace engine void unpack_t::local_free_hook( uc_engine *uc_ctx, unpack_t *obj ) { - // TODO + uc_err err; + std::uintptr_t rax = 0ull; + + if ( ( err = uc_reg_write( uc_ctx, UC_X86_REG_RAX, &rax ) ) ) + { + std::printf( "> failed to write rax... reason = %d\n", err ); + return; + } } void unpack_t::load_library_hook( uc_engine *uc_ctx, unpack_t *obj ) @@ -319,6 +382,37 @@ namespace engine } } + void unpack_t::query_system_info_hook( uc_engine *uc_ctx, unpack_t *obj ) + { + uc_err err; + std::uintptr_t rcx, rdx, r8, r9; + if ( ( err = uc_reg_read( uc_ctx, UC_X86_REG_RCX, &rcx ) ) ) + { + std::printf( "> failed to read reg... reason = %d\n", err ); + return; + } + + if ( ( err = uc_reg_read( uc_ctx, UC_X86_REG_RDX, &rdx ) ) ) + { + std::printf( "> failed to read reg... reason = %d\n", err ); + return; + } + + if ( ( err = uc_reg_read( uc_ctx, UC_X86_REG_R8, &r8 ) ) ) + { + std::printf( "> failed to read reg... reason = %d\n", err ); + return; + } + + if ( ( err = uc_reg_read( uc_ctx, UC_X86_REG_R9, &r9 ) ) ) + { + std::printf( "> failed to read reg... reason = %d\n", err ); + return; + } + + std::printf( "> rcx = 0x%p, rdx = 0x%p, r8 = 0x%p, r9 = 0x%p\n", rcx, rdx, r8, r9 ); + } + void unpack_t::uc_strcpy( uc_engine *uc_ctx, char *buff, std::uintptr_t addr ) { uc_err err; From ceb4f38cb7e2b70a58c5a0f1ad7424b5d3dab171 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Sun, 1 Aug 2021 23:13:35 -0700 Subject: [PATCH 06/12] added code to add relocs in unpacked sections... --- include/unpacker.hpp | 24 ++++--- src/unpacker.cpp | 158 +++++++++++++++++++++---------------------- 2 files changed, 93 insertions(+), 89 deletions(-) diff --git a/include/unpacker.hpp b/include/unpacker.hpp index 316a034..1bfa3f9 100644 --- a/include/unpacker.hpp +++ b/include/unpacker.hpp @@ -2,13 +2,27 @@ #include #include -#include #include #include #include #include #include #include +#include + +struct process_module_info_t +{ + std::uintptr_t section, mapped_base, img_base; + std::uint32_t image_size, flags; + std::uint16_t loaded_order_index, init_order_index, load_count, file_name_offset; + char file_path[ 0x100 ]; +}; + +struct process_modules_t +{ + std::uint32_t cnt; + process_module_info_t modules[ VAR_LEN ]; +}; #define PAGE_4KB 0x1000 #define STACK_SIZE PAGE_4KB * 512 @@ -50,12 +64,9 @@ namespace engine std::uintptr_t img_base, img_size, heap_offset, pack_section_offset; win::image_t<> *win_img; - static void alloc_pool_hook( uc_engine *, unpack_t * ); - static void free_pool_hook( uc_engine *, unpack_t * ); static void local_alloc_hook( uc_engine *, unpack_t * ); static void local_free_hook( uc_engine *, unpack_t * ); static void load_library_hook( uc_engine *, unpack_t * ); - static void query_system_info_hook( uc_engine *, unpack_t * ); static void uc_strcpy( uc_engine *, char *buff, std::uintptr_t addr ); static bool iat_dispatcher( uc_engine *uc, uint64_t address, uint32_t size, unpack_t *unpack ); @@ -68,11 +79,8 @@ namespace engine std::vector< std::uintptr_t > loaded_modules; std::map< std::string, std::pair< std::uint32_t, iat_hook_t > > iat_hooks = { - { "ExAllocatePool", { EX_ALLOCATE_POOL_VECTOR, &alloc_pool_hook } }, - { "ExFreePool", { EX_FREE_POOL_VECTOR, &free_pool_hook } }, { "LocalAlloc", { LOCAL_ALLOC_VECTOR, &local_alloc_hook } }, { "LocalFree", { LOCAL_FREE_VECTOR, &local_free_hook } }, - { "LoadLibraryA", { LOAD_LIBRARY_VECTOR, &load_library_hook } }, - { "NtQuerySystemInformation", { NT_QUERY_SYSTEM_INFO_VECTOR, &query_system_info_hook } } }; + { "LoadLibraryA", { LOAD_LIBRARY_VECTOR, &load_library_hook } } }; }; } // namespace engine \ No newline at end of file diff --git a/src/unpacker.cpp b/src/unpacker.cpp index d0a1054..c96785f 100644 --- a/src/unpacker.cpp +++ b/src/unpacker.cpp @@ -213,80 +213,107 @@ namespace engine return false; } - auto img = reinterpret_cast< win::image_t<> * >( output.data() ); - auto sections = img->get_nt_headers()->get_sections(); - auto section_cnt = img->get_file_header()->num_sections; + auto output_img = reinterpret_cast< win::image_t<> * >( output.data() ); + auto sections = output_img->get_nt_headers()->get_sections(); + auto section_cnt = output_img->get_file_header()->num_sections; + // { section virtual address -> vector of section offset to reloc } + std::map< std::uint32_t, std::vector< std::uint16_t > > new_relocs; + + // search executable sections for MOV RAX, 00 00 00 00 00 00 00 00... std::for_each( sections, sections + section_cnt, [ & ]( win::section_header_t &header ) { - if ( header.characteristics.mem_execute && !header.ptr_raw_data && !header.size_raw_data ) + if ( header.characteristics.mem_execute ) { auto result = output.data() + header.virtual_address; - std::vector< std::uintptr_t > reloc_rvas; do { result = reinterpret_cast< std::uint8_t * >( xtils::um_t::get_instance()->sigscan( - result, header.virtual_size, MOV_RAX_0_SIG, MOV_RAX_0_MASK ) ); - - // offset from section begin... - auto reloc_offset = ( reinterpret_cast< std::uintptr_t >( result ) + 2 ) - - reinterpret_cast< std::uintptr_t >( output.data() + header.virtual_address ); + result, + header.virtual_size - + ( reinterpret_cast< std::uintptr_t >( result ) - + ( header.virtual_address + reinterpret_cast< std::uintptr_t >( output.data() ) ) ), + MOV_RAX_0_SIG, MOV_RAX_0_MASK ) ); - reloc_rvas.push_back( reloc_offset ); - } while ( result ); + if ( result ) + { + result += 2; // advance ahead of the 0x48 0xB8... - auto basereloc_dir = img->get_directory( win::directory_id::directory_entry_basereloc ); - auto reloc_dir = reinterpret_cast< win::reloc_directory_t * >( basereloc_dir->rva + output.data() ); - win::reloc_block_t *reloc_block = &reloc_dir->first_block; + // offset from section begin... + auto reloc_offset = + ( reinterpret_cast< std::uintptr_t >( result ) ) - + reinterpret_cast< std::uintptr_t >( output.data() + header.virtual_address ); - // - // assuming that the .reloc section is the last section in the entire module... - // + new_relocs[ ( header.virtual_address + reloc_offset ) & ~0xFFFull ].push_back( reloc_offset ); + } - while ( reloc_block->base_rva && reloc_block->size_block ) - reloc_block = reloc_block->next(); - - reloc_block->base_rva = header.virtual_address; - reloc_block->size_block = reloc_rvas.size() * sizeof win::reloc_entry_t; + } while ( result ); } header.ptr_raw_data = header.virtual_address; header.size_raw_data = header.virtual_size; } ); - return true; - } - void unpack_t::alloc_pool_hook( uc_engine *uc_ctx, unpack_t *obj ) - { - uc_err err; - std::uintptr_t rax, rdx; + // determines if a relocation block exists for a given page... + static const auto has_reloc_page = [ & ]( std::uint32_t page ) -> bool { + auto img = reinterpret_cast< win::image_t<> * >( output.data() ); + auto sections = img->get_nt_headers()->get_sections(); + auto section_cnt = img->get_file_header()->num_sections; - if ( ( err = uc_reg_read( uc_ctx, UC_X86_REG_RDX, &rdx ) ) ) - { - std::printf( "> failed to read RDX... reason = %d\n", rdx ); - return; - } + auto basereloc_dir = img->get_directory( win::directory_id::directory_entry_basereloc ); + auto reloc_dir = reinterpret_cast< win::reloc_directory_t * >( basereloc_dir->rva + output.data() ); + win::reloc_block_t *reloc_block = &reloc_dir->first_block; - auto size = ( ( rdx + PAGE_4KB ) & ~0xFFFull ); - if ( ( err = uc_mem_map( uc_ctx, HEAP_BASE + obj->heap_offset, size, UC_PROT_ALL ) ) ) - { - std::printf( "> failed to allocate memory... reason = %d\n", err ); - return; - } + while ( reloc_block->base_rva && reloc_block->size_block ) + { + if ( reloc_block->base_rva == page ) + return true; - rax = HEAP_BASE + obj->heap_offset; - obj->heap_offset += size; + reloc_block = reloc_block->next(); + } - if ( ( err = uc_reg_write( uc_ctx, UC_X86_REG_RAX, &rax ) ) ) + return false; + }; + + // calc size to add new reloc info... + std::size_t resize_cnt = 0ull; + for ( const auto &[ reloc_rva, relocs ] : new_relocs ) + if ( !has_reloc_page( reloc_rva ) ) + resize_cnt += sizeof( win::reloc_block_t ) + ( relocs.size() * sizeof( win::reloc_entry_t ) ); + + // last block needs to contain 0 for block_rva and size_block... + if ( resize_cnt ) + resize_cnt += sizeof win::reloc_block_t; + + output.resize( output.size() + resize_cnt ); + output_img = reinterpret_cast< win::image_t<> * >( output.data() ); + + auto basereloc_dir = output_img->get_directory( win::directory_id::directory_entry_basereloc ); + auto reloc_dir = reinterpret_cast< win::reloc_directory_t * >( basereloc_dir->rva + output.data() ); + + basereloc_dir->size += resize_cnt; + for ( const auto &[ reloc_rva, relocs ] : new_relocs ) { - std::printf( "> failed to write rax... reason = %d\n", err ); - return; - } - } + if ( has_reloc_page( reloc_rva ) ) + continue; - void unpack_t::free_pool_hook( uc_engine *uc_ctx, unpack_t *obj ) - { - // TODO + win::reloc_block_t *reloc_block = &reloc_dir->first_block; + while ( reloc_block->base_rva && reloc_block->size_block ) + reloc_block = reloc_block->next(); + + reloc_block->base_rva = reloc_rva; + reloc_block->size_block = relocs.size() * sizeof( win::reloc_entry_t ) + sizeof uint64_t; + + reloc_block->next()->base_rva = 0ull; + reloc_block->next()->size_block = 0ull; + + for ( auto idx = 0u; idx < relocs.size(); ++idx ) + { + reloc_block->entries[ idx ].type = win::reloc_type_id::rel_based_dir64; + reloc_block->entries[ idx ].offset = relocs[ idx ]; + } + } + return true; } void unpack_t::local_alloc_hook( uc_engine *uc_ctx, unpack_t *obj ) @@ -382,37 +409,6 @@ namespace engine } } - void unpack_t::query_system_info_hook( uc_engine *uc_ctx, unpack_t *obj ) - { - uc_err err; - std::uintptr_t rcx, rdx, r8, r9; - if ( ( err = uc_reg_read( uc_ctx, UC_X86_REG_RCX, &rcx ) ) ) - { - std::printf( "> failed to read reg... reason = %d\n", err ); - return; - } - - if ( ( err = uc_reg_read( uc_ctx, UC_X86_REG_RDX, &rdx ) ) ) - { - std::printf( "> failed to read reg... reason = %d\n", err ); - return; - } - - if ( ( err = uc_reg_read( uc_ctx, UC_X86_REG_R8, &r8 ) ) ) - { - std::printf( "> failed to read reg... reason = %d\n", err ); - return; - } - - if ( ( err = uc_reg_read( uc_ctx, UC_X86_REG_R9, &r9 ) ) ) - { - std::printf( "> failed to read reg... reason = %d\n", err ); - return; - } - - std::printf( "> rcx = 0x%p, rdx = 0x%p, r8 = 0x%p, r9 = 0x%p\n", rcx, rdx, r8, r9 ); - } - void unpack_t::uc_strcpy( uc_engine *uc_ctx, char *buff, std::uintptr_t addr ) { uc_err err; From 4bc35659f1b770cbe3c86a6d19816ce6f054b84b Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Sun, 1 Aug 2021 23:48:59 -0700 Subject: [PATCH 07/12] removed useless typedefs... --- include/unpacker.hpp | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/include/unpacker.hpp b/include/unpacker.hpp index 1bfa3f9..eeb06e2 100644 --- a/include/unpacker.hpp +++ b/include/unpacker.hpp @@ -10,20 +10,6 @@ #include #include -struct process_module_info_t -{ - std::uintptr_t section, mapped_base, img_base; - std::uint32_t image_size, flags; - std::uint16_t loaded_order_index, init_order_index, load_count, file_name_offset; - char file_path[ 0x100 ]; -}; - -struct process_modules_t -{ - std::uint32_t cnt; - process_module_info_t modules[ VAR_LEN ]; -}; - #define PAGE_4KB 0x1000 #define STACK_SIZE PAGE_4KB * 512 From fd3e44fb9db73055d6d180ed4a5d135f4fe6cb0a Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Mon, 2 Aug 2021 00:40:17 -0700 Subject: [PATCH 08/12] preparing for vmemu re-write --- include/vmemu_t.hpp | 1 + src/main.cpp | 4 ++-- src/vmemu_t.cpp | 4 +++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/include/vmemu_t.hpp b/include/vmemu_t.hpp index 42fc34f..7b4ddd4 100644 --- a/include/vmemu_t.hpp +++ b/include/vmemu_t.hpp @@ -15,5 +15,6 @@ namespace vm private: uc_engine *uc_ctx; + vm::ctx_t *vm_ctx; }; } // namespace vm \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index a0eb184..53e2079 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -31,13 +31,13 @@ int __cdecl main( int argc, const char *argv[] ) auto umtils = xtils::um_t::get_instance(); - if ( !parser.exists( "unpack" ) ) + if ( !parser.exists( "unpack" ) && parser.exists( "vmentry" ) && parser.exists( "bin" ) ) { 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 >( "vmpbin" ).c_str() ); + const auto image_base = umtils->image_base( parser.get< std::string >( "bin" ).c_str() ); const auto image_size = NT_HEADER( module_base )->OptionalHeader.SizeOfImage; std::printf( "> image base = %p, image size = %p, module base = %p\n", image_base, image_size, module_base ); diff --git a/src/vmemu_t.cpp b/src/vmemu_t.cpp index b6570f1..59399d1 100644 --- a/src/vmemu_t.cpp +++ b/src/vmemu_t.cpp @@ -2,12 +2,14 @@ namespace vm { - emu_t::emu_t( vm::ctx_t *vmctx ) + emu_t::emu_t( vm::ctx_t *vm_ctx ) : vm_ctx( vm_ctx ), uc_ctx( nullptr ) { } emu_t::~emu_t() { + if ( uc_ctx ) + uc_close( uc_ctx ); } bool emu_t::init() From e9945bde6cc95c32e7ffb0d4db01009c282efbd6 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Tue, 3 Aug 2021 16:39:51 -0700 Subject: [PATCH 09/12] working on adding multi-vm branching support... --- include/vmemu_t.hpp | 34 +++- src/main.cpp | 6 + src/vmemu_t.cpp | 481 +++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 516 insertions(+), 5 deletions(-) diff --git a/include/vmemu_t.hpp b/include/vmemu_t.hpp index 7b4ddd4..943ab1a 100644 --- a/include/vmemu_t.hpp +++ b/include/vmemu_t.hpp @@ -1,20 +1,50 @@ #pragma once +#include #include #include +#define PAGE_4KB 0x1000 +#define STACK_SIZE PAGE_4KB * 512 +#define STACK_BASE 0xFFFF000000000000 + namespace vm { class emu_t { + struct cpu_ctx_t + { + std::uintptr_t rip; + uc_context *context; + std::uint8_t stack[ STACK_SIZE ]; + }; + + struct code_block_data_t + { + vm::instrs::code_block_t code_block; + std::shared_ptr< cpu_ctx_t > cpu_ctx; + std::shared_ptr< vm::ctx_t > g_vm_ctx; + }; + public: - explicit emu_t( vm::ctx_t *vm_ctx ); + explicit emu_t( vm::ctx_t *g_vm_ctx ); ~emu_t(); bool init(); bool get_trace( std::vector< vm::instrs::code_block_t > &code_blocks ); private: + std::uintptr_t img_base, img_size; + uc_hook code_exec_hook, invalid_mem_hook; + uc_engine *uc_ctx; - vm::ctx_t *vm_ctx; + vm::ctx_t *g_vm_ctx; + code_block_data_t *cc_block; + + std::vector< std::uintptr_t > vip_begins; + std::vector< code_block_data_t > code_blocks; + uc_err create_entry( vmp2::v2::entry_t *entry ); + static bool code_exec_callback( uc_engine *uc, uint64_t address, uint32_t size, emu_t *obj ); + static void invalid_mem( uc_engine *uc, uc_mem_type type, uint64_t address, int size, int64_t value, + emu_t *obj ); }; } // namespace vm \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 53e2079..ef45150 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -36,6 +36,12 @@ int __cdecl main( int argc, const char *argv[] ) const auto module_base = reinterpret_cast< std::uintptr_t >( LoadLibraryExA( parser.get< std::string >( "bin" ).c_str(), NULL, DONT_RESOLVE_DLL_REFERENCES ) ); + if ( !module_base ) + { + std::printf( "[!] failed to open binary file...\n" ); + return -1; + } + 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; diff --git a/src/vmemu_t.cpp b/src/vmemu_t.cpp index 59399d1..b19a4d9 100644 --- a/src/vmemu_t.cpp +++ b/src/vmemu_t.cpp @@ -2,7 +2,8 @@ namespace vm { - emu_t::emu_t( vm::ctx_t *vm_ctx ) : vm_ctx( vm_ctx ), uc_ctx( nullptr ) + emu_t::emu_t( vm::ctx_t *g_vm_ctx ) + : g_vm_ctx( g_vm_ctx ), uc_ctx( nullptr ), img_base( g_vm_ctx->image_base ), img_size( g_vm_ctx->image_size ) { } @@ -14,11 +15,485 @@ namespace vm bool emu_t::init() { - return {}; + uc_err err; + if ( ( err = uc_open( UC_ARCH_X86, UC_MODE_64, &uc_ctx ) ) ) + { + std::printf( "> uc_open err = %d\n", err ); + return false; + } + + if ( ( err = uc_mem_map( uc_ctx, STACK_BASE, STACK_SIZE, UC_PROT_ALL ) ) ) + { + std::printf( "> uc_mem_map stack err, reason = %d\n", err ); + return false; + } + + if ( ( err = uc_mem_map( uc_ctx, img_base, img_size, UC_PROT_ALL ) ) ) + { + std::printf( "> map memory failed, reason = %d\n", err ); + return false; + } + + if ( ( err = uc_mem_write( uc_ctx, img_base, reinterpret_cast< void * >( g_vm_ctx->module_base ), img_size ) ) ) + { + std::printf( "> failed to write memory... reason = %d\n", err ); + return false; + } + + if ( ( err = uc_hook_add( uc_ctx, &code_exec_hook, UC_HOOK_CODE, &vm::emu_t::code_exec_callback, this, img_base, + img_base + img_size ) ) ) + { + std::printf( "> uc_hook_add error, reason = %d\n", err ); + return false; + } + + if ( ( err = uc_hook_add( uc_ctx, &invalid_mem_hook, + UC_HOOK_MEM_READ_UNMAPPED | UC_HOOK_MEM_WRITE_UNMAPPED | UC_HOOK_MEM_FETCH_UNMAPPED | + UC_HOOK_INSN_INVALID, + &vm::emu_t::invalid_mem, this, true, false ) ) ) + { + std::printf( "> uc_hook_add error, reason = %d\n", err ); + return false; + } + return true; } bool emu_t::get_trace( std::vector< vm::instrs::code_block_t > &entries ) { - return {}; + uc_err err; + std::uintptr_t rip = g_vm_ctx->vm_entry_rva + img_base, rsp = STACK_BASE + STACK_SIZE - PAGE_4KB; + + if ( ( err = uc_reg_write( uc_ctx, UC_X86_REG_RSP, &rsp ) ) ) + { + std::printf( "> uc_reg_write error, reason = %d\n", err ); + return false; + } + + if ( ( err = uc_reg_write( uc_ctx, UC_X86_REG_RIP, &rip ) ) ) + { + std::printf( "> uc_reg_write error, reason = %d\n", err ); + return false; + } + + // trace the first block given the vm enter... + code_block_data_t code_block{ { rip }, nullptr, nullptr }; + cc_block = &code_block; + + std::printf( "> beginning execution at = 0x%p\n", rip ); + if ( ( err = uc_emu_start( uc_ctx, rip, 0ull, 0ull, 0ull ) ) ) + { + std::printf( "> error starting emu... reason = %d\n", err ); + return false; + } + + code_blocks.push_back( code_block ); + + // code_blocks.size() will continue to grow as all branches are traced... + // when idx is > code_blocks.size() then we have traced all branches... + for ( auto idx = 0u; idx < code_blocks.size(); ++idx ) + { + const auto &code_block = code_blocks[ idx ]; + if ( !code_block.code_block.jcc.has_jcc ) + continue; + + switch ( code_block.code_block.jcc.type ) + { + case vm::instrs::jcc_type::branching: + { + if ( std::find( vip_begins.begin(), vip_begins.end(), code_block.code_block.jcc.block_addr[ 1 ] ) != + vip_begins.end() ) + continue; + + std::uintptr_t rbp = 0ull; + std::uint32_t branch_rva = code_block.code_block.jcc.block_addr[ 1 ]; + + // setup object globals so that the tracing will work... + code_block_data_t branch_block{ { code_block.cpu_ctx->rip }, nullptr, nullptr }; + cc_block = &branch_block; + g_vm_ctx = code_block.g_vm_ctx.get(); + + // restore register values... + if ( ( err = uc_context_restore( uc_ctx, code_block.cpu_ctx->context ) ) ) + { + std::printf( "> failed to restore emu context... reason = %d\n", err ); + return false; + } + + // restore stack values... + if ( ( err = uc_mem_write( uc_ctx, STACK_BASE, code_block.cpu_ctx->stack, STACK_SIZE ) ) ) + { + std::printf( "> failed to restore stack... reason = %d\n", err ); + return false; + } + + // get the address in rbp (top of vsp)... then patch the branch rva... + if ( ( err = uc_reg_read( uc_ctx, UC_X86_REG_RBP, &rbp ) ) ) + { + std::printf( "> failed to read rbp... reason = %d\n", err ); + return false; + } + + // patch the branch rva... + if ( ( err = uc_mem_write( uc_ctx, rbp, &branch_rva, sizeof branch_rva ) ) ) + { + std::printf( "> failed to patch branch rva... reason = %d\n", err ); + return false; + } + + std::printf( "> beginning execution at = 0x%p\n", code_block.cpu_ctx->rip ); + if ( ( err = uc_emu_start( uc_ctx, code_block.cpu_ctx->rip, 0ull, 0ull, 0ull ) ) ) + { + std::printf( "> error starting emu... reason = %d\n", err ); + return false; + } + + // push back new block that has been traced... + code_blocks.push_back( branch_block ); + + // drop down and execute the absolute case as well since that + // will trace the first branch... + } + case vm::instrs::jcc_type::absolute: + { + if ( std::find( vip_begins.begin(), vip_begins.end(), code_block.code_block.jcc.block_addr[ 0 ] ) != + vip_begins.end() ) + continue; + + std::uintptr_t rbp = 0ull; + std::uint32_t branch_rva = code_block.code_block.jcc.block_addr[ 0 ]; + + // setup object globals so that the tracing will work... + code_block_data_t branch_block{ { code_block.cpu_ctx->rip }, nullptr, nullptr }; + cc_block = &branch_block; + g_vm_ctx = code_block.g_vm_ctx.get(); + + // restore register values... + if ( ( err = uc_context_restore( uc_ctx, code_block.cpu_ctx->context ) ) ) + { + std::printf( "> failed to restore emu context... reason = %d\n", err ); + return false; + } + + // restore stack values... + if ( ( err = uc_mem_write( uc_ctx, STACK_BASE, code_block.cpu_ctx->stack, STACK_SIZE ) ) ) + { + std::printf( "> failed to restore stack... reason = %d\n", err ); + return false; + } + + // get the address in rbp (top of vsp)... then patch the branch rva... + if ( ( err = uc_reg_read( uc_ctx, UC_X86_REG_RBP, &rbp ) ) ) + { + std::printf( "> failed to read rbp... reason = %d\n", err ); + return false; + } + + // patch the branch rva... + if ( ( err = uc_mem_write( uc_ctx, rbp, &branch_rva, sizeof branch_rva ) ) ) + { + std::printf( "> failed to patch branch rva... reason = %d\n", err ); + return false; + } + + std::printf( "> beginning execution at = 0x%p\n", code_block.cpu_ctx->rip ); + if ( ( err = uc_emu_start( uc_ctx, code_block.cpu_ctx->rip, 0ull, 0ull, 0ull ) ) ) + { + std::printf( "> error starting emu... reason = %d\n", err ); + return false; + } + + // push back new block that has been traced... + code_blocks.push_back( branch_block ); + break; + } + } + } + + for ( const auto &[ code_block, cpu_ctx, vm_ctx ] : code_blocks ) + entries.push_back( code_block ); + + return true; + } + + uc_err emu_t::create_entry( vmp2::v2::entry_t *entry ) + { + uc_reg_read( uc_ctx, UC_X86_REG_R15, &entry->regs.r15 ); + uc_reg_read( uc_ctx, UC_X86_REG_R14, &entry->regs.r14 ); + uc_reg_read( uc_ctx, UC_X86_REG_R13, &entry->regs.r13 ); + uc_reg_read( uc_ctx, UC_X86_REG_R12, &entry->regs.r12 ); + uc_reg_read( uc_ctx, UC_X86_REG_R11, &entry->regs.r11 ); + uc_reg_read( uc_ctx, UC_X86_REG_R10, &entry->regs.r10 ); + uc_reg_read( uc_ctx, UC_X86_REG_R9, &entry->regs.r9 ); + uc_reg_read( uc_ctx, UC_X86_REG_R8, &entry->regs.r8 ); + uc_reg_read( uc_ctx, UC_X86_REG_RBP, &entry->regs.rbp ); + uc_reg_read( uc_ctx, UC_X86_REG_RDI, &entry->regs.rdi ); + uc_reg_read( uc_ctx, UC_X86_REG_RSI, &entry->regs.rsi ); + uc_reg_read( uc_ctx, UC_X86_REG_RDX, &entry->regs.rdx ); + uc_reg_read( uc_ctx, UC_X86_REG_RCX, &entry->regs.rcx ); + uc_reg_read( uc_ctx, UC_X86_REG_RBX, &entry->regs.rbx ); + uc_reg_read( uc_ctx, UC_X86_REG_RAX, &entry->regs.rax ); + uc_reg_read( uc_ctx, UC_X86_REG_EFLAGS, &entry->regs.rflags ); + + entry->vip = entry->regs.rsi; + entry->handler_idx = entry->regs.rax; + entry->decrypt_key = entry->regs.rbx; + + uc_err err; + if ( ( err = uc_mem_read( uc_ctx, entry->regs.rdi, entry->vregs.raw, sizeof entry->vregs.raw ) ) ) + return err; + + // copy virtual stack values... + for ( auto idx = 0u; idx < sizeof( entry->vsp ) / 8; ++idx ) + if ( ( err = uc_mem_read( uc_ctx, entry->regs.rbp + ( idx * 8 ), &entry->vsp.qword[ idx ], + sizeof entry->vsp.qword[ idx ] ) ) ) + return err; + + return UC_ERR_OK; + } + + bool emu_t::code_exec_callback( uc_engine *uc, uint64_t address, uint32_t size, emu_t *obj ) + { + uc_err err; + vmp2::v2::entry_t vinstr_entry; + std::uint8_t vm_handler_table_idx = 0u; + std::uintptr_t vm_handler_addr; + + static ZydisDecoder decoder; + static ZydisFormatter formatter; + static ZydisDecodedInstruction instr; + + if ( static std::atomic< bool > once{ false }; !once.exchange( true ) ) + { + ZydisDecoderInit( &decoder, ZYDIS_MACHINE_MODE_LONG_64, ZYDIS_ADDRESS_WIDTH_64 ); + ZydisFormatterInit( &formatter, ZYDIS_FORMATTER_STYLE_INTEL ); + } + + auto instr_ptr = reinterpret_cast< void * >( obj->g_vm_ctx->module_base + ( address - obj->img_base ) ); + if ( !ZYAN_SUCCESS( ZydisDecoderDecodeBuffer( &decoder, instr_ptr, PAGE_4KB, &instr ) ) ) + { + std::printf( "> failed to decode instruction at = 0x%p\n", address ); + if ( ( err = uc_emu_stop( uc ) ) ) + { + std::printf( "> failed to stop emulation, exiting... reason = %d\n", err ); + exit( 0 ); + } + return false; + } + + // if the native instruction is a jmp rcx/rdx... then AL will contain the vm handler + // table index of the vm handler that the emulator is about to jmp too... + if ( !( instr.mnemonic == ZYDIS_MNEMONIC_JMP && instr.operands[ 0 ].type == ZYDIS_OPERAND_TYPE_REGISTER && + ( instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RCX || + instr.operands[ 0 ].reg.value == ZYDIS_REGISTER_RDX ) ) ) + return true; + + // extract address of vm handler table... + switch ( instr.operands[ 0 ].reg.value ) + { + case ZYDIS_REGISTER_RCX: + if ( ( err = uc_reg_read( uc, UC_X86_REG_RCX, &vm_handler_addr ) ) ) + { + std::printf( "> failed to read rcx... reason = %d\n", err ); + if ( ( err = uc_emu_stop( uc ) ) ) + { + std::printf( "> failed to stop emulation, exiting... reason = %d\n", err ); + exit( 0 ); + } + return false; + } + break; + case ZYDIS_REGISTER_RDX: + if ( ( err = uc_reg_read( uc, UC_X86_REG_RDX, &vm_handler_addr ) ) ) + { + std::printf( "> failed to read rdx... reason = %d\n", err ); + if ( ( err = uc_emu_stop( uc ) ) ) + { + std::printf( "> failed to stop emulation, exiting... reason = %d\n", err ); + exit( 0 ); + } + return false; + } + break; + } + + if ( ( err = uc_reg_read( obj->uc_ctx, UC_X86_REG_AL, &vm_handler_table_idx ) ) ) + { + std::printf( "> failed to read register... reason = %d\n", err ); + if ( ( err = uc_emu_stop( uc ) ) ) + { + std::printf( "> failed to stop emulation, exiting... reason = %d\n", err ); + exit( 0 ); + } + return false; + } + + const auto &vm_handler = obj->g_vm_ctx->vm_handlers[ vm_handler_table_idx ]; + + // quick check to ensure sanity... things can get crazy so this is good to check... + if ( vm_handler.address != vm_handler_addr ) + { + std::printf( "> vm handler index (%d) does not match vm handler address (%p)...\n", vm_handler_table_idx, + vm_handler_addr ); + if ( ( err = uc_emu_stop( uc ) ) ) + { + std::printf( "> failed to stop emulation, exiting... reason = %d\n", err ); + exit( 0 ); + } + return false; + } + + if ( ( err = obj->create_entry( &vinstr_entry ) ) ) + { + std::printf( "> failed to create vinstr entry... reason = %d\n", err ); + if ( ( err = uc_emu_stop( uc ) ) ) + { + std::printf( "> failed to stop emulation, exiting... reason = %d\n", err ); + exit( 0 ); + } + return false; + } + + auto vinstr = vm::instrs::get( *obj->g_vm_ctx, vinstr_entry ); + + if ( !vinstr.has_value() ) + { + std::printf( "> failed to decode virtual instruction...\n" ); + if ( ( err = uc_emu_stop( uc ) ) ) + { + std::printf( "> failed to stop emulation, exiting... reason = %d\n", err ); + exit( 0 ); + } + return false; + } + + // log this virtual blocks vip_begin... + if ( obj->cc_block->code_block.vinstrs.empty() ) + { + obj->cc_block->code_block.vip_begin = + obj->g_vm_ctx->exec_type == vmp2::exec_type_t::forward ? vinstr_entry.vip - 1 : vinstr_entry.vip + 1; + + obj->vip_begins.push_back( obj->cc_block->code_block.vip_begin ); + } + + obj->cc_block->code_block.vinstrs.push_back( vinstr.value() ); + std::printf( "> %s %p\n", vm_handler.profile ? vm_handler.profile->name : "UNK", vm_handler_addr ); + + if ( vm_handler.profile ) + { + switch ( vm_handler.profile->mnemonic ) + { + case vm::handler::VMEXIT: + { + obj->cc_block->code_block.jcc.has_jcc = false; + obj->cc_block->code_block.jcc.type = vm::instrs::jcc_type::none; + + if ( ( err = uc_emu_stop( uc ) ) ) + { + std::printf( "> failed to stop emulation, exiting... reason = %d\n", err ); + exit( 0 ); + } + break; + } + case vm::handler::JMP: + { + // get jcc data about the virtual instruction code block that was just emulated... + auto jcc_data = vm::instrs::get_jcc_data( *obj->g_vm_ctx, obj->cc_block->code_block ); + obj->cc_block->code_block.jcc = jcc_data.value(); + + // allocate space for the cpu context and stack... + auto new_cpu_ctx = std::make_shared< vm::emu_t::cpu_ctx_t >(); + auto new_vm_ctx = std::make_shared< vm::ctx_t >( obj->g_vm_ctx->module_base, obj->img_base, + obj->img_size, vm_handler_addr - obj->img_base ); + if ( !new_vm_ctx->init() ) + { + std::printf( "> failed to init vm::ctx_t for virtual jmp... vip = 0x%p, jmp handler = 0x%p\n", + vinstr_entry.vip, vm_handler_addr ); + + if ( ( err = uc_emu_stop( uc ) ) ) + { + std::printf( "> failed to stop emulation, exiting... reason = %d\n", err ); + exit( 0 ); + } + return false; + } + + if ( ( err = uc_context_alloc( uc, &new_cpu_ctx->context ) ) ) + { + std::printf( "> failed to allocate a unicorn context... reason = %d\n", err ); + if ( ( err = uc_emu_stop( uc ) ) ) + { + std::printf( "> failed to stop emulation, exiting... reason = %d\n", err ); + exit( 0 ); + } + return false; + } + + // save the cpu's registers... + new_cpu_ctx->rip = vm_handler_addr; + if ( ( err = uc_context_save( uc, new_cpu_ctx->context ) ) ) + { + std::printf( "> failed to save emulator context... reason = %d\n", err ); + if ( ( err = uc_emu_stop( uc ) ) ) + { + std::printf( "> failed to stop emulation, exiting... reason = %d\n", err ); + exit( 0 ); + } + return false; + } + + // save the entire stack... + if ( ( err = uc_mem_read( uc, STACK_BASE, new_cpu_ctx->stack, STACK_SIZE ) ) ) + { + std::printf( "> failed to read stack... reason = %d\n", err ); + if ( ( err = uc_emu_stop( uc ) ) ) + { + std::printf( "> failed to stop emulation, exiting... reason = %d\n", err ); + exit( 0 ); + } + return false; + } + + if ( ( err = uc_emu_stop( uc ) ) ) + { + std::printf( "> failed to stop emulation, exiting... reason = %d\n", err ); + exit( 0 ); + } + + obj->cc_block->cpu_ctx = new_cpu_ctx; + obj->cc_block->g_vm_ctx = new_vm_ctx; + break; + } + default: + break; + } + } + return true; + } + + void emu_t::invalid_mem( uc_engine *uc, uc_mem_type type, uint64_t address, int size, int64_t value, emu_t *obj ) + { + switch ( type ) + { + case UC_MEM_READ_UNMAPPED: + { + uc_mem_map( uc, address & ~0xFFFull, PAGE_4KB, UC_PROT_ALL ); + std::printf( ">>> reading invalid memory at address = 0x%p, size = 0x%x\n", address, size ); + break; + } + case UC_MEM_WRITE_UNMAPPED: + { + uc_mem_map( uc, address & ~0xFFFull, PAGE_4KB, UC_PROT_ALL ); + std::printf( ">>> writing invalid memory at address = 0x%p, size = 0x%x, val = 0x%x\n", address, size, + value ); + break; + } + case UC_MEM_FETCH_UNMAPPED: + { + std::printf( ">>> fetching invalid instructions at address = 0x%p\n", address ); + break; + } + default: + break; + } } } // namespace vm \ No newline at end of file From 3f8fea77cf67371315b34033a8c6b87bed3a81a6 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Tue, 3 Aug 2021 20:08:08 -0700 Subject: [PATCH 10/12] finished vmemu recode, added --locateconst --- include/vmemu_t.hpp | 2 ++ src/main.cpp | 78 +++++++++++++++++++++++++++++++++++++++++++-- src/vmemu_t.cpp | 68 ++++++++++++++++++++++----------------- 3 files changed, 116 insertions(+), 32 deletions(-) diff --git a/include/vmemu_t.hpp b/include/vmemu_t.hpp index 943ab1a..ebbd940 100644 --- a/include/vmemu_t.hpp +++ b/include/vmemu_t.hpp @@ -42,6 +42,8 @@ namespace vm std::vector< std::uintptr_t > vip_begins; std::vector< code_block_data_t > code_blocks; + std::map< std::uintptr_t, std::shared_ptr< vm::ctx_t > > vm_ctxs; + uc_err create_entry( vmp2::v2::entry_t *entry ); static bool code_exec_callback( uc_engine *uc, uint64_t address, uint32_t size, emu_t *obj ); static void invalid_mem( uc_engine *uc, uc_mem_type type, uint64_t address, int size, int64_t value, diff --git a/src/main.cpp b/src/main.cpp index ef45150..79d1fad 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -11,8 +11,11 @@ int __cdecl main( int argc, const char *argv[] ) argparse::argument_parser_t parser( "VMEmu", "VMProtect 2 VM Handler Emulator" ); parser.add_argument().name( "--vmentry" ).description( "relative virtual address to a vm entry..." ); parser.add_argument().name( "--bin" ).description( "path to unpacked virtualized binary..." ); - parser.add_argument().required( true ).name( "--out" ).description( "output file name..." ); + parser.add_argument().name( "--out" ).description( "output file name..." ); parser.add_argument().name( "--unpack" ).description( "unpack a vmp2 binary..." ); + parser.add_argument() + .name( "--locateconst" ) + .description( "scan all vm enters for a specific constant value...\n" ); parser.enable_help(); auto result = parser.parse( argc, argv ); @@ -31,7 +34,7 @@ int __cdecl main( int argc, const char *argv[] ) auto umtils = xtils::um_t::get_instance(); - if ( !parser.exists( "unpack" ) && parser.exists( "vmentry" ) && parser.exists( "bin" ) ) + if ( !parser.exists( "unpack" ) && parser.exists( "vmentry" ) && parser.exists( "bin" ) && parser.exists( "out" ) ) { const auto module_base = reinterpret_cast< std::uintptr_t >( LoadLibraryExA( parser.get< std::string >( "bin" ).c_str(), NULL, DONT_RESOLVE_DLL_REFERENCES ) ); @@ -127,7 +130,7 @@ int __cdecl main( int argc, const char *argv[] ) output.close(); } - else + else if ( parser.exists( "unpack" ) && parser.exists( "bin" ) && parser.exists( "out" ) ) { std::vector< std::uint8_t > packed_bin, unpacked_bin; if ( !umtils->open_binary_file( parser.get< std::string >( "unpack" ), packed_bin ) ) @@ -155,4 +158,73 @@ int __cdecl main( int argc, const char *argv[] ) output.write( reinterpret_cast< char * >( unpacked_bin.data() ), unpacked_bin.size() ); output.close(); } + else if ( parser.exists( "bin" ) && parser.exists( "locateconst" ) ) + { + std::vector< vm::instrs::code_block_t > code_blocks; + const auto module_base = reinterpret_cast< std::uintptr_t >( + LoadLibraryExA( parser.get< std::string >( "bin" ).c_str(), NULL, DONT_RESOLVE_DLL_REFERENCES ) ); + + const auto const_val = std::strtoull( parser.get< std::string >( "locateconst" ).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; + + auto vm_handler_tables = vm::locate::all_handler_tables( module_base ); + auto vm_enters = vm::locate::all_vm_enters( module_base, vm_handler_tables ); + + std::printf( "> number of vm enters = %d\n", vm_enters.size() ); + if ( std::find_if( vm_enters.begin() + 1, vm_enters.end(), + [ & ]( const std::pair< std::uint32_t, std::uint32_t > &vm_enter_data ) -> bool { + return vm_enter_data.second == vm_enters[ 0 ].second; + } ) != vm_enters.end() ) + { + std::printf( "> optimizations can be done.\n" ); + std::getchar(); + } + + for ( const auto &[ vm_enter_offset, encrypted_rva ] : vm_enters ) + { + std::printf( "> emulating vm enter at rva = 0x%x\n", vm_enter_offset ); + vm::ctx_t vm_ctx( module_base, image_base, image_size, vm_enter_offset ); + + if ( !vm_ctx.init() ) + { + std::printf( "[!] failed to init vmctx... this can be for many reasons..." + " try validating your vm entry rva... make sure the binary is unpacked and is" + "protected with VMProtect 2...\n" ); + return -1; + } + + vm::emu_t emu( &vm_ctx ); + + if ( !emu.init() ) + { + std::printf( "[!] failed to init emulator...\n" ); + return -1; + } + + std::vector< vm::instrs::code_block_t > new_code_blocks; + + if ( !emu.get_trace( new_code_blocks ) ) + { + std::printf( "[!] something failed during tracing, review the console for more information...\n" ); + return -1; + } + + std::printf( "> number of blocks = %d\n", new_code_blocks.size() ); + + for ( auto &code_block : new_code_blocks ) + { + for ( const auto &vinstr : code_block.vinstrs ) + { + if ( vinstr.operand.has_imm && vinstr.operand.imm.u == const_val ) + { + std::printf( "> found constant in vm enter at = 0x%x\n", vm_enter_offset ); + std::getchar(); + } + } + } + + code_blocks.insert( code_blocks.end(), new_code_blocks.begin(), new_code_blocks.end() ); + } + } } \ No newline at end of file diff --git a/src/vmemu_t.cpp b/src/vmemu_t.cpp index b19a4d9..9ed484d 100644 --- a/src/vmemu_t.cpp +++ b/src/vmemu_t.cpp @@ -92,35 +92,35 @@ namespace vm // when idx is > code_blocks.size() then we have traced all branches... for ( auto idx = 0u; idx < code_blocks.size(); ++idx ) { - const auto &code_block = code_blocks[ idx ]; - if ( !code_block.code_block.jcc.has_jcc ) + const auto _code_block = code_blocks[ idx ]; + if ( !_code_block.code_block.jcc.has_jcc ) continue; - switch ( code_block.code_block.jcc.type ) + switch ( _code_block.code_block.jcc.type ) { case vm::instrs::jcc_type::branching: { - if ( std::find( vip_begins.begin(), vip_begins.end(), code_block.code_block.jcc.block_addr[ 1 ] ) != + if ( std::find( vip_begins.begin(), vip_begins.end(), _code_block.code_block.jcc.block_addr[ 1 ] ) != vip_begins.end() ) continue; std::uintptr_t rbp = 0ull; - std::uint32_t branch_rva = code_block.code_block.jcc.block_addr[ 1 ]; + std::uint32_t branch_rva = _code_block.code_block.jcc.block_addr[ 1 ]; // setup object globals so that the tracing will work... - code_block_data_t branch_block{ { code_block.cpu_ctx->rip }, nullptr, nullptr }; + code_block_data_t branch_block{ { _code_block.cpu_ctx->rip }, nullptr, nullptr }; cc_block = &branch_block; - g_vm_ctx = code_block.g_vm_ctx.get(); + g_vm_ctx = _code_block.g_vm_ctx.get(); // restore register values... - if ( ( err = uc_context_restore( uc_ctx, code_block.cpu_ctx->context ) ) ) + if ( ( err = uc_context_restore( uc_ctx, _code_block.cpu_ctx->context ) ) ) { std::printf( "> failed to restore emu context... reason = %d\n", err ); return false; } // restore stack values... - if ( ( err = uc_mem_write( uc_ctx, STACK_BASE, code_block.cpu_ctx->stack, STACK_SIZE ) ) ) + if ( ( err = uc_mem_write( uc_ctx, STACK_BASE, _code_block.cpu_ctx->stack, STACK_SIZE ) ) ) { std::printf( "> failed to restore stack... reason = %d\n", err ); return false; @@ -140,8 +140,8 @@ namespace vm return false; } - std::printf( "> beginning execution at = 0x%p\n", code_block.cpu_ctx->rip ); - if ( ( err = uc_emu_start( uc_ctx, code_block.cpu_ctx->rip, 0ull, 0ull, 0ull ) ) ) + std::printf( "> beginning execution at = 0x%p\n", _code_block.cpu_ctx->rip ); + if ( ( err = uc_emu_start( uc_ctx, _code_block.cpu_ctx->rip, 0ull, 0ull, 0ull ) ) ) { std::printf( "> error starting emu... reason = %d\n", err ); return false; @@ -155,27 +155,27 @@ namespace vm } case vm::instrs::jcc_type::absolute: { - if ( std::find( vip_begins.begin(), vip_begins.end(), code_block.code_block.jcc.block_addr[ 0 ] ) != + if ( std::find( vip_begins.begin(), vip_begins.end(), _code_block.code_block.jcc.block_addr[ 0 ] ) != vip_begins.end() ) continue; std::uintptr_t rbp = 0ull; - std::uint32_t branch_rva = code_block.code_block.jcc.block_addr[ 0 ]; + std::uint32_t branch_rva = _code_block.code_block.jcc.block_addr[ 0 ]; // setup object globals so that the tracing will work... - code_block_data_t branch_block{ { code_block.cpu_ctx->rip }, nullptr, nullptr }; + code_block_data_t branch_block{ { _code_block.cpu_ctx->rip }, nullptr, nullptr }; cc_block = &branch_block; - g_vm_ctx = code_block.g_vm_ctx.get(); + g_vm_ctx = _code_block.g_vm_ctx.get(); // restore register values... - if ( ( err = uc_context_restore( uc_ctx, code_block.cpu_ctx->context ) ) ) + if ( ( err = uc_context_restore( uc_ctx, _code_block.cpu_ctx->context ) ) ) { std::printf( "> failed to restore emu context... reason = %d\n", err ); return false; } // restore stack values... - if ( ( err = uc_mem_write( uc_ctx, STACK_BASE, code_block.cpu_ctx->stack, STACK_SIZE ) ) ) + if ( ( err = uc_mem_write( uc_ctx, STACK_BASE, _code_block.cpu_ctx->stack, STACK_SIZE ) ) ) { std::printf( "> failed to restore stack... reason = %d\n", err ); return false; @@ -195,8 +195,8 @@ namespace vm return false; } - std::printf( "> beginning execution at = 0x%p\n", code_block.cpu_ctx->rip ); - if ( ( err = uc_emu_start( uc_ctx, code_block.cpu_ctx->rip, 0ull, 0ull, 0ull ) ) ) + std::printf( "> beginning execution at = 0x%p\n", _code_block.cpu_ctx->rip ); + if ( ( err = uc_emu_start( uc_ctx, _code_block.cpu_ctx->rip, 0ull, 0ull, 0ull ) ) ) { std::printf( "> error starting emu... reason = %d\n", err ); return false; @@ -258,6 +258,9 @@ namespace vm std::uint8_t vm_handler_table_idx = 0u; std::uintptr_t vm_handler_addr; + static std::shared_ptr< vm::ctx_t > _jmp_ctx; + static zydis_routine_t _jmp_stream; + static ZydisDecoder decoder; static ZydisFormatter formatter; static ZydisDecodedInstruction instr; @@ -402,21 +405,28 @@ namespace vm // allocate space for the cpu context and stack... auto new_cpu_ctx = std::make_shared< vm::emu_t::cpu_ctx_t >(); - auto new_vm_ctx = std::make_shared< vm::ctx_t >( obj->g_vm_ctx->module_base, obj->img_base, - obj->img_size, vm_handler_addr - obj->img_base ); - if ( !new_vm_ctx->init() ) + + // optimize so that we dont need to create a new vm::ctx_t every single virtual JMP... + if ( obj->vm_ctxs.find( vm_handler_addr ) == obj->vm_ctxs.end() ) { - std::printf( "> failed to init vm::ctx_t for virtual jmp... vip = 0x%p, jmp handler = 0x%p\n", - vinstr_entry.vip, vm_handler_addr ); + obj->vm_ctxs[ vm_handler_addr ] = std::make_shared< vm::ctx_t >( + obj->g_vm_ctx->module_base, obj->img_base, obj->img_size, vm_handler_addr - obj->img_base ); - if ( ( err = uc_emu_stop( uc ) ) ) + if ( !obj->vm_ctxs[ vm_handler_addr ]->init() ) { - std::printf( "> failed to stop emulation, exiting... reason = %d\n", err ); - exit( 0 ); + std::printf( "> failed to init vm::ctx_t for virtual jmp... vip = 0x%p, jmp handler = 0x%p\n", + vinstr_entry.vip, vm_handler_addr ); + + if ( ( err = uc_emu_stop( uc ) ) ) + { + std::printf( "> failed to stop emulation, exiting... reason = %d\n", err ); + exit( 0 ); + } + return false; } - return false; } + _jmp_ctx = obj->vm_ctxs[ vm_handler_addr ]; if ( ( err = uc_context_alloc( uc, &new_cpu_ctx->context ) ) ) { std::printf( "> failed to allocate a unicorn context... reason = %d\n", err ); @@ -460,7 +470,7 @@ namespace vm } obj->cc_block->cpu_ctx = new_cpu_ctx; - obj->cc_block->g_vm_ctx = new_vm_ctx; + obj->cc_block->g_vm_ctx = _jmp_ctx; break; } default: From abc22a3ca1d822575b1786f2fe3fe0c800a46544 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Tue, 3 Aug 2021 23:19:34 -0700 Subject: [PATCH 11/12] vmemu recode is done, just need to make vmemu-lib and submodule it.. --- include/vmemu_t.hpp | 7 +++++-- src/main.cpp | 5 ++++- src/vmemu_t.cpp | 46 ++++++++++++++++++++++++++------------------- 3 files changed, 36 insertions(+), 22 deletions(-) diff --git a/include/vmemu_t.hpp b/include/vmemu_t.hpp index ebbd940..8f98089 100644 --- a/include/vmemu_t.hpp +++ b/include/vmemu_t.hpp @@ -1,11 +1,14 @@ #pragma once -#include #include + +#include #include #define PAGE_4KB 0x1000 #define STACK_SIZE PAGE_4KB * 512 + #define STACK_BASE 0xFFFF000000000000 +#define IAT_VECTOR_TABLE 0xFFFFF00000000000 namespace vm { @@ -26,7 +29,7 @@ namespace vm }; public: - explicit emu_t( vm::ctx_t *g_vm_ctx ); + explicit emu_t( vm::ctx_t *vm_ctx ); ~emu_t(); bool init(); diff --git a/src/main.cpp b/src/main.cpp index 79d1fad..48abd32 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -77,7 +77,10 @@ int __cdecl main( int argc, const char *argv[] ) } if ( !emu.get_trace( code_blocks ) ) + { std::printf( "[!] something failed during tracing, review the console for more information...\n" ); + return -1; + } std::printf( "> number of blocks = %d\n", code_blocks.size() ); @@ -207,7 +210,7 @@ int __cdecl main( int argc, const char *argv[] ) if ( !emu.get_trace( new_code_blocks ) ) { std::printf( "[!] something failed during tracing, review the console for more information...\n" ); - return -1; + continue; } std::printf( "> number of blocks = %d\n", new_code_blocks.size() ); diff --git a/src/vmemu_t.cpp b/src/vmemu_t.cpp index 9ed484d..fc6deb1 100644 --- a/src/vmemu_t.cpp +++ b/src/vmemu_t.cpp @@ -2,8 +2,8 @@ namespace vm { - emu_t::emu_t( vm::ctx_t *g_vm_ctx ) - : g_vm_ctx( g_vm_ctx ), uc_ctx( nullptr ), img_base( g_vm_ctx->image_base ), img_size( g_vm_ctx->image_size ) + emu_t::emu_t( vm::ctx_t *vm_ctx ) + : g_vm_ctx( vm_ctx ), uc_ctx( nullptr ), img_base( vm_ctx->image_base ), img_size( vm_ctx->image_size ) { } @@ -28,20 +28,21 @@ namespace vm return false; } - if ( ( err = uc_mem_map( uc_ctx, img_base, img_size, UC_PROT_ALL ) ) ) + if ( ( err = uc_mem_map( uc_ctx, g_vm_ctx->module_base, img_size, UC_PROT_ALL ) ) ) { std::printf( "> map memory failed, reason = %d\n", err ); return false; } - if ( ( err = uc_mem_write( uc_ctx, img_base, reinterpret_cast< void * >( g_vm_ctx->module_base ), img_size ) ) ) + if ( ( err = uc_mem_write( uc_ctx, g_vm_ctx->module_base, reinterpret_cast< void * >( g_vm_ctx->module_base ), + img_size ) ) ) { std::printf( "> failed to write memory... reason = %d\n", err ); return false; } - if ( ( err = uc_hook_add( uc_ctx, &code_exec_hook, UC_HOOK_CODE, &vm::emu_t::code_exec_callback, this, img_base, - img_base + img_size ) ) ) + if ( ( err = uc_hook_add( uc_ctx, &code_exec_hook, UC_HOOK_CODE, &vm::emu_t::code_exec_callback, this, + g_vm_ctx->module_base, g_vm_ctx->module_base + img_size ) ) ) { std::printf( "> uc_hook_add error, reason = %d\n", err ); return false; @@ -61,7 +62,7 @@ namespace vm bool emu_t::get_trace( std::vector< vm::instrs::code_block_t > &entries ) { uc_err err; - std::uintptr_t rip = g_vm_ctx->vm_entry_rva + img_base, rsp = STACK_BASE + STACK_SIZE - PAGE_4KB; + std::uintptr_t rip = g_vm_ctx->vm_entry_rva + g_vm_ctx->module_base, rsp = STACK_BASE + STACK_SIZE - PAGE_4KB; if ( ( err = uc_reg_write( uc_ctx, UC_X86_REG_RSP, &rsp ) ) ) { @@ -105,7 +106,8 @@ namespace vm continue; std::uintptr_t rbp = 0ull; - std::uint32_t branch_rva = _code_block.code_block.jcc.block_addr[ 1 ]; + std::uint32_t branch_rva = + ( _code_block.code_block.jcc.block_addr[ 1 ] - g_vm_ctx->module_base ) + g_vm_ctx->image_base; // setup object globals so that the tracing will work... code_block_data_t branch_block{ { _code_block.cpu_ctx->rip }, nullptr, nullptr }; @@ -160,7 +162,8 @@ namespace vm continue; std::uintptr_t rbp = 0ull; - std::uint32_t branch_rva = _code_block.code_block.jcc.block_addr[ 0 ]; + std::uint32_t branch_rva = + ( _code_block.code_block.jcc.block_addr[ 1 ] - g_vm_ctx->module_base ) + g_vm_ctx->image_base; // setup object globals so that the tracing will work... code_block_data_t branch_block{ { _code_block.cpu_ctx->rip }, nullptr, nullptr }; @@ -271,8 +274,8 @@ namespace vm ZydisFormatterInit( &formatter, ZYDIS_FORMATTER_STYLE_INTEL ); } - auto instr_ptr = reinterpret_cast< void * >( obj->g_vm_ctx->module_base + ( address - obj->img_base ) ); - if ( !ZYAN_SUCCESS( ZydisDecoderDecodeBuffer( &decoder, instr_ptr, PAGE_4KB, &instr ) ) ) + if ( !ZYAN_SUCCESS( + ZydisDecoderDecodeBuffer( &decoder, reinterpret_cast< void * >( address ), PAGE_4KB, &instr ) ) ) { std::printf( "> failed to decode instruction at = 0x%p\n", address ); if ( ( err = uc_emu_stop( uc ) ) ) @@ -332,11 +335,9 @@ namespace vm const auto &vm_handler = obj->g_vm_ctx->vm_handlers[ vm_handler_table_idx ]; - // quick check to ensure sanity... things can get crazy so this is good to check... - if ( vm_handler.address != vm_handler_addr ) + if ( ( err = obj->create_entry( &vinstr_entry ) ) ) { - std::printf( "> vm handler index (%d) does not match vm handler address (%p)...\n", vm_handler_table_idx, - vm_handler_addr ); + std::printf( "> failed to create vinstr entry... reason = %d\n", err ); if ( ( err = uc_emu_stop( uc ) ) ) { std::printf( "> failed to stop emulation, exiting... reason = %d\n", err ); @@ -345,14 +346,20 @@ namespace vm return false; } - if ( ( err = obj->create_entry( &vinstr_entry ) ) ) + // quick check to ensure sanity... things can get crazy so this is good to check... + if ( vm_handler.address != vm_handler_addr || + vinstr_entry.vip >= obj->g_vm_ctx->module_base + obj->g_vm_ctx->image_size || + vinstr_entry.vip < obj->g_vm_ctx->module_base ) { - std::printf( "> failed to create vinstr entry... reason = %d\n", err ); + std::printf( "> vm handler index (%d) does not match vm handler address (%p)...\n", vm_handler_table_idx, + vm_handler_addr ); + if ( ( err = uc_emu_stop( uc ) ) ) { std::printf( "> failed to stop emulation, exiting... reason = %d\n", err ); exit( 0 ); } + return false; } @@ -409,8 +416,9 @@ namespace vm // optimize so that we dont need to create a new vm::ctx_t every single virtual JMP... if ( obj->vm_ctxs.find( vm_handler_addr ) == obj->vm_ctxs.end() ) { - obj->vm_ctxs[ vm_handler_addr ] = std::make_shared< vm::ctx_t >( - obj->g_vm_ctx->module_base, obj->img_base, obj->img_size, vm_handler_addr - obj->img_base ); + obj->vm_ctxs[ vm_handler_addr ] = + std::make_shared< vm::ctx_t >( obj->g_vm_ctx->module_base, obj->img_base, obj->img_size, + vm_handler_addr - obj->g_vm_ctx->module_base ); if ( !obj->vm_ctxs[ vm_handler_addr ]->init() ) { From 7dd708d2f0ea9747ba2bf8d50bdc46cc8d374973 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Tue, 3 Aug 2021 23:28:34 -0700 Subject: [PATCH 12/12] updated readme --- README.md | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index abbfc5d..6ef034b 100644 --- a/README.md +++ b/README.md @@ -8,33 +8,28 @@ VMEmu uses unicorn to emulate x86_64 instructions which make up the virtual machine handlers. This project is extremely simple in that it will check every executed instruction in order to find any `JMP` instruction which uses a register and jumps to a vm handler. When this JMP is executed all native registers, virtual scratch registers, and the virtual stack are saved into a trace entry. Emulation ends when a VMEXIT instruction is found. This project supports multi-code path virtual instruction code and will discover all code paths. You can continue the analysis using IDA outside of the virtual machine and then use VMEmu again once execution enters back into the virtual machine. -# Restrictions - -* dumped modules are not supported at the moment as a "dump" can mean many things - * I.E: does the dump have a pe header? are the sections of the dump mapped back to file offset manner? - * does the dump file have relocations fixed? -* Only x86_64 PE files are supported, support for ELF can be added later, no support for x86 will be added. - -# Usage - Creating A Trace - -In order to use VMEmu you must have an unpacked VMProtect 2 binary which you know some basic information about. - ``` -Usage: vmemu [options...] +Usage: VMEmu [options...] Options: - --vmentry relative virtual address to a vm entry... (Required) - --vmpbin path to unpacked virtualized binary... (Required) - --out output file name for trace file... (Required) + --vmentry relative virtual address to a vm entry... + --bin path to unpacked virtualized binary... + --out output file name... + --unpack unpack a vmp2, usermode, binary... + --locateconst scan all vm enters for a specific constant value... -h, --help Shows this page ``` # Building Instructions -First download the repo using `git clone --recursive https://githacks.org/vmp2/vmemu.git`. Then navigate to ***dependencies*** --> ***unicorn*** --> ***msvc***. Open ***unicorn.sln***, select ***Release*** and ***x64*** on the top of Visual Studios, then click ***Build*** --> ***Build Solution***. +Download and generate visual studios project. Ensure you have Visual Studios 2019 installed! -Now that unicorn has been built, you can open ***vmemu.sln**. Select ***Release MT*** and ***x64***, then click ***Build*** --> ***Build Solution***. Now copy ***unicorn.dll*** from ***dependencies/unicorn/msvc/x64/Release/unicorn.dll*** into ***x64/Release/***. You should now be able to open a command prompt inside of ***x64/Release/***, type `vmemu.exe -h`, if the help message is displayed then everything has worked. +``` +git clone --recursive https://githacks.org/vmp2/vmemu.git +cd vmemu +cmake -B build +``` -The reason for building unicorn outside of the vmemu solution is that unicorn has build scripts which create folders. These build scripts fail when they are in the wrong working directory. +Go into `build` and open `vmemu.sln`. Select "Release", and "x64", then build the project. # VMProtect 2 - Virtual Machine Architecture Overview @@ -188,4 +183,9 @@ sub bl, al mov rdx, [rbp+0] add rbp, 8 mov [rax+rdi], rdx -``` \ No newline at end of file +``` + +# Links + +https://back.engineering/17/05/2021/ +https://back.engineering/21/06/2021/ \ No newline at end of file