diff --git a/RyujinConsole/RyujinConsole/Ryujin/Ryujin.cc b/RyujinConsole/RyujinConsole/Ryujin/Ryujin.cc index f138178..224e593 100644 --- a/RyujinConsole/RyujinConsole/Ryujin/Ryujin.cc +++ b/RyujinConsole/RyujinConsole/Ryujin/Ryujin.cc @@ -91,13 +91,13 @@ bool Ryujin::run(const RyujinObfuscatorConfig& config) { return FALSE; } - for (const auto& proc : m_ryujinProcedures) { + for (auto& proc : m_ryujinProcedures) { auto it = std::find(config.m_strProceduresToObfuscate.begin(), config.m_strProceduresToObfuscate.end(), proc.name); if (it == config.m_strProceduresToObfuscate.end()) continue; - std::printf("[WORKING ON]: %s\n", proc.name); + std::printf("[WORKING ON]: %s\n", proc.name.c_str()); // Is a valid procedure ? if (proc.size == 0) { @@ -111,8 +111,22 @@ bool Ryujin::run(const RyujinObfuscatorConfig& config) { continue; } - //Create basic blocks + //Get procedure opcodes from mapped pe file + auto ucOpcodes = new unsigned char[proc.size] { 0 }; + std::memcpy( + + ucOpcodes, + reinterpret_cast(proc.address), + proc.size + + ); + //Create basic blocks + RyujinBasicBlockerBuilder rybb(ZYDIS_MACHINE_MODE_LONG_64, ZydisStackWidth_::ZYDIS_STACK_WIDTH_64); + proc.basic_blocks = rybb.createBasicBlocks(ucOpcodes, proc.size, proc.address); + + //Clean up opcodes + delete[] ucOpcodes; } diff --git a/RyujinConsole/RyujinConsole/Ryujin/Ryujin.hh b/RyujinConsole/RyujinConsole/Ryujin/Ryujin.hh index 448a040..b32a8cb 100644 --- a/RyujinConsole/RyujinConsole/Ryujin/Ryujin.hh +++ b/RyujinConsole/RyujinConsole/Ryujin/Ryujin.hh @@ -7,6 +7,7 @@ #include "PDB/RyujinPdbParsing.hh" #include "Utils/RyujinUtils.hh" #include "Models/RyujinObfuscatorConfig.hh" +#include "RyujinCore/BasicBlockerBuilder.hh" class Ryujin { diff --git a/RyujinConsole/RyujinConsole/Ryujin/RyujinCore/BasicBlockerBuilder.cc b/RyujinConsole/RyujinConsole/Ryujin/RyujinCore/BasicBlockerBuilder.cc new file mode 100644 index 0000000..9f09418 --- /dev/null +++ b/RyujinConsole/RyujinConsole/Ryujin/RyujinCore/BasicBlockerBuilder.cc @@ -0,0 +1,100 @@ +#include "BasicBlockerBuilder.hh" + +bool RyujinBasicBlockerBuilder::isControlFlow(const ZydisDecodedInstruction& instruction) const { + + return (instruction.meta.category == ZYDIS_CATEGORY_CALL || + instruction.meta.category == ZYDIS_CATEGORY_RET || + instruction.meta.category == ZYDIS_CATEGORY_UNCOND_BR || + instruction.meta.category == ZYDIS_CATEGORY_COND_BR || + instruction.meta.category == ZYDIS_CATEGORY_SYSTEM || + instruction.meta.category == ZYDIS_CATEGORY_INTERRUPT || + instruction.meta.category == ZYDIS_CATEGORY_SYSCALL); +} + +RyujinBasicBlockerBuilder::RyujinBasicBlockerBuilder(ZydisMachineMode machine, ZydisStackWidth stack) { + + ::ZydisDecoderInit( + + _Inout_ &decoder, + _In_ machine, + _In_ stack + + ); + +} + +std::vector RyujinBasicBlockerBuilder::createBasicBlocks(const unsigned char* chOpcode, size_t szOpcode, uintptr_t start_address) { + + std::vector blocks; + + std::size_t offset = 0; + uintptr_t curr_addr = start_address; + + while (offset < szOpcode) { + + RyujinBasicBlock block; + block.start_address = start_address; + + std::size_t inner = offset; + while (inner < szOpcode) { + + ZydisDisassembledInstruction instr; + if (!ZYAN_SUCCESS(::ZydisDisassembleIntel( + + _In_ ZYDIS_MACHINE_MODE_LONG_64, + _In_ curr_addr + (inner - offset), + _In_ chOpcode + inner, + _In_ szOpcode - inner, + _Out_ &instr + + ))) { + + std::printf( + + "RyujinBasicBlockerBuilder::createBasicBlocks: Zydis disam failed %llx\n", + inner + + ); + + break; + } + + //Storing the instruction relative to the basic block + RyujinInstruction inst; + inst.addressofinstruction = curr_addr + (inner - offset); + inst.instruction = instr; + + block.instructions.push_back( + + inst + + ); + + //Storing the original opcodes from basic block + block.opcodes.emplace_back( + + chOpcode + inner, + chOpcode + inner + instr.info.length + + ); + + inner += instr.info.length; + + //Theres a branch ? so let's preparate the next block + if (isControlFlow( + + instr.info + + )) break; + + } + + block.end_address = curr_addr + (inner - offset); + blocks.push_back(std::move(block)); + + curr_addr = block.end_address; + offset = inner; + } + + return blocks; +} diff --git a/RyujinConsole/RyujinConsole/Ryujin/RyujinCore/BasicBlockerBuilder.hh b/RyujinConsole/RyujinConsole/Ryujin/RyujinCore/BasicBlockerBuilder.hh new file mode 100644 index 0000000..b71d667 --- /dev/null +++ b/RyujinConsole/RyujinConsole/Ryujin/RyujinCore/BasicBlockerBuilder.hh @@ -0,0 +1,17 @@ +#pragma once +#include +#include +#include +#include "../Models/RyujinBasicBlock.hh" + +class RyujinBasicBlockerBuilder { + +private: + ZydisDecoder decoder; + bool isControlFlow(const ZydisDecodedInstruction& instruction) const; + +public: + RyujinBasicBlockerBuilder(ZydisMachineMode machine, ZydisStackWidth stack); + std::vector createBasicBlocks(const unsigned char* chOpcode, size_t szOpcode, uintptr_t start_address); + +}; \ No newline at end of file diff --git a/RyujinConsole/RyujinConsole/RyujinConsole.vcxproj b/RyujinConsole/RyujinConsole/RyujinConsole.vcxproj index 4cf5666..e4934a2 100644 --- a/RyujinConsole/RyujinConsole/RyujinConsole.vcxproj +++ b/RyujinConsole/RyujinConsole/RyujinConsole.vcxproj @@ -133,6 +133,7 @@ + @@ -142,6 +143,7 @@ + diff --git a/RyujinConsole/RyujinConsole/RyujinConsole.vcxproj.filters b/RyujinConsole/RyujinConsole/RyujinConsole.vcxproj.filters index 65e05e6..e20b699 100644 --- a/RyujinConsole/RyujinConsole/RyujinConsole.vcxproj.filters +++ b/RyujinConsole/RyujinConsole/RyujinConsole.vcxproj.filters @@ -25,6 +25,9 @@ {df02e440-42fd-4d5d-ace9-62fb1891e33c} + + {cc8cdc69-0dce-4cc2-9b0d-6bba400b9599} + @@ -36,6 +39,9 @@ Source Files + + Ryujin\RyujinCore + @@ -59,5 +65,8 @@ Ryujin + + Ryujin\RyujinCore + \ No newline at end of file