feat: Begin working on Ryuujin core
- Working on obfuscated core - Optimizing Ryuujin
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
#pragma once;
|
||||
|
||||
struct RyujinInstruction {
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#pragma once
|
||||
#include <string>
|
||||
|
||||
class RyujinObfuscatorConfig {
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
};
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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() {
|
||||
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
};
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
Reference in New Issue
Block a user