diff --git a/RyujinConsole/RyujinConsole/Ryujin/Ryujin.cc b/RyujinConsole/RyujinConsole/Ryujin/Ryujin.cc index c14e98f..ae49839 100644 --- a/RyujinConsole/RyujinConsole/Ryujin/Ryujin.cc +++ b/RyujinConsole/RyujinConsole/Ryujin/Ryujin.cc @@ -156,8 +156,43 @@ bool Ryujin::run(const RyujinObfuscatorConfig& config) { RyujinPESections peSections; peSections.AddNewSection(m_strInputFilePath, chSectionName); - uintptr_t offsetVA = 0; + uintptr_t offsetVA = 0, miniVmEnterAddress = 0; std::vector opcodesWithRelocsFixed; + + //Insert minivm enter routine + if (config.m_isVirtualized) { + + std::vector miniVmEnter{ + + 0x48, 0x89, 0x4C, 0x24, 0x08, 0x48, 0x83, 0xEC, 0x28, 0x48, 0x8B, 0x44, + 0x24, 0x30, 0x48, 0xC1, 0xE8, 0x10, 0x48, 0x25, 0xFF, 0x00, 0x00, 0x00, + 0x88, 0x44, 0x24, 0x01, 0x48, 0x8B, 0x44, 0x24, 0x30, 0x48, 0xC1, 0xE8, + 0x08, 0x48, 0x25, 0xFF, 0x00, 0x00, 0x00, 0x88, 0x04, 0x24, 0x48, 0x8B, + 0x44, 0x24, 0x30, 0x48, 0x25, 0xFF, 0x00, 0x00, 0x00, 0x48, 0x89, 0x44, + 0x24, 0x10, 0x48, 0xC7, 0x44, 0x24, 0x08, 0x00, 0x00, 0x00, 0x00, 0x0F, + 0xB6, 0x04, 0x24, 0x88, 0x44, 0x24, 0x04, 0x80, 0x7C, 0x24, 0x04, 0x01, + 0x74, 0x17, 0x80, 0x7C, 0x24, 0x04, 0x02, 0x74, 0x27, 0x80, 0x7C, 0x24, + 0x04, 0x03, 0x74, 0x37, 0x80, 0x7C, 0x24, 0x04, 0x04, 0x74, 0x42, 0xEB, + 0x53, 0x48, 0x8B, 0x44, 0x24, 0x10, 0x48, 0x8B, 0x4C, 0x24, 0x08, 0x48, + 0x03, 0xC8, 0x48, 0x8B, 0xC1, 0x48, 0x89, 0x44, 0x24, 0x08, 0xEB, 0x45, + 0x48, 0x8B, 0x44, 0x24, 0x10, 0x48, 0x8B, 0x4C, 0x24, 0x08, 0x48, 0x2B, + 0xC8, 0x48, 0x8B, 0xC1, 0x48, 0x89, 0x44, 0x24, 0x08, 0xEB, 0x2E, 0x48, + 0x8B, 0x44, 0x24, 0x08, 0x48, 0x0F, 0xAF, 0x44, 0x24, 0x10, 0x48, 0x89, + 0x44, 0x24, 0x08, 0xEB, 0x1C, 0x33, 0xD2, 0x48, 0x8B, 0x44, 0x24, 0x08, + 0x48, 0xF7, 0x74, 0x24, 0x10, 0x48, 0x89, 0x44, 0x24, 0x08, 0xEB, 0x09, + 0x48, 0xC7, 0x44, 0x24, 0x08, 0x00, 0x00, 0x00, 0x00, 0x48, 0x8B, 0x44, + 0x24, 0x08, 0x48, 0x83, 0xC4, 0x28, 0xC3 + + }; + + opcodesWithRelocsFixed.insert(opcodesWithRelocsFixed.end(), miniVmEnter.begin(), miniVmEnter.end()); + + miniVmEnterAddress = peSections.getRyujinSectionVA(); + + offsetVA += miniVmEnter.size(); + + } + for (auto& obc : processed_procs) { auto tempValued = obc.getProcessedProc().getUpdateOpcodes(); @@ -168,6 +203,9 @@ bool Ryujin::run(const RyujinObfuscatorConfig& config) { // Removing and adding a jump in the original procedure and removing original opcodes for a jump to the new obfuscated code obc.removeOldOpcodeRedirect(peSections.mappedPeDiskBaseAddress(), peSections.getRyujinMappedPeSize(), reinterpret_cast(imgDos) + peSections.getRyujinSectionVA() + offsetVA, config.m_isIgnoreOriginalCodeRemove); + // Inserindo MiniVMEnter + if (config.m_isVirtualized) obc.InsertMiniVmEnterProcedureAddress(reinterpret_cast(imgDos), miniVmEnterAddress, tempValued); + // Destructing class obc.~RyujinObfuscationCore(); diff --git a/RyujinConsole/RyujinConsole/Ryujin/RyujinCore/RyujinObfuscationCore.cc b/RyujinConsole/RyujinConsole/Ryujin/RyujinCore/RyujinObfuscationCore.cc index f0c5119..ca302f2 100644 --- a/RyujinConsole/RyujinConsole/Ryujin/RyujinCore/RyujinObfuscationCore.cc +++ b/RyujinConsole/RyujinConsole/Ryujin/RyujinCore/RyujinObfuscationCore.cc @@ -440,7 +440,9 @@ void RyujinObfuscationCore::insertVirtualization() { // É uma instrução candidata a ser virtualizada pela minivm ?? auto isValidToSRyujinMiniVm = [&](RyujinInstruction instr) { - return instr.instruction.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && instr.instruction.operands[1].type == ZYDIS_OPERAND_TYPE_IMMEDIATE; + return instr.instruction.operands[0].type == ZYDIS_OPERAND_TYPE_REGISTER && instr.instruction.operands[1].type == ZYDIS_OPERAND_TYPE_IMMEDIATE && + //Ignorando registradores e operações de stack + (instr.instruction.operands[0].reg.value != ZYDIS_REGISTER_RSP && instr.instruction.operands[0].reg.value != ZYDIS_REGISTER_RBP); }; // Vamos mapear o registrador do Zydis para o ASMJIT @@ -766,8 +768,13 @@ void RyujinObfuscationCore::insertVirtualization() { asmjit::x86::Assembler a(&code); a.push(asmjit::x86::rcx); - a.mov(asmjit::x86::rcx, translateToMiniVmBytecode(instr.instruction.operands[0].reg.value, opType, instr.instruction.operands[1].imm.value.u)); - a.mov(asmjit::x86::rax, 0x8888888888888888); // Endereço a ser substituido pelo endereço da nossa minivm + a.mov(asmjit::x86::rcx, translateToMiniVmBytecode(instr.instruction.operands[0].reg.value, opType, instr.instruction.operands[1].imm.value.u)); //TODO: e se o reg ex: rax já tiver uma valor para um add, devemos armazenar rax também ? + a.emit(asmjit::x86::Inst::kIdRdgsbase, asmjit::x86::rax); + a.add(asmjit::x86::rax, 0x60); + a.mov(asmjit::x86::rax, asmjit::x86::ptr(asmjit::x86::rax)); + a.add(asmjit::x86::rax, 0x10); + a.mov(asmjit::x86::rax, asmjit::x86::ptr(asmjit::x86::rax)); + a.add(asmjit::x86::rax, asmjit::imm(0x88)); a.call(asmjit::x86::rax); a.mov(mapZydisToAsmjitGp(instr.instruction.operands[0].reg.value), asmjit::x86::rax); a.pop(asmjit::x86::rcx); @@ -1143,6 +1150,25 @@ void RyujinObfuscationCore::applyRelocationFixupsToInstructions(uintptr_t imageB } +void RyujinObfuscationCore::InsertMiniVmEnterProcedureAddress(uintptr_t imageBase, uintptr_t virtualAddress, std::vector& new_opcodes) { + + //Inserting Ryujin MiniVm Address on each vm entry reference + if (m_config.m_isVirtualized) { + auto size = new_opcodes.size(); + auto data = new_opcodes.data(); + + unsigned char ucSignature[]{ 0x48, 0x05, 0x88, 0x00, 0x00, 0x00 }; + + for (auto i = 0; i < size; i++) + if (std::memcmp(&*(data + i), ucSignature, 6) == 0) { + std::printf("FIND!!\n"); + std::memset(&*(data + i + 2), 0, 4); + std::memcpy(&*(data + i + 2), &virtualAddress, sizeof(uint32_t)); + } + } + +} + void RyujinObfuscationCore::removeOldOpcodeRedirect(uintptr_t newMappedPE, std::size_t szMapped, uintptr_t newObfuscatedAddress, bool isIgnoreOriginalCodeRemove) { /* diff --git a/RyujinConsole/RyujinConsole/Ryujin/RyujinCore/RyujinObfuscationCore.hh b/RyujinConsole/RyujinConsole/Ryujin/RyujinCore/RyujinObfuscationCore.hh index 6412d41..a7c5021 100644 --- a/RyujinConsole/RyujinConsole/Ryujin/RyujinCore/RyujinObfuscationCore.hh +++ b/RyujinConsole/RyujinConsole/Ryujin/RyujinCore/RyujinObfuscationCore.hh @@ -67,6 +67,7 @@ public: RyujinObfuscationCore(const RyujinObfuscatorConfig& config, const RyujinProcedure& proc, uintptr_t ProcImageBase); void applyRelocationFixupsToInstructions(uintptr_t imageBase, DWORD virtualAddress, std::vector& new_opcodes); void removeOldOpcodeRedirect(uintptr_t newMappedPE, std::size_t szMapped, uintptr_t newObfuscatedAddress, bool isIgnoreOriginalCodeRemove = false); + void InsertMiniVmEnterProcedureAddress(uintptr_t imageBase, uintptr_t virtualAddress, std::vector& new_opcodes); BOOL Run(); RyujinProcedure getProcessedProc(); ~RyujinObfuscationCore(); diff --git a/RyujinConsole/RyujinConsole/RyujinConsole.cc b/RyujinConsole/RyujinConsole/RyujinConsole.cc index 4d8e8f1..ca42026 100644 --- a/RyujinConsole/RyujinConsole/RyujinConsole.cc +++ b/RyujinConsole/RyujinConsole/RyujinConsole.cc @@ -11,17 +11,17 @@ auto main() -> int { RyujinObfuscatorConfig config; config.m_isIgnoreOriginalCodeRemove = FALSE; - config.m_isJunkCode = FALSE; + config.m_isJunkCode = TRUE; config.m_isRandomSection = FALSE; config.m_isVirtualized = TRUE; config.m_isIatObfuscation = TRUE; config.m_isEncryptObfuscatedCode = FALSE; std::vector procsToObfuscate{ - //"main" - //"invoke_main", - "sum" - // "__scrt_common_main", - // "j___security_init_cookie" + "sum", + "main", + "invoke_main" + "__scrt_common_main", + "j___security_init_cookie" }; config.m_strProceduresToObfuscate.assign(procsToObfuscate.begin(), procsToObfuscate.end());