diff --git a/.gitmodules b/.gitmodules index cf7c4bb..c3c1dd8 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,9 @@ [submodule "dependencies/cli-parser"] path = dependencies/cli-parser url = https://githacks.org/_xeroxz/cli-parser.git +[submodule "dependencies/xtils"] + path = dependencies/xtils + url = https://githacks.org/_xeroxz/xtils.git +[submodule "dependencies/vmprofiler"] + path = dependencies/vmprofiler + url = https://githacks.org/gavz/vmprofiler.git diff --git a/dependencies/vmprofiler b/dependencies/vmprofiler new file mode 160000 index 0000000..a05293a --- /dev/null +++ b/dependencies/vmprofiler @@ -0,0 +1 @@ +Subproject commit a05293ab21c93c024792a8064a8344241b947f81 diff --git a/dependencies/xtils b/dependencies/xtils new file mode 160000 index 0000000..09d0342 --- /dev/null +++ b/dependencies/xtils @@ -0,0 +1 @@ +Subproject commit 09d0342da61c74b08a95ee284a8b25c742ca89c1 diff --git a/vmemu.sln b/vmemu.sln index 7cbfe9f..2b83d53 100644 --- a/vmemu.sln +++ b/vmemu.sln @@ -5,6 +5,8 @@ VisualStudioVersion = 16.0.30907.101 MinimumVisualStudioVersion = 10.0.40219.1 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vmemu", "vmemu\vmemu.vcxproj", "{B94A9F63-113F-4F80-A962-2E949A0D4826}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vmprofiler", "dependencies\vmprofiler\src\vmprofiler.vcxproj", "{D0B6092A-9944-4F24-9486-4B7DAE372619}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Release|x64 = Release|x64 @@ -12,6 +14,8 @@ Global GlobalSection(ProjectConfigurationPlatforms) = postSolution {B94A9F63-113F-4F80-A962-2E949A0D4826}.Release|x64.ActiveCfg = Release|x64 {B94A9F63-113F-4F80-A962-2E949A0D4826}.Release|x64.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 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/vmemu/main.cpp b/vmemu/main.cpp index 9130335..6ffadda 100644 --- a/vmemu/main.cpp +++ b/vmemu/main.cpp @@ -1,6 +1,7 @@ #include #include #include +#include "vmemu_t.hpp" int __cdecl main(int argc, const char* argv[]) { @@ -19,6 +20,7 @@ int __cdecl main(int argc, const char* argv[]) .name("--imagebase").required("true") .description("image base from optional PE header..."); + parser.enable_help(); auto result = parser.parse(argc, argv); if (result) @@ -28,4 +30,22 @@ int __cdecl main(int argc, const char* argv[]) return -1; } + + if (parser.exists("help")) + { + parser.print_help(); + return 0; + } + + const auto vm_entry_rva = std::strtoull( + parser.get("vmentry").c_str(), nullptr, 16); + + const auto image_base = std::strtoull( + parser.get("imagebase").c_str(), nullptr, 16); + + const auto module_base = reinterpret_cast( + LoadLibraryExA(parser.get("vmpbin").c_str(), + NULL, DONT_RESOLVE_DLL_REFERENCES)); + + vm::emu_t emu(vm_entry_rva, image_base, module_base); } diff --git a/vmemu/vmemu.vcxproj b/vmemu/vmemu.vcxproj index 763bd65..a31514e 100644 --- a/vmemu/vmemu.vcxproj +++ b/vmemu/vmemu.vcxproj @@ -33,7 +33,7 @@ false - $(Project)..\dependencies\cli-parser;$(Project)..\dependencies\unicorn\include;$(IncludePath) + $(Project)..\dependencies\cli-parser;$(Project)..\dependencies\unicorn\include;$(Project)..\dependencies\xtils;$(IncludePath) @@ -55,6 +55,7 @@ + @@ -69,6 +70,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {d0b6092a-9944-4f24-9486-4b7dae372619} + diff --git a/vmemu/vmemu.vcxproj.filters b/vmemu/vmemu.vcxproj.filters index 3214239..d0b0389 100644 --- a/vmemu/vmemu.vcxproj.filters +++ b/vmemu/vmemu.vcxproj.filters @@ -15,11 +15,32 @@ {a871bdc5-3faf-4d03-9f95-45d59e394562} + + {9fb4cc4f-eb2f-49e3-b680-56e43aa3c1e5} + + + {2a9e2ea7-67f2-408b-b125-f1dac9a81696} + + + {ea6cc84d-2152-46e5-81ea-195dfa58bf37} + + + {ab91c846-5e2a-4b0f-b119-28b56f5136e9} + + + {b2469cba-4a7f-4f5c-b60d-17cd07278695} + + + {c4e9ba60-a20a-4a30-9c6b-a188c298c957} + Source Files + + Source Files + @@ -58,5 +79,161 @@ Header Files + + Header Files + + + Header Files + + + Header Files\vmprofiler + + + Header Files\vmprofiler + + + Header Files\vmprofiler + + + Header Files\vmprofiler + + + Header Files\vmprofiler + + + Header Files\vmprofiler + + + Header Files\vmprofiler + + + Header Files\vmprofiler + + + Header Files\vmprofiler\Zydis + + + Header Files\vmprofiler\Zydis + + + Header Files\vmprofiler\Zydis + + + Header Files\vmprofiler\Zydis + + + Header Files\vmprofiler\Zydis + + + Header Files\vmprofiler\Zydis + + + Header Files\vmprofiler\Zydis + + + Header Files\vmprofiler\Zydis + + + Header Files\vmprofiler\Zydis + + + Header Files\vmprofiler\Zydis + + + Header Files\vmprofiler\Zydis + + + Header Files\vmprofiler\Zydis + + + Header Files\vmprofiler\Zydis\Internal + + + Header Files\vmprofiler\Zydis\Internal + + + Header Files\vmprofiler\Zydis\Internal + + + Header Files\vmprofiler\Zydis\Internal + + + Header Files\vmprofiler\Zydis\Internal + + + Header Files\vmprofiler\Zydis\Internal + + + Header Files\vmprofiler\Zydis\Generated + + + Header Files\vmprofiler\Zydis\Generated + + + Header Files\vmprofiler\Zydis\Generated + + + Header Files\vmprofiler\Zydis\Generated + + + Header Files\vmprofiler\Zydis\Generated + + + Header Files\vmprofiler\Zycore + + + Header Files\vmprofiler\Zycore + + + Header Files\vmprofiler\Zycore + + + Header Files\vmprofiler\Zycore + + + Header Files\vmprofiler\Zycore + + + Header Files\vmprofiler\Zycore + + + Header Files\vmprofiler\Zycore + + + Header Files\vmprofiler\Zycore + + + Header Files\vmprofiler\Zycore + + + Header Files\vmprofiler\Zycore + + + Header Files\vmprofiler\Zycore + + + Header Files\vmprofiler\Zycore + + + Header Files\vmprofiler\Zycore + + + Header Files\vmprofiler\Zycore + + + Header Files\vmprofiler\Zycore\API + + + Header Files\vmprofiler\Zycore\API + + + Header Files\vmprofiler\Zycore\API + + + Header Files\vmprofiler\Zycore\API + + + Header Files\vmprofiler\Zycore\API + \ No newline at end of file diff --git a/vmemu/vmemu_t.cpp b/vmemu/vmemu_t.cpp new file mode 100644 index 0000000..7fd006b --- /dev/null +++ b/vmemu/vmemu_t.cpp @@ -0,0 +1,43 @@ +#include "vmemu_t.hpp" + +namespace vm +{ + emu_t::emu_t(std::uint32_t vm_entry_rva, + std::uintptr_t image_base, std::uintptr_t module_base) + : + module_base(module_base), + image_base(image_base), + vm_entry_rva(vm_entry_rva) + { + auto err = uc_open(UC_ARCH_X86, UC_MODE_64, &uc); + + if (err) + throw std::exception("failed to init unicorn", err); + + const auto image_size = + NT_HEADER(module_base)->OptionalHeader.SizeOfImage; + + const auto vm_entry = vm_entry_rva + module_base; + constexpr auto stack_addr = 0x1000000; + + // allocate space for module... + uc_mem_map(uc, module_base, image_size, UC_PROT_ALL); + + // allocate 6 pages for stack... + uc_mem_map(uc, stack_addr, 0x1000 * 6, UC_PROT_READ | UC_PROT_WRITE); + + // write the module into memory... + uc_mem_write(uc, module_base, reinterpret_cast(module_base), image_size); + + // set vm_entry into RIP... + uc_reg_write(uc, UC_X86_REG_RIP, &vm_entry); + + // set stack address up... + uc_reg_write(uc, UC_X86_REG_RSP, &stack_addr); + } + + emu_t::~emu_t() + { + uc_close(uc); + } +} \ No newline at end of file diff --git a/vmemu/vmemu_t.hpp b/vmemu/vmemu_t.hpp new file mode 100644 index 0000000..b962186 --- /dev/null +++ b/vmemu/vmemu_t.hpp @@ -0,0 +1,21 @@ +#pragma once +#include +#include +#include +#include + +namespace vm +{ + class emu_t + { + public: + explicit emu_t(std::uint32_t vm_entry_rva, + std::uintptr_t image_base, std::uintptr_t module_base); + + ~emu_t(); + private: + std::uintptr_t image_base, module_base; + std::uint32_t vm_entry_rva; + uc_engine* uc; + }; +} \ No newline at end of file