feat: Ryujin Basic Blocks, Opcode extractor and disassembler.
- Working on Ryujin Basic Block parsing feature. - Opcodes Extractor. - Disassembler. - Fixing some bugs when printing names.
This commit is contained in:
@@ -91,13 +91,13 @@ bool Ryujin::run(const RyujinObfuscatorConfig& config) {
|
|||||||
return FALSE;
|
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);
|
auto it = std::find(config.m_strProceduresToObfuscate.begin(), config.m_strProceduresToObfuscate.end(), proc.name);
|
||||||
|
|
||||||
if (it == config.m_strProceduresToObfuscate.end()) continue;
|
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 ?
|
// Is a valid procedure ?
|
||||||
if (proc.size == 0) {
|
if (proc.size == 0) {
|
||||||
@@ -111,8 +111,22 @@ bool Ryujin::run(const RyujinObfuscatorConfig& config) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Create basic blocks
|
//Get procedure opcodes from mapped pe file
|
||||||
|
auto ucOpcodes = new unsigned char[proc.size] { 0 };
|
||||||
|
std::memcpy(
|
||||||
|
|
||||||
|
ucOpcodes,
|
||||||
|
reinterpret_cast<void*>(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;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
#include "PDB/RyujinPdbParsing.hh"
|
#include "PDB/RyujinPdbParsing.hh"
|
||||||
#include "Utils/RyujinUtils.hh"
|
#include "Utils/RyujinUtils.hh"
|
||||||
#include "Models/RyujinObfuscatorConfig.hh"
|
#include "Models/RyujinObfuscatorConfig.hh"
|
||||||
|
#include "RyujinCore/BasicBlockerBuilder.hh"
|
||||||
|
|
||||||
class Ryujin {
|
class Ryujin {
|
||||||
|
|
||||||
|
|||||||
@@ -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<RyujinBasicBlock> RyujinBasicBlockerBuilder::createBasicBlocks(const unsigned char* chOpcode, size_t szOpcode, uintptr_t start_address) {
|
||||||
|
|
||||||
|
std::vector<RyujinBasicBlock> 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;
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <Zydis/Zydis.h>
|
||||||
|
#include <Zydis/SharedTypes.h>
|
||||||
|
#include <vector>
|
||||||
|
#include "../Models/RyujinBasicBlock.hh"
|
||||||
|
|
||||||
|
class RyujinBasicBlockerBuilder {
|
||||||
|
|
||||||
|
private:
|
||||||
|
ZydisDecoder decoder;
|
||||||
|
bool isControlFlow(const ZydisDecodedInstruction& instruction) const;
|
||||||
|
|
||||||
|
public:
|
||||||
|
RyujinBasicBlockerBuilder(ZydisMachineMode machine, ZydisStackWidth stack);
|
||||||
|
std::vector<RyujinBasicBlock> createBasicBlocks(const unsigned char* chOpcode, size_t szOpcode, uintptr_t start_address);
|
||||||
|
|
||||||
|
};
|
||||||
@@ -133,6 +133,7 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="RyujinConsole.cc" />
|
<ClCompile Include="RyujinConsole.cc" />
|
||||||
<ClCompile Include="Ryujin\Ryujin.cc" />
|
<ClCompile Include="Ryujin\Ryujin.cc" />
|
||||||
|
<ClCompile Include="Ryujin\RyujinCore\BasicBlockerBuilder.cc" />
|
||||||
<ClCompile Include="Ryujin\Utils\RyujinUtils.cc" />
|
<ClCompile Include="Ryujin\Utils\RyujinUtils.cc" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -142,6 +143,7 @@
|
|||||||
<ClInclude Include="Ryujin\Models\RyujinProcedure.hh" />
|
<ClInclude Include="Ryujin\Models\RyujinProcedure.hh" />
|
||||||
<ClInclude Include="Ryujin\PDB\RyujinPdbParsing.hh" />
|
<ClInclude Include="Ryujin\PDB\RyujinPdbParsing.hh" />
|
||||||
<ClInclude Include="Ryujin\Ryujin.hh" />
|
<ClInclude Include="Ryujin\Ryujin.hh" />
|
||||||
|
<ClInclude Include="Ryujin\RyujinCore\BasicBlockerBuilder.hh" />
|
||||||
<ClInclude Include="Ryujin\Utils\RyujinUtils.hh" />
|
<ClInclude Include="Ryujin\Utils\RyujinUtils.hh" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
|||||||
@@ -25,6 +25,9 @@
|
|||||||
<Filter Include="Ryujin\Models">
|
<Filter Include="Ryujin\Models">
|
||||||
<UniqueIdentifier>{df02e440-42fd-4d5d-ace9-62fb1891e33c}</UniqueIdentifier>
|
<UniqueIdentifier>{df02e440-42fd-4d5d-ace9-62fb1891e33c}</UniqueIdentifier>
|
||||||
</Filter>
|
</Filter>
|
||||||
|
<Filter Include="Ryujin\RyujinCore">
|
||||||
|
<UniqueIdentifier>{cc8cdc69-0dce-4cc2-9b0d-6bba400b9599}</UniqueIdentifier>
|
||||||
|
</Filter>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="Ryujin\Utils\RyujinUtils.cc">
|
<ClCompile Include="Ryujin\Utils\RyujinUtils.cc">
|
||||||
@@ -36,6 +39,9 @@
|
|||||||
<ClCompile Include="RyujinConsole.cc">
|
<ClCompile Include="RyujinConsole.cc">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="Ryujin\RyujinCore\BasicBlockerBuilder.cc">
|
||||||
|
<Filter>Ryujin\RyujinCore</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="Ryujin\Models\RyujinBasicBlock.hh">
|
<ClInclude Include="Ryujin\Models\RyujinBasicBlock.hh">
|
||||||
@@ -59,5 +65,8 @@
|
|||||||
<ClInclude Include="Ryujin\Ryujin.hh">
|
<ClInclude Include="Ryujin\Ryujin.hh">
|
||||||
<Filter>Ryujin</Filter>
|
<Filter>Ryujin</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="Ryujin\RyujinCore\BasicBlockerBuilder.hh">
|
||||||
|
<Filter>Ryujin\RyujinCore</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
Reference in New Issue
Block a user