feat: Begin working on Ryuujin core

- Working on obfuscated core
- Optimizing Ryuujin
This commit is contained in:
keowu
2025-05-30 09:25:43 -03:00
parent dff74ed8b9
commit 3f8bced350
9 changed files with 215 additions and 6 deletions

View File

@@ -1,3 +1,4 @@
#pragma once;
struct RyujinInstruction {

View File

@@ -1,3 +1,5 @@
#pragma once
#include <string>
class RyujinObfuscatorConfig {

View File

@@ -1,4 +1,5 @@
#pragma once
#include <string>
#include "RyujinBasicBlock.hh"
class RyujinProcedure {
@@ -10,4 +11,26 @@ public:
uintptr_t size;
std::vector<RyujinBasicBlock> basic_blocks;
std::vector<ZyanU8> getUpdateOpcodes() {
std::vector<unsigned char> 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;
}
};

View File

@@ -94,6 +94,8 @@ bool Ryujin::run(const RyujinObfuscatorConfig& config) {
return FALSE;
}
std::vector<RyujinProcedure> 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<unsigned char> tempValued = { 0xDE, 0xAD, 0xBE, 0xEF };
peSections.ProcessOpcodesNewSection(tempValued);
//Get New Opcodes - todo: improve, this only works for the first procedure
std::vector<unsigned char> tempValued = processed_procs.front().getUpdateOpcodes();
//Fix relocations
//Process new opcodes
peSections.ProcessOpcodesNewSection(tempValued);
//Save output file
peSections.FinishNewSection(m_strOutputFilePath);

View File

@@ -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 {

View File

@@ -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<ZydisRegister> 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<ZydisRegister> 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<std::vector<ZyanU8>> new_instructions;
for (auto& opcode : block.opcodes) {
std::vector<ZyanU8> new_opcodes;
for (auto individual_opcode : opcode) {
new_opcodes.push_back(individual_opcode);
}
new_instructions.push_back(new_opcodes);
//Inserindo junkcode
std::vector<ZyanU8> 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() {
}

View File

@@ -0,0 +1,25 @@
#pragma once
#include <Windows.h>
#include <vector>
#include <set>
#include <asmjit/asmjit.h>
#include <Zydis/Zydis.h>
#include <Zydis/SharedTypes.h>
#include "../Models/RyujinProcedure.hh"
#include "../Models/RyujinObfuscatorConfig.hh"
class RyujinObfuscationCore {
private:
std::vector<ZydisRegister> m_unusedRegisters;
RyujinProcedure m_proc;
BOOL extractUnusedRegisters();
void addPaddingSpaces();
public:
RyujinObfuscationCore(const RyujinObfuscatorConfig& config, const RyujinProcedure& proc);
BOOL Run();
RyujinProcedure getProcessedProc();
~RyujinObfuscationCore();
};

View File

@@ -134,6 +134,7 @@
<ClCompile Include="RyujinConsole.cc" />
<ClCompile Include="Ryujin\Ryujin.cc" />
<ClCompile Include="Ryujin\RyujinCore\BasicBlockerBuilder.cc" />
<ClCompile Include="Ryujin\RyujinCore\RyujinObfuscationCore.cc" />
<ClCompile Include="Ryujin\Utils\RyujinPESections.cc" />
<ClCompile Include="Ryujin\Utils\RyujinUtils.cc" />
</ItemGroup>
@@ -145,6 +146,7 @@
<ClInclude Include="Ryujin\PDB\RyujinPdbParsing.hh" />
<ClInclude Include="Ryujin\Ryujin.hh" />
<ClInclude Include="Ryujin\RyujinCore\BasicBlockerBuilder.hh" />
<ClInclude Include="Ryujin\RyujinCore\RyujinObfuscationCore.hh" />
<ClInclude Include="Ryujin\Utils\RyujinPESections.hh" />
<ClInclude Include="Ryujin\Utils\RyujinUtils.hh" />
</ItemGroup>

View File

@@ -45,6 +45,9 @@
<ClCompile Include="Ryujin\Utils\RyujinPESections.cc">
<Filter>Ryujin\Utils</Filter>
</ClCompile>
<ClCompile Include="Ryujin\RyujinCore\RyujinObfuscationCore.cc">
<Filter>Ryujin\RyujinCore</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Ryujin\Models\RyujinBasicBlock.hh">
@@ -74,5 +77,8 @@
<ClInclude Include="Ryujin\Utils\RyujinPESections.hh">
<Filter>Ryujin\Utils</Filter>
</ClInclude>
<ClInclude Include="Ryujin\RyujinCore\RyujinObfuscationCore.hh">
<Filter>Ryujin\RyujinCore</Filter>
</ClInclude>
</ItemGroup>
</Project>