feat: Start implementing the base for the "AntiDump" feature
- Begin work on the foundational structure for the "AntiDump" feature - Introduced a new capability in Ryujin called "RyujinRunOncePass", which runs only on the first obfuscated function — ideal for volatile features - Updated "RyujinCoreConfiguration" structures - Updated "RyujinGUI" to include the "AntiDump" option - Updated "RyujinConsole" to display the "AntiDump" feature - Updated "README.md" accordingly
This commit is contained in:
@@ -13,10 +13,10 @@
|
|||||||
- Random Section naming(Default name: Ryujin)
|
- Random Section naming(Default name: Ryujin)
|
||||||
- Mathematical Operators Virtualization(aka: Ryūjin MiniVM)
|
- Mathematical Operators Virtualization(aka: Ryūjin MiniVM)
|
||||||
- Obfuscated code Encryption(Using TeaDelKew Algorithm)
|
- Obfuscated code Encryption(Using TeaDelKew Algorithm)
|
||||||
- Anti-Debug User + Kernel(Planned)
|
- Anti-Debug User + Kernel
|
||||||
- Anti-Dump(Planned)
|
- Anti-Dump
|
||||||
- Anti-Disassembly(Planned)
|
- Anti-Disassembly(Planned)
|
||||||
- Troll Reversers(Exclusive Planned)
|
- Troll Reversers(Exclusive)
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ Options:
|
|||||||
--help Show this help message
|
--help Show this help message
|
||||||
|
|
||||||
In Action Usage Example:
|
In Action Usage Example:
|
||||||
RyujinConsole.exe --input C:\\Users\\Keowu\\Documents\\GitHub\\Ryujin\\compiled\\release\\DemoObfuscation.exe --pdb C:\\Users\\Keowu\\Documents\\GitHub\\Ryujin\\compiled\\release\\RyujinConsole.pdb --output C:\\Users\\Keowu\\Documents\\GitHub\\Ryujin\\compiled\\release\\DemoObfuscation.ryujin.exe --virtualize --junk --encrypt --AntiDebug --troll --procs main,sub,subadd,sum,invoke_main,__scrt_common_main,j___security_init_cookie
|
RyujinConsole.exe --input C:\\Users\\Keowu\\Documents\\GitHub\\Ryujin\\compiled\\release\\DemoObfuscation.exe --pdb C:\\Users\\Keowu\\Documents\\GitHub\\Ryujin\\compiled\\release\\RyujinConsole.pdb --output C:\\Users\\Keowu\\Documents\\GitHub\\Ryujin\\compiled\\release\\DemoObfuscation.ryujin.exe --virtualize --junk --encrypt --AntiDebug --troll --AntiDump --procs main,sub,subadd,sum,invoke_main,__scrt_common_main,j___security_init_cookie
|
||||||
|
|
||||||
)";
|
)";
|
||||||
|
|
||||||
@@ -86,6 +86,7 @@ auto main(int argc, char* argv[]) -> int {
|
|||||||
config.m_isEncryptObfuscatedCode = has_flag(args, "--encrypt");
|
config.m_isEncryptObfuscatedCode = has_flag(args, "--encrypt");
|
||||||
config.m_isTrollRerversers = has_flag(args, "--troll");
|
config.m_isTrollRerversers = has_flag(args, "--troll");
|
||||||
config.m_isAntiDebug = has_flag(args, "--AntiDebug");
|
config.m_isAntiDebug = has_flag(args, "--AntiDebug");
|
||||||
|
config.m_isAntiDump = has_flag(args, "--AntiDump");
|
||||||
|
|
||||||
if (has_flag(args, "--procs")) {
|
if (has_flag(args, "--procs")) {
|
||||||
auto rawList = args["--procs"];
|
auto rawList = args["--procs"];
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ public:
|
|||||||
bool m_isEncryptObfuscatedCode; // The user wants to encrypt all obfuscated code to avoid detection
|
bool m_isEncryptObfuscatedCode; // The user wants to encrypt all obfuscated code to avoid detection
|
||||||
bool m_isAntiDebug; // The user wants to avoid debuggers use while running a binary protected by Ryujin
|
bool m_isAntiDebug; // The user wants to avoid debuggers use while running a binary protected by Ryujin
|
||||||
bool m_isTrollRerversers; // The user wants to trick and use a special feature to troll reversers when their debugs be detected making they loose all the progress
|
bool m_isTrollRerversers; // The user wants to trick and use a special feature to troll reversers when their debugs be detected making they loose all the progress
|
||||||
|
bool m_isAntiDump; // Enable Anti Dump technic for Ryujin protected binary
|
||||||
RyujinObfuscatorProcs m_strProceduresToObfuscate; // Names of the procedures to obfuscate
|
RyujinObfuscatorProcs m_strProceduresToObfuscate; // Names of the procedures to obfuscate
|
||||||
std::vector<std::string> m_strdProceduresToObfuscate; // Names of the procedures to obfuscate
|
std::vector<std::string> m_strdProceduresToObfuscate; // Names of the procedures to obfuscate
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ public:
|
|||||||
bool m_isEncryptObfuscatedCode; // The user wants to encrypt all obfuscated code to avoid detection
|
bool m_isEncryptObfuscatedCode; // The user wants to encrypt all obfuscated code to avoid detection
|
||||||
bool m_isAntiDebug; // The user wants to avoid debuggers use while running a binary protected by Ryujin
|
bool m_isAntiDebug; // The user wants to avoid debuggers use while running a binary protected by Ryujin
|
||||||
bool m_isTrollRerversers; // The user wants to trick and use a special feature to troll reversers when their debugs be detected making they loose all the progress
|
bool m_isTrollRerversers; // The user wants to trick and use a special feature to troll reversers when their debugs be detected making they loose all the progress
|
||||||
|
bool m_isAntiDump; // Enable Anti Dump technic for Ryujin protected binary
|
||||||
RyujinObfuscatorProcs m_strProceduresToObfuscate; // Names of the procedures to obfuscate - FFI
|
RyujinObfuscatorProcs m_strProceduresToObfuscate; // Names of the procedures to obfuscate - FFI
|
||||||
std::vector<std::string> m_strdProceduresToObfuscate; // Names of the procedures to obfuscate
|
std::vector<std::string> m_strdProceduresToObfuscate; // Names of the procedures to obfuscate
|
||||||
// todo: passes
|
// todo: passes
|
||||||
|
|||||||
@@ -94,8 +94,8 @@ bool Ryujin::run(const RyujinObfuscatorConfig& config) {
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool RyujinRunOncePass{ TRUE };
|
||||||
std::vector<RyujinObfuscationCore> processed_procs;
|
std::vector<RyujinObfuscationCore> processed_procs;
|
||||||
|
|
||||||
for (auto& proc : m_ryujinProcedures) {
|
for (auto& proc : m_ryujinProcedures) {
|
||||||
|
|
||||||
auto it = std::find(config.m_strdProceduresToObfuscate.begin(), config.m_strdProceduresToObfuscate.end(), proc.name);
|
auto it = std::find(config.m_strdProceduresToObfuscate.begin(), config.m_strdProceduresToObfuscate.end(), proc.name);
|
||||||
@@ -137,7 +137,7 @@ bool Ryujin::run(const RyujinObfuscatorConfig& config) {
|
|||||||
|
|
||||||
//Is time to obfuscate ?
|
//Is time to obfuscate ?
|
||||||
RyujinObfuscationCore obc(config, proc, reinterpret_cast<uintptr_t>(m_mappedPE.get()));
|
RyujinObfuscationCore obc(config, proc, reinterpret_cast<uintptr_t>(m_mappedPE.get()));
|
||||||
obc.Run();
|
obc.Run(RyujinRunOncePass);
|
||||||
|
|
||||||
//TODO: Custom passes support
|
//TODO: Custom passes support
|
||||||
|
|
||||||
|
|||||||
@@ -1602,6 +1602,34 @@ void RyujinObfuscationCore::insertAntiDebug() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RyujinObfuscationCore::insertAntiDump() {
|
||||||
|
|
||||||
|
BOOL isInserted{ FALSE };
|
||||||
|
|
||||||
|
for (auto& block : m_proc.basic_blocks) {
|
||||||
|
|
||||||
|
for (auto& instr : block.instructions) {
|
||||||
|
|
||||||
|
if (isInserted) break;
|
||||||
|
|
||||||
|
if (!isInserted) {
|
||||||
|
|
||||||
|
auto block_info = findBlockId(instr.instruction.info.opcode, instr.instruction.operands[1].imm.value.u, 2, sizeof(unsigned char));
|
||||||
|
|
||||||
|
if (block_info.first == -1 || block_info.second == -1) continue;
|
||||||
|
|
||||||
|
auto& data = m_proc.basic_blocks[block_info.first].opcodes[block_info.second];
|
||||||
|
|
||||||
|
std::printf("RyujinObfuscationCore::insertAntiDump\n");
|
||||||
|
|
||||||
|
isInserted = TRUE;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void RyujinObfuscationCore::updateBasicBlocksContext() {
|
void RyujinObfuscationCore::updateBasicBlocksContext() {
|
||||||
|
|
||||||
auto new_obfuscated_opcodes = getProcessedProc().getUpdateOpcodes();
|
auto new_obfuscated_opcodes = getProcessedProc().getUpdateOpcodes();
|
||||||
@@ -1610,11 +1638,22 @@ void RyujinObfuscationCore::updateBasicBlocksContext() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL RyujinObfuscationCore::Run() {
|
BOOL RyujinObfuscationCore::Run(bool& RyujinRunOncePass) {
|
||||||
|
|
||||||
//Add padding spaces
|
//Add padding spaces
|
||||||
addPaddingSpaces();
|
addPaddingSpaces();
|
||||||
|
|
||||||
|
/*
|
||||||
|
RyujinRunOncePass only run once for the first function candidate to obfuscation.
|
||||||
|
this is the better place to put unique logic code that is high volatily.
|
||||||
|
*/
|
||||||
|
if (RyujinRunOncePass) {
|
||||||
|
|
||||||
|
this->insertAntiDump();
|
||||||
|
|
||||||
|
RyujinRunOncePass = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
//Update basic blocks view based on the new obfuscated
|
//Update basic blocks view based on the new obfuscated
|
||||||
this->updateBasicBlocksContext();
|
this->updateBasicBlocksContext();
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ private:
|
|||||||
void insertJunkCode();
|
void insertJunkCode();
|
||||||
void insertVirtualization();
|
void insertVirtualization();
|
||||||
void insertAntiDebug();
|
void insertAntiDebug();
|
||||||
|
void insertAntiDump();
|
||||||
std::vector<uint8_t> fix_branch_near_far_short(uint8_t original_opcode, uint64_t jmp_address, uint64_t target_address);
|
std::vector<uint8_t> fix_branch_near_far_short(uint8_t original_opcode, uint64_t jmp_address, uint64_t target_address);
|
||||||
uint32_t findOpcodeOffset(const uint8_t* data, size_t dataSize, const void* opcode, size_t opcodeSize);
|
uint32_t findOpcodeOffset(const uint8_t* data, size_t dataSize, const void* opcode, size_t opcodeSize);
|
||||||
|
|
||||||
@@ -69,7 +70,7 @@ public:
|
|||||||
void applyRelocationFixupsToInstructions(uintptr_t imageBase, DWORD virtualAddress, std::vector<unsigned char>& new_opcodes);
|
void applyRelocationFixupsToInstructions(uintptr_t imageBase, DWORD virtualAddress, std::vector<unsigned char>& new_opcodes);
|
||||||
void removeOldOpcodeRedirect(uintptr_t newMappedPE, std::size_t szMapped, uintptr_t newObfuscatedAddress, bool isIgnoreOriginalCodeRemove = false);
|
void removeOldOpcodeRedirect(uintptr_t newMappedPE, std::size_t szMapped, uintptr_t newObfuscatedAddress, bool isIgnoreOriginalCodeRemove = false);
|
||||||
void InsertMiniVmEnterProcedureAddress(uintptr_t imageBase, uintptr_t virtualAddress, std::vector<unsigned char>& new_opcodes);
|
void InsertMiniVmEnterProcedureAddress(uintptr_t imageBase, uintptr_t virtualAddress, std::vector<unsigned char>& new_opcodes);
|
||||||
BOOL Run();
|
BOOL Run(bool& RyujinRunOncePass);
|
||||||
RyujinProcedure getProcessedProc();
|
RyujinProcedure getProcessedProc();
|
||||||
~RyujinObfuscationCore();
|
~RyujinObfuscationCore();
|
||||||
|
|
||||||
|
|||||||
@@ -199,6 +199,13 @@ bool RyujinApp::OnInit() {
|
|||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
m_isAntiDump = DrawnStyledCheckbox(
|
||||||
|
|
||||||
|
panel,
|
||||||
|
"AntiDump"
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
optionsSizer->Add(
|
optionsSizer->Add(
|
||||||
|
|
||||||
m_virtualize
|
m_virtualize
|
||||||
@@ -238,6 +245,11 @@ bool RyujinApp::OnInit() {
|
|||||||
|
|
||||||
m_isAntiDebugNormal
|
m_isAntiDebugNormal
|
||||||
|
|
||||||
|
);
|
||||||
|
optionsSizer->Add(
|
||||||
|
|
||||||
|
m_isAntiDump
|
||||||
|
|
||||||
);
|
);
|
||||||
optionsBox->Add(
|
optionsBox->Add(
|
||||||
|
|
||||||
@@ -684,6 +696,7 @@ auto RyujinApp::BindRunEvent(wxFrame* frame) -> void {
|
|||||||
core.m_isJunkCode = m_junk->IsChecked();
|
core.m_isJunkCode = m_junk->IsChecked();
|
||||||
core.m_isRandomSection = m_randomSection->IsChecked();
|
core.m_isRandomSection = m_randomSection->IsChecked();
|
||||||
core.m_isVirtualized = m_virtualize->IsChecked();
|
core.m_isVirtualized = m_virtualize->IsChecked();
|
||||||
|
core.m_isAntiDump = m_isAntiDump->IsChecked();
|
||||||
|
|
||||||
if (m_isAntiDebugWithTroll->IsChecked()) {
|
if (m_isAntiDebugWithTroll->IsChecked()) {
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ private:
|
|||||||
wxCheckBox* m_ignoreOriginalCodeRemove = nullptr;
|
wxCheckBox* m_ignoreOriginalCodeRemove = nullptr;
|
||||||
wxCheckBox* m_isAntiDebugWithTroll = nullptr;
|
wxCheckBox* m_isAntiDebugWithTroll = nullptr;
|
||||||
wxCheckBox* m_isAntiDebugNormal = nullptr;
|
wxCheckBox* m_isAntiDebugNormal = nullptr;
|
||||||
|
wxCheckBox* m_isAntiDump = nullptr;
|
||||||
wxListBox* m_procList = nullptr;
|
wxListBox* m_procList = nullptr;
|
||||||
wxGauge* m_progress = nullptr;
|
wxGauge* m_progress = nullptr;
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ public:
|
|||||||
bool m_isEncryptObfuscatedCode; // The user wants to encrypt all obfuscated code to avoid detection
|
bool m_isEncryptObfuscatedCode; // The user wants to encrypt all obfuscated code to avoid detection
|
||||||
bool m_isAntiDebug; // The user wants to avoid debuggers use while running a binary protected by Ryujin
|
bool m_isAntiDebug; // The user wants to avoid debuggers use while running a binary protected by Ryujin
|
||||||
bool m_isTrollRerversers; // The user wants to trick and use a special feature to troll reversers when their debugs be detected making they loose all the progress
|
bool m_isTrollRerversers; // The user wants to trick and use a special feature to troll reversers when their debugs be detected making they loose all the progress
|
||||||
|
bool m_isAntiDump; // Enable Anti Dump technic for Ryujin protected binary
|
||||||
RyujinObfuscatorProcs m_strProceduresToObfuscate; // Names of the procedures to obfuscate - FFI
|
RyujinObfuscatorProcs m_strProceduresToObfuscate; // Names of the procedures to obfuscate - FFI
|
||||||
std::vector<std::string> m_strdProceduresToObfuscate; // Names of the procedures to obfuscate
|
std::vector<std::string> m_strdProceduresToObfuscate; // Names of the procedures to obfuscate
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user