From 2c1bcbe4fed3a9e70f375f205c1af6587c3fcd60 Mon Sep 17 00:00:00 2001 From: keowu Date: Sun, 8 Jun 2025 12:04:43 -0300 Subject: [PATCH] feat: Code improvements, new obfuscation options, and initial junk code insertion logic - Some parts of the code have been organized. - A new obfuscation option to encrypt the obfuscated code is now available. - The foundation for junk code insertion has been implemented. --- .../Ryujin/Models/RyujinObfuscatorConfig.hh | 1 + RyujinConsole/RyujinConsole/Ryujin/Ryujin.cc | 3 ++ .../RyujinCore/RyujinObfuscationCore.cc | 38 +++++++++++-------- .../RyujinCore/RyujinObfuscationCore.hh | 1 + RyujinConsole/RyujinConsole/RyujinConsole.cc | 1 + 5 files changed, 29 insertions(+), 15 deletions(-) diff --git a/RyujinConsole/RyujinConsole/Ryujin/Models/RyujinObfuscatorConfig.hh b/RyujinConsole/RyujinConsole/Ryujin/Models/RyujinObfuscatorConfig.hh index 2a6eaec..0fc3d7b 100644 --- a/RyujinConsole/RyujinConsole/Ryujin/Models/RyujinObfuscatorConfig.hh +++ b/RyujinConsole/RyujinConsole/Ryujin/Models/RyujinObfuscatorConfig.hh @@ -9,6 +9,7 @@ public: bool m_isIatObfuscation; //Process IAT Obfuscation bool m_isJunkCode; // Insert junk code to confuse bool m_isIgnoreOriginalCodeRemove; // Do not remove the original code after processing (replace the original instructions with NOPs) + bool m_isEncryptObfuscatedCode; // The user wants to encrypt all obfuscated code to avoid detection std::vector m_strProceduresToObfuscate; // Names of the procedures to obfuscate // todo: passes diff --git a/RyujinConsole/RyujinConsole/Ryujin/Ryujin.cc b/RyujinConsole/RyujinConsole/Ryujin/Ryujin.cc index 062306a..fff5a31 100644 --- a/RyujinConsole/RyujinConsole/Ryujin/Ryujin.cc +++ b/RyujinConsole/RyujinConsole/Ryujin/Ryujin.cc @@ -179,6 +179,9 @@ bool Ryujin::run(const RyujinObfuscatorConfig& config) { } + // Encrypt all obfuscated code + if (config.m_isEncryptObfuscatedCode) todoAction(); + //Process new opcodes peSections.ProcessOpcodesNewSection(opcodesWithRelocsFixed); diff --git a/RyujinConsole/RyujinConsole/Ryujin/RyujinCore/RyujinObfuscationCore.cc b/RyujinConsole/RyujinConsole/Ryujin/RyujinCore/RyujinObfuscationCore.cc index 22e5a81..67c7bb9 100644 --- a/RyujinConsole/RyujinConsole/Ryujin/RyujinCore/RyujinObfuscationCore.cc +++ b/RyujinConsole/RyujinConsole/Ryujin/RyujinCore/RyujinObfuscationCore.cc @@ -84,15 +84,12 @@ void RyujinObfuscationCore::addPaddingSpaces() { std::vector new_opcodes; - for (auto individual_opcode : opcode) { - + for (auto individual_opcode : opcode) new_opcodes.push_back(individual_opcode); - } - new_instructions.push_back(new_opcodes); - //Inserindo junkcode + //Storing Nop-Spacing std::vector gen_opcodes; asmjit::CodeHolder code; @@ -104,12 +101,10 @@ void RyujinObfuscationCore::addPaddingSpaces() { code.flatten(); auto section = code.sectionById(0); - const uint8_t* buf = section->buffer().data(); - size_t size = section->buffer().size(); + const auto buf = section->buffer().data(); + auto size = section->buffer().size(); - for (size_t i = 0; i < size; ++i) { - gen_opcodes.push_back(buf[i]); - } + for (auto i = 0; i < size; ++i) gen_opcodes.push_back(buf[i]); new_instructions.push_back(gen_opcodes); @@ -144,12 +139,12 @@ void RyujinObfuscationCore::obfuscateIat() { auto data = opcode.data(); auto size = opcode.size(); - if (data[0] == uopcode) { //0xFF ? + if (data[0] == uopcode) //0xFF ? if (std::memcmp(&*(data + 2), &value, sizeof(uint32_t)) == 0) // Is it the same memory immediate? return std::make_pair(block_id, opcode_id); - } + opcode_id++; @@ -159,7 +154,7 @@ void RyujinObfuscationCore::obfuscateIat() { } return std::make_pair(-1, -1); - }; + }; for (auto& block : m_obfuscated_bb) { @@ -270,6 +265,10 @@ void RyujinObfuscationCore::obfuscateIat() { return; } +void RyujinObfuscationCore::insertJunkCode() { + // TODO +} + void RyujinObfuscationCore::updateBasicBlocksContext() { auto new_obfuscated_opcodes = getProcessedProc().getUpdateOpcodes(); @@ -297,9 +296,18 @@ BOOL RyujinObfuscationCore::Run() { } + if (m_config.m_isJunkCode) { + + //First let's insert junk code + insertJunkCode(); + + //Update our basic blocks context to rely 1-1 for the new obfuscated opcodes. + this->updateBasicBlocksContext(); + + } + /* - if (config.m_isJunkCode) todoAction(); - if (config.m_isVirtualized) todoAction(); + if (m_config.m_isVirtualized) todoAction(); */ return TRUE; diff --git a/RyujinConsole/RyujinConsole/Ryujin/RyujinCore/RyujinObfuscationCore.hh b/RyujinConsole/RyujinConsole/Ryujin/RyujinCore/RyujinObfuscationCore.hh index 55bcccf..3550eb2 100644 --- a/RyujinConsole/RyujinConsole/Ryujin/RyujinCore/RyujinObfuscationCore.hh +++ b/RyujinConsole/RyujinConsole/Ryujin/RyujinCore/RyujinObfuscationCore.hh @@ -26,6 +26,7 @@ private: void updateBasicBlocksContext(); void addPaddingSpaces(); void obfuscateIat(); + void insertJunkCode(); std::vector fix_branch_near_far_short(uint8_t original_opcode, uint64_t jmp_address, uint64_t target_address); uint32_t findOpcodeOffset(const uint8_t* data, size_t dataSize, const void* opcode, size_t opcodeSize); diff --git a/RyujinConsole/RyujinConsole/RyujinConsole.cc b/RyujinConsole/RyujinConsole/RyujinConsole.cc index 74e00df..cccb6ea 100644 --- a/RyujinConsole/RyujinConsole/RyujinConsole.cc +++ b/RyujinConsole/RyujinConsole/RyujinConsole.cc @@ -15,6 +15,7 @@ auto main() -> int { config.m_isRandomSection = FALSE; config.m_isVirtualized = FALSE; config.m_isIatObfuscation = TRUE; + config.m_isEncryptObfuscatedCode = FALSE; std::vector procsToObfuscate{ "main", "invoke_main",