From 8841661c3b7dc488ddab6e9039d7713bce896a32 Mon Sep 17 00:00:00 2001 From: _xeroxz Date: Fri, 6 Aug 2021 00:30:06 -0700 Subject: [PATCH] added cli parser to deps... added vmp2 file parsing... --- .gitmodules | 3 ++ CMakeLists.txt | 1 + cmake.toml | 1 + dependencies/CMakeLists.txt | 18 +++++++++++ dependencies/cli-parser | 1 + dependencies/cmake.toml | 6 +++- src/main.cpp | 62 +++++++++++++++++++++++++++++++++++-- 7 files changed, 89 insertions(+), 3 deletions(-) create mode 160000 dependencies/cli-parser diff --git a/.gitmodules b/.gitmodules index 5dee4f3..138c549 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,6 @@ [submodule "dependencies/vmprofiler"] path = dependencies/vmprofiler url = https://githacks.org/vmp2/vmprofiler.git +[submodule "dependencies/cli-parser"] + path = dependencies/cli-parser + url = https://githacks.org/_xeroxz/cli-parser.git diff --git a/CMakeLists.txt b/CMakeLists.txt index 31f16ad..4855cec 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -72,6 +72,7 @@ target_include_directories(vmdevirt PRIVATE ) target_link_libraries(vmdevirt PRIVATE + cli-parser vmprofiler LLVMCore LLVMCodeGen diff --git a/cmake.toml b/cmake.toml index d1e3021..1be73bc 100644 --- a/cmake.toml +++ b/cmake.toml @@ -15,6 +15,7 @@ include-directories = [ "build/dependencies/llvm/llvm/include/", ] link-libraries = [ + "cli-parser", "vmprofiler", "LLVMCore", "LLVMCodeGen", diff --git a/dependencies/CMakeLists.txt b/dependencies/CMakeLists.txt index fd10308..a883033 100644 --- a/dependencies/CMakeLists.txt +++ b/dependencies/CMakeLists.txt @@ -26,3 +26,21 @@ endif() add_subdirectory(vmprofiler) 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/cli-parser b/dependencies/cli-parser new file mode 160000 index 0000000..1aedaf8 --- /dev/null +++ b/dependencies/cli-parser @@ -0,0 +1 @@ +Subproject commit 1aedaf8bb7f383f54b7cd498767611535526da85 diff --git a/dependencies/cmake.toml b/dependencies/cmake.toml index 117df27..2fa4154 100644 --- a/dependencies/cmake.toml +++ b/dependencies/cmake.toml @@ -1,2 +1,6 @@ [subdir."llvm/llvm"] -[subdir.vmprofiler] \ No newline at end of file +[subdir.vmprofiler] + +[target.cli-parser] +type = "interface" +include-directories = ["cli-parser"] \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index ef51045..56f637b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,4 +1,7 @@ #include +#include +#include +#include #include "llvm/IR/BasicBlock.h" #include "llvm/IR/Constants.h" @@ -16,9 +19,64 @@ using namespace llvm; -int main( int argc, char **argv ) +int main( int argc, const char *argv[] ) { - // test for now... + argparse::argument_parser_t parser( "vmdevirt", "virtual instruction pseudo code generator" ); + parser.add_argument().name( "--vmp2file" ).required( true ).description( "path to .vmp2 file..." ); + + parser.enable_help(); + auto err = parser.parse( argc, argv ); + + if ( err ) + { + std::cout << err << std::endl; + return -1; + } + + if ( parser.exists( "help" ) ) + { + parser.print_help(); + return 0; + } + + std::vector< std::uint8_t > vmp2file; + const auto umtils = xtils::um_t::get_instance(); + + if ( !umtils->open_binary_file( parser.get< std::string >( "vmp2file" ), vmp2file ) ) + { + std::printf( "[!] failed to open vmp2 file...\n" ); + return -1; + } + + const auto file_header = reinterpret_cast< vmp2::v3::file_header * >( vmp2file.data() ); + + if ( file_header->version != vmp2::version_t::v3 ) + { + std::printf( "[!] invalid vmp2 file version... this build uses v3...\n" ); + return -1; + } + + auto first_block = reinterpret_cast< vmp2::v3::code_block_t * >( reinterpret_cast< std::uintptr_t >( file_header ) + + file_header->code_block_offset ); + + for ( auto [ code_block, code_block_num ] = std::tuple{ first_block, 0u }; + code_block_num < file_header->code_block_count; + code_block = reinterpret_cast< vmp2::v3::code_block_t * >( reinterpret_cast< std::uintptr_t >( code_block ) + + code_block->next_block_offset ), + ++code_block_num ) + { + + std::printf( "[code block #%d] begin = 0x%p, virtual instruction count = %d\n", code_block_num, + ABS_TO_IMG( code_block->vip_begin, file_header->module_base, file_header->image_base ), + code_block->vinstr_count ); + + if ( code_block->jcc.has_jcc ) + std::printf( + "\tcode block branches to 0x%p and 0x%p\n", + ABS_TO_IMG( code_block->jcc.block_addr[ 0 ], file_header->module_base, file_header->image_base ), + ABS_TO_IMG( code_block->jcc.block_addr[ 1 ], file_header->module_base, file_header->image_base ) ); + } + LLVMContext llvm_ctx; Module llvm_module( "VMProtect 2 Static Devirtualizer", llvm_ctx ); IRBuilder<> ir_builder( llvm_ctx );