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;
|
||||
}
|
||||
|
||||
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<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 "Utils/RyujinUtils.hh"
|
||||
#include "Models/RyujinObfuscatorConfig.hh"
|
||||
#include "RyujinCore/BasicBlockerBuilder.hh"
|
||||
|
||||
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>
|
||||
<ClCompile Include="RyujinConsole.cc" />
|
||||
<ClCompile Include="Ryujin\Ryujin.cc" />
|
||||
<ClCompile Include="Ryujin\RyujinCore\BasicBlockerBuilder.cc" />
|
||||
<ClCompile Include="Ryujin\Utils\RyujinUtils.cc" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
@@ -142,6 +143,7 @@
|
||||
<ClInclude Include="Ryujin\Models\RyujinProcedure.hh" />
|
||||
<ClInclude Include="Ryujin\PDB\RyujinPdbParsing.hh" />
|
||||
<ClInclude Include="Ryujin\Ryujin.hh" />
|
||||
<ClInclude Include="Ryujin\RyujinCore\BasicBlockerBuilder.hh" />
|
||||
<ClInclude Include="Ryujin\Utils\RyujinUtils.hh" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
|
||||
@@ -25,6 +25,9 @@
|
||||
<Filter Include="Ryujin\Models">
|
||||
<UniqueIdentifier>{df02e440-42fd-4d5d-ace9-62fb1891e33c}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Ryujin\RyujinCore">
|
||||
<UniqueIdentifier>{cc8cdc69-0dce-4cc2-9b0d-6bba400b9599}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Ryujin\Utils\RyujinUtils.cc">
|
||||
@@ -36,6 +39,9 @@
|
||||
<ClCompile Include="RyujinConsole.cc">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Ryujin\RyujinCore\BasicBlockerBuilder.cc">
|
||||
<Filter>Ryujin\RyujinCore</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Ryujin\Models\RyujinBasicBlock.hh">
|
||||
@@ -59,5 +65,8 @@
|
||||
<ClInclude Include="Ryujin\Ryujin.hh">
|
||||
<Filter>Ryujin</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Ryujin\RyujinCore\BasicBlockerBuilder.hh">
|
||||
<Filter>Ryujin\RyujinCore</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
Reference in New Issue
Block a user