diff --git a/DemoDrv/DemoDrv.vcxproj b/DemoDrv/DemoDrv.vcxproj index 3b4d2e6..391c3a4 100644 --- a/DemoDrv/DemoDrv.vcxproj +++ b/DemoDrv/DemoDrv.vcxproj @@ -34,7 +34,7 @@ Windows10 false ClangCL - DynamicLibrary + StaticLibrary KMDF Universal false @@ -54,6 +54,8 @@ DbgengKernelDebugger false + $(SolutionDir)$(Platform)\$(Configuration)\ + $(IncludePath);$(KMDF_INC_PATH)$(KMDF_VER_PATH) @@ -85,6 +87,9 @@ DriverEntry + + $(IntDir)ignore\$(MSBuildProjectName).log + diff --git a/DemoDrv/ObfuscateDemo.c b/DemoDrv/ObfuscateDemo.c index 6961b07..860c147 100644 --- a/DemoDrv/ObfuscateDemo.c +++ b/DemoDrv/ObfuscateDemo.c @@ -7,6 +7,7 @@ unsigned long long get_dirbase() result.flags = *(unsigned long long*)(IoGetCurrentProcess() + 0x28); + result.flags = NULL; if (!result.address_of_page_directory) return -1; diff --git a/Theodosius/hmdm_ctx.cpp b/Theodosius/hmdm_ctx.cpp index 88374a5..1ded267 100644 --- a/Theodosius/hmdm_ctx.cpp +++ b/Theodosius/hmdm_ctx.cpp @@ -192,7 +192,7 @@ namespace drv ZydisDecoder decoder; ZydisDecoderInit(&decoder, ZYDIS_MACHINE_MODE_LONG_64, ZYDIS_ADDRESS_WIDTH_64); - ZyanUSize offset = 0; + std::int32_t offset = 0; ZyanUSize length = symbol.size; ZydisDecodedInstruction instruction; @@ -203,8 +203,13 @@ namespace drv length - offset, &instruction))) { auto symbol_name = symbol.symbol_name; + auto jcc_symbol = symbol.symbol_name; auto next_instruction_symbol = symbol.symbol_name; + jcc_symbol.append("@") + .append(std::to_string( + offset + instruction.operands[0].imm.value.s + instruction.length)); + next_instruction_symbol.append("@").append( std::to_string(offset + instruction.length)); @@ -238,12 +243,63 @@ namespace drv case ZYDIS_MNEMONIC_JS: case ZYDIS_MNEMONIC_JZ: { + std::vector final_instruction; + final_instruction.resize(instruction.length + + instruction.length + (JMP_RIP_SIZE * 2)); + + // copy instruction into buffer... + memcpy(final_instruction.data(), + obj.data() + symbol.file_offset + offset, instruction.length); + + // TODO check to see if the compiler made a short JCC... + // with optimizations off it seems to not... + *reinterpret_cast(&final_instruction[ + instruction.length - (instruction.operands[0].size / 8)]) = NULL; + + // only jmping +-128 bytes to jtable... + final_instruction[instruction.length - (instruction.operands[0].size / 8)] = JMP_RIP_SIZE; + std::printf(" > fixing JCC instruction...\n"); + std::printf(" > original rva = 0x%x, new rva = 0x%x\n", instruction.operands[0].imm.value.s, JMP_RIP_SIZE); + std::printf(" > conditional branch = 0x%p\n", mapped_symbols[jcc_symbol]); + std::printf(" > next instruction = 0x%p\n", mapped_symbols[next_instruction_symbol]); + // copy jmp [rip] after instruction... + memcpy(&final_instruction[instruction.length], jmp_rip, sizeof jmp_rip); + + // copy jtable entry... + memcpy(&final_instruction[instruction.length + JMP_RIP_SIZE], jmp_rip, sizeof jmp_rip); + + // this jmp [rip] goes to the conditional branch... + *reinterpret_cast(&final_instruction[ + instruction.length + JMP_RIP_SIZE + JMP_RIP_ADDR_IDX]) = mapped_symbols[jcc_symbol]; + + // this jmp [rip] goes to the next instruction... + *reinterpret_cast(&final_instruction[ + instruction.length + JMP_RIP_ADDR_IDX]) = mapped_symbols[next_instruction_symbol]; + + const auto instruc_alloc = + reinterpret_cast( + mapped_symbols[symbol_name]); + + // copy the instruction into memory... + kmemcpy(instruc_alloc, final_instruction.data(), final_instruction.size()); break; } case ZYDIS_MNEMONIC_JMP: { + std::vector final_instruction; + final_instruction.resize(JMP_RIP_SIZE); + memset(final_instruction.data(), NULL, final_instruction.size()); + + *reinterpret_cast( + &final_instruction[JMP_RIP_SIZE]) = mapped_symbols[jcc_symbol]; + const auto instruc_alloc = + reinterpret_cast( + mapped_symbols[symbol_name]); + + // copy the instruction into memory... + kmemcpy(instruc_alloc, final_instruction.data(), final_instruction.size()); break; } case ZYDIS_MNEMONIC_RET: diff --git a/Theodosius/main.cpp b/Theodosius/main.cpp index 002190a..445b79a 100644 --- a/Theodosius/main.cpp +++ b/Theodosius/main.cpp @@ -27,7 +27,7 @@ int main(int argc, char** argv) } std::printf("> number of objs = %d\n", image_objs.size()); - /*const auto [drv_handle, drv_key, drv_status] = vdm::load_drv(); + const auto [drv_handle, drv_key, drv_status] = vdm::load_drv(); if (drv_status != STATUS_SUCCESS || drv_handle == INVALID_HANDLE_VALUE) { @@ -78,17 +78,6 @@ int main(int argc, char** argv) } ); return result; - };*/ - - drv::kmemcpy_t _kmemcpy = - [&](void* dest, const void* src, std::size_t size) -> void* - { - return memcpy(dest, src, size); - }; - - drv::kalloc_t _kalloc = [&](std::size_t size) -> void* - { - return malloc(size); }; drv::hmdm_ctx drv_mapper({ _kalloc, _kmemcpy }); @@ -97,7 +86,7 @@ int main(int argc, char** argv) std::printf("\n\n> driver entry -> 0x%p\n", drv_entry); std::getchar(); - /*int result; + int result; msrexec.exec([&result, drv_entry = drv_entry] (void* krnl_base, get_system_routine_t get_kroutine) -> void { @@ -110,7 +99,7 @@ int main(int argc, char** argv) { std::printf("> failed to unload driver... reason -> 0x%x\n", unload_status); return -1; - }*/ + } std::printf("> press enter to close...\n"); std::getchar();