diff --git a/RyujinConsole/RyujinConsole/Ryujin/Models/RyujinInstruction.hh b/RyujinConsole/RyujinConsole/Ryujin/Models/RyujinInstruction.hh index ca0353a..83fb714 100644 --- a/RyujinConsole/RyujinConsole/Ryujin/Models/RyujinInstruction.hh +++ b/RyujinConsole/RyujinConsole/Ryujin/Models/RyujinInstruction.hh @@ -1,3 +1,4 @@ +#pragma once; struct RyujinInstruction { diff --git a/RyujinConsole/RyujinConsole/Ryujin/Models/RyujinObfuscatorConfig.hh b/RyujinConsole/RyujinConsole/Ryujin/Models/RyujinObfuscatorConfig.hh index 1c8f13f..2a6eaec 100644 --- a/RyujinConsole/RyujinConsole/Ryujin/Models/RyujinObfuscatorConfig.hh +++ b/RyujinConsole/RyujinConsole/Ryujin/Models/RyujinObfuscatorConfig.hh @@ -1,3 +1,5 @@ +#pragma once +#include class RyujinObfuscatorConfig { diff --git a/RyujinConsole/RyujinConsole/Ryujin/Models/RyujinProcedure.hh b/RyujinConsole/RyujinConsole/Ryujin/Models/RyujinProcedure.hh index 6776adb..db9f0fd 100644 --- a/RyujinConsole/RyujinConsole/Ryujin/Models/RyujinProcedure.hh +++ b/RyujinConsole/RyujinConsole/Ryujin/Models/RyujinProcedure.hh @@ -1,4 +1,5 @@ #pragma once +#include #include "RyujinBasicBlock.hh" class RyujinProcedure { @@ -10,4 +11,26 @@ public: uintptr_t size; std::vector basic_blocks; + std::vector getUpdateOpcodes() { + + std::vector result; + + for (auto& block : basic_blocks) { + + auto& blocks = block.opcodes; + + for (size_t i = 0; i < blocks.size(); ++i) { + const auto& block = blocks[i]; + if (!block.empty()) { + for (const auto& byte : block) { + result.emplace_back(byte); + } + } + } + + } + + return result; + } + }; \ No newline at end of file diff --git a/RyujinConsole/RyujinConsole/Ryujin/Ryujin.cc b/RyujinConsole/RyujinConsole/Ryujin/Ryujin.cc index 763498a..fd958af 100644 --- a/RyujinConsole/RyujinConsole/Ryujin/Ryujin.cc +++ b/RyujinConsole/RyujinConsole/Ryujin/Ryujin.cc @@ -94,6 +94,8 @@ bool Ryujin::run(const RyujinObfuscatorConfig& config) { return FALSE; } + std::vector processed_procs; + for (auto& proc : m_ryujinProcedures) { auto it = std::find(config.m_strProceduresToObfuscate.begin(), config.m_strProceduresToObfuscate.end(), proc.name); @@ -134,9 +136,10 @@ bool Ryujin::run(const RyujinObfuscatorConfig& config) { proc.basic_blocks = rybb.createBasicBlocks(ucOpcodes, proc.size, proc.address); //Is time to obfuscate ? - if (config.m_isVirtualized) todoAction(); - if (config.m_isIatObfuscation) todoAction(); - if (config.m_isJunkCode) todoAction(); + RyujinObfuscationCore obc(config, proc); + obc.Run(); + processed_procs.push_back(obc.getProcessedProc()); + obc.~RyujinObfuscationCore(); //TODO: Custom passes support @@ -155,12 +158,15 @@ bool Ryujin::run(const RyujinObfuscatorConfig& config) { RyujinPESections peSections; peSections.AddNewSection(m_strInputFilePath, chSectionName); - //Process new opcodes - std::vector tempValued = { 0xDE, 0xAD, 0xBE, 0xEF }; - peSections.ProcessOpcodesNewSection(tempValued); + //Get New Opcodes - todo: improve, this only works for the first procedure + std::vector tempValued = processed_procs.front().getUpdateOpcodes(); //Fix relocations + + //Process new opcodes + peSections.ProcessOpcodesNewSection(tempValued); + //Save output file peSections.FinishNewSection(m_strOutputFilePath); diff --git a/RyujinConsole/RyujinConsole/Ryujin/Ryujin.hh b/RyujinConsole/RyujinConsole/Ryujin/Ryujin.hh index 875b5b5..07ad19b 100644 --- a/RyujinConsole/RyujinConsole/Ryujin/Ryujin.hh +++ b/RyujinConsole/RyujinConsole/Ryujin/Ryujin.hh @@ -8,6 +8,7 @@ #include "Utils/RyujinUtils.hh" #include "Models/RyujinObfuscatorConfig.hh" #include "RyujinCore/BasicBlockerBuilder.hh" +#include "RyujinCore/RyujinObfuscationCore.hh" #include "Utils/RyujinPESections.hh" class Ryujin { diff --git a/RyujinConsole/RyujinConsole/Ryujin/RyujinCore/RyujinObfuscationCore.cc b/RyujinConsole/RyujinConsole/Ryujin/RyujinCore/RyujinObfuscationCore.cc new file mode 100644 index 0000000..b2b93f0 --- /dev/null +++ b/RyujinConsole/RyujinConsole/Ryujin/RyujinCore/RyujinObfuscationCore.cc @@ -0,0 +1,143 @@ +#include "RyujinObfuscationCore.hh" + +RyujinObfuscationCore::RyujinObfuscationCore(const RyujinObfuscatorConfig& config, const RyujinProcedure& proc) { + + m_proc = proc; + + if (!extractUnusedRegisters()) + throw std::exception("No registers avaliable for obfuscation..."); + + + +} + +RyujinProcedure RyujinObfuscationCore::getProcessedProc() { + + return this->m_proc; +} + +BOOL RyujinObfuscationCore::extractUnusedRegisters() { + + std::vector candidateRegs = { + + ZYDIS_REGISTER_RAX, + ZYDIS_REGISTER_RCX, + ZYDIS_REGISTER_RDX, + ZYDIS_REGISTER_RBX, + ZYDIS_REGISTER_RSP, + ZYDIS_REGISTER_RBP, + ZYDIS_REGISTER_RSI, + ZYDIS_REGISTER_RDI, + ZYDIS_REGISTER_R8, + ZYDIS_REGISTER_R9, + ZYDIS_REGISTER_R10, + ZYDIS_REGISTER_R11, + ZYDIS_REGISTER_R12, + ZYDIS_REGISTER_R13, + ZYDIS_REGISTER_R14, + ZYDIS_REGISTER_R15, + + }; + + std::set usedRegs; + + for (auto blocks : m_proc.basic_blocks) { + + for (auto instr : blocks.instructions) { + + for (auto i = 0; i < instr.instruction.info.operand_count; ++i) { + + const ZydisDecodedOperand& op = instr.instruction.operands[i]; + + if (op.type == ZYDIS_OPERAND_TYPE_REGISTER) usedRegs.insert(op.reg.value); + else if (op.type == ZYDIS_OPERAND_TYPE_POINTER) { + + if (op.mem.base != ZYDIS_REGISTER_NONE) usedRegs.insert(op.mem.base); + if (op.mem.index != ZYDIS_REGISTER_NONE) usedRegs.insert(op.mem.index); + + } + + } + + } + + } + + ZydisRegister freeReg = ZYDIS_REGISTER_NONE; + for (auto reg : candidateRegs) + if (usedRegs.count(reg) == 0) m_unusedRegisters.push_back(reg); + + return m_unusedRegisters.size() >= 2; //Theres unused regs for be used by us ? +} + +void RyujinObfuscationCore::addPaddingSpaces() { + + asmjit::JitRuntime runtime; + + for (auto& block : m_proc.basic_blocks) { + + std::vector> new_instructions; + + for (auto& opcode : block.opcodes) { + + std::vector new_opcodes; + + for (auto individual_opcode : opcode) { + + new_opcodes.push_back(individual_opcode); + + } + + new_instructions.push_back(new_opcodes); + + //Inserindo junkcode + std::vector gen_opcodes; + + asmjit::CodeHolder code; + code.init(runtime.environment()); + asmjit::x86::Assembler a(&code); + + for (auto i = 0; i < 50; i++) { + a.nop(); + } + + code.flatten(); + + auto section = code.sectionById(0); + const uint8_t* buf = section->buffer().data(); + size_t size = section->buffer().size(); + + for (size_t i = 0; i < size; ++i) { + gen_opcodes.push_back(buf[i]); + } + + new_instructions.push_back(gen_opcodes); + + } + + //Overrite the original opcodes with new ones + block.opcodes.clear(); + block.opcodes.assign(new_instructions.begin(), new_instructions.end()); + + } + +} + +BOOL RyujinObfuscationCore::Run() { + + //Add padding spaces + addPaddingSpaces(); + + /* + if (config.m_isIatObfuscation) todoAction(); + + if (config.m_isVirtualized) todoAction(); + if (config.m_isJunkCode) todoAction(); + */ + + return TRUE; +} + +RyujinObfuscationCore::~RyujinObfuscationCore() { + +} \ No newline at end of file diff --git a/RyujinConsole/RyujinConsole/Ryujin/RyujinCore/RyujinObfuscationCore.hh b/RyujinConsole/RyujinConsole/Ryujin/RyujinCore/RyujinObfuscationCore.hh new file mode 100644 index 0000000..dbc2262 --- /dev/null +++ b/RyujinConsole/RyujinConsole/Ryujin/RyujinCore/RyujinObfuscationCore.hh @@ -0,0 +1,25 @@ +#pragma once +#include +#include +#include +#include +#include +#include +#include "../Models/RyujinProcedure.hh" +#include "../Models/RyujinObfuscatorConfig.hh" + +class RyujinObfuscationCore { + +private: + std::vector m_unusedRegisters; + RyujinProcedure m_proc; + BOOL extractUnusedRegisters(); + void addPaddingSpaces(); + +public: + RyujinObfuscationCore(const RyujinObfuscatorConfig& config, const RyujinProcedure& proc); + BOOL Run(); + RyujinProcedure getProcessedProc(); + ~RyujinObfuscationCore(); + +}; \ No newline at end of file diff --git a/RyujinConsole/RyujinConsole/RyujinConsole.vcxproj b/RyujinConsole/RyujinConsole/RyujinConsole.vcxproj index 2c0ed01..60024b2 100644 --- a/RyujinConsole/RyujinConsole/RyujinConsole.vcxproj +++ b/RyujinConsole/RyujinConsole/RyujinConsole.vcxproj @@ -134,6 +134,7 @@ + @@ -145,6 +146,7 @@ + diff --git a/RyujinConsole/RyujinConsole/RyujinConsole.vcxproj.filters b/RyujinConsole/RyujinConsole/RyujinConsole.vcxproj.filters index 0c91088..9a621c7 100644 --- a/RyujinConsole/RyujinConsole/RyujinConsole.vcxproj.filters +++ b/RyujinConsole/RyujinConsole/RyujinConsole.vcxproj.filters @@ -45,6 +45,9 @@ Ryujin\Utils + + Ryujin\RyujinCore + @@ -74,5 +77,8 @@ Ryujin\Utils + + Ryujin\RyujinCore + \ No newline at end of file