diff --git a/RyujinConsole/Ryujin Protector.sln b/RyujinConsole/Ryujin Protector.sln index 903ce91..0b8acfe 100644 --- a/RyujinConsole/Ryujin Protector.sln +++ b/RyujinConsole/Ryujin Protector.sln @@ -7,7 +7,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RyujinConsole", "RyujinCons EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RyujinCore", "..\RyujinCore\RyujinCore.vcxproj", "{AEFF626B-1317-4C8F-94B3-B3D405AE65B2}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RyujinGUI", "..\RyujinGUI\RyujinGUI.vcxproj", "{FDD2BEA6-E750-4F6E-86D3-98973C261D75}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RyujinGUI", "..\RyujinGUI\RyujinGUI.vcxproj", "{04712D9F-1C08-4605-B938-1EC74F2B0ACF}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -29,18 +29,18 @@ Global {AEFF626B-1317-4C8F-94B3-B3D405AE65B2}.Debug|x64.Build.0 = Debug|x64 {AEFF626B-1317-4C8F-94B3-B3D405AE65B2}.Debug|x86.ActiveCfg = Debug|Win32 {AEFF626B-1317-4C8F-94B3-B3D405AE65B2}.Debug|x86.Build.0 = Debug|Win32 - {AEFF626B-1317-4C8F-94B3-B3D405AE65B2}.Release|x64.ActiveCfg = Release|x64 - {AEFF626B-1317-4C8F-94B3-B3D405AE65B2}.Release|x64.Build.0 = Release|x64 + {AEFF626B-1317-4C8F-94B3-B3D405AE65B2}.Release|x64.ActiveCfg = Debug|x64 + {AEFF626B-1317-4C8F-94B3-B3D405AE65B2}.Release|x64.Build.0 = Debug|x64 {AEFF626B-1317-4C8F-94B3-B3D405AE65B2}.Release|x86.ActiveCfg = Release|Win32 {AEFF626B-1317-4C8F-94B3-B3D405AE65B2}.Release|x86.Build.0 = Release|Win32 - {FDD2BEA6-E750-4F6E-86D3-98973C261D75}.Debug|x64.ActiveCfg = Debug|x64 - {FDD2BEA6-E750-4F6E-86D3-98973C261D75}.Debug|x64.Build.0 = Debug|x64 - {FDD2BEA6-E750-4F6E-86D3-98973C261D75}.Debug|x86.ActiveCfg = Debug|Win32 - {FDD2BEA6-E750-4F6E-86D3-98973C261D75}.Debug|x86.Build.0 = Debug|Win32 - {FDD2BEA6-E750-4F6E-86D3-98973C261D75}.Release|x64.ActiveCfg = Release|x64 - {FDD2BEA6-E750-4F6E-86D3-98973C261D75}.Release|x64.Build.0 = Release|x64 - {FDD2BEA6-E750-4F6E-86D3-98973C261D75}.Release|x86.ActiveCfg = Release|Win32 - {FDD2BEA6-E750-4F6E-86D3-98973C261D75}.Release|x86.Build.0 = Release|Win32 + {04712D9F-1C08-4605-B938-1EC74F2B0ACF}.Debug|x64.ActiveCfg = Debug|x64 + {04712D9F-1C08-4605-B938-1EC74F2B0ACF}.Debug|x64.Build.0 = Debug|x64 + {04712D9F-1C08-4605-B938-1EC74F2B0ACF}.Debug|x86.ActiveCfg = Debug|Win32 + {04712D9F-1C08-4605-B938-1EC74F2B0ACF}.Debug|x86.Build.0 = Debug|Win32 + {04712D9F-1C08-4605-B938-1EC74F2B0ACF}.Release|x64.ActiveCfg = Release|x64 + {04712D9F-1C08-4605-B938-1EC74F2B0ACF}.Release|x64.Build.0 = Release|x64 + {04712D9F-1C08-4605-B938-1EC74F2B0ACF}.Release|x86.ActiveCfg = Release|Win32 + {04712D9F-1C08-4605-B938-1EC74F2B0ACF}.Release|x86.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/RyujinConsole/RyujinConsole/RyujinConsole.cc b/RyujinConsole/RyujinConsole/RyujinConsole.cc index fe9763c..3fa5b36 100644 --- a/RyujinConsole/RyujinConsole/RyujinConsole.cc +++ b/RyujinConsole/RyujinConsole/RyujinConsole.cc @@ -87,30 +87,32 @@ auto main(int argc, char* argv[]) -> int { config.m_isTrollRerversers = has_flag(args, "--troll"); config.m_isAntiDebug = has_flag(args, "--AntiDebug"); - std::vector procsToObfuscate; if (has_flag(args, "--procs")) { - auto rawList = args["--procs"]; size_t start = 0; size_t end = 0; - while ((end = rawList.find(',', start)) != std::string::npos) { - - procsToObfuscate.push_back(rawList.substr(start, end - start)); + int index = 0; + + while ((end = rawList.find(',', start)) != std::string::npos && index < MAX_PROCEDURES) { + auto procName = rawList.substr(start, end - start); + strncpy_s(config.m_strProceduresToObfuscate.procedures[index], procName.c_str(), MAX_PROCEDURE_NAME_LEN - 1); + ++index; start = end + 1; - } - - procsToObfuscate.push_back(rawList.substr(start)); + + if (index < MAX_PROCEDURES) { + auto procName = rawList.substr(start); + strncpy_s(config.m_strProceduresToObfuscate.procedures[index], procName.c_str(), MAX_PROCEDURE_NAME_LEN - 1); + ++index; + } + + config.m_strProceduresToObfuscate.procedureCount = index; } else { - print_help(); - return 0; } - config.m_strProceduresToObfuscate.assign(procsToObfuscate.begin(), procsToObfuscate.end()); - auto bSuccess = config.RunRyujin(input, pdb, output, config); std::printf("Ryujin core returned: %d\n", bSuccess); diff --git a/RyujinConsole/RyujinConsole/RyujinCore.hh b/RyujinConsole/RyujinConsole/RyujinCore.hh index d136790..d3e28fd 100644 --- a/RyujinConsole/RyujinConsole/RyujinCore.hh +++ b/RyujinConsole/RyujinConsole/RyujinCore.hh @@ -3,6 +3,14 @@ #include #include +#define MAX_PROCEDURES 128 +#define MAX_PROCEDURE_NAME_LEN 128 + +struct RyujinObfuscatorProcs { + int procedureCount; + char procedures[MAX_PROCEDURES][MAX_PROCEDURE_NAME_LEN]; +}; + class RyujinObfuscatorConfig { public: @@ -12,13 +20,14 @@ public: bool m_isJunkCode; // Insert junk code to confuse bool m_isIgnoreOriginalCodeRemove; // Do not remove the original code after processing (replace the original instructions with NOPs) 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_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 - std::vector m_strProceduresToObfuscate; // Names of the procedures to obfuscate + 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 + RyujinObfuscatorProcs m_strProceduresToObfuscate; // Names of the procedures to obfuscate + std::vector m_strdProceduresToObfuscate; // Names of the procedures to obfuscate - bool RunRyujin(const std::string& strInputFilePath, const std::string& strPdbFilePath, const std::string& strOutputFilePath, RyujinObfuscatorConfig& config) { + static bool RunRyujin(const std::string& strInputFilePath, const std::string& strPdbFilePath, const std::string& strOutputFilePath, RyujinObfuscatorConfig& config) { - using tpdRunRyujinCore = BOOL(__stdcall*)(const std::string& strInputFilePath, const std::string& strPdbFilePath, const std::string& strOutputFilePath, RyujinObfuscatorConfig& config); + using tpdRunRyujinCore = BOOL(__stdcall*)(const char*, const char*, const char*, RyujinObfuscatorConfig&); auto hModule = LoadLibraryW(L"RyujinCore.dll"); @@ -28,7 +37,7 @@ public: if (!RunRyujinCore) return FALSE; - return RunRyujinCore(strInputFilePath, strPdbFilePath, strOutputFilePath, config); + return RunRyujinCore(strInputFilePath.c_str(), strPdbFilePath.c_str(), strOutputFilePath.c_str(), config); } -}; +}; \ No newline at end of file diff --git a/RyujinCore/Ryujin.def b/RyujinCore/Ryujin.def index 480a89e..45a71c9 100644 --- a/RyujinCore/Ryujin.def +++ b/RyujinCore/Ryujin.def @@ -1,3 +1,3 @@ LIBRARY RyujinObfuscator EXPORTS - RunRyujinCore = ?RunRyujinCore@@YAHAEBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@00AEAVRyujinObfuscatorConfig@@@Z \ No newline at end of file + RunRyujinCore = ?RunRyujinCore@@YAHPEBD00AEAVRyujinObfuscatorConfig@@@Z \ No newline at end of file diff --git a/RyujinCore/Ryujin/Models/RyujinObfuscatorConfig.hh b/RyujinCore/Ryujin/Models/RyujinObfuscatorConfig.hh index 75cf1f5..a303bad 100644 --- a/RyujinCore/Ryujin/Models/RyujinObfuscatorConfig.hh +++ b/RyujinCore/Ryujin/Models/RyujinObfuscatorConfig.hh @@ -1,18 +1,27 @@ #pragma once #include +#define MAX_PROCEDURES 128 +#define MAX_PROCEDURE_NAME_LEN 128 + +struct RyujinObfuscatorProcs { + int procedureCount; + char procedures[MAX_PROCEDURES][MAX_PROCEDURE_NAME_LEN]; +}; + class RyujinObfuscatorConfig { public: - bool m_isRandomSection; // Randomize the name of the new section with the processed code -> ".Ryujin" standard - bool m_isVirtualized; // Virtualize the code [Try as much as possible] - bool m_isIatObfuscation; //Process IAT Obfuscation - bool m_isJunkCode; // Insert junk code to confuse - bool m_isIgnoreOriginalCodeRemove; // Do not remove the original code after processing (replace the original instructions with NOPs) - 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_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 - std::vector m_strProceduresToObfuscate; // Names of the procedures to obfuscate + bool m_isRandomSection; // Randomize the name of the new section with the processed code -> ".Ryujin" standard + bool m_isVirtualized; // Virtualize the code [Try as much as possible] + bool m_isIatObfuscation; //Process IAT Obfuscation + bool m_isJunkCode; // Insert junk code to confuse + bool m_isIgnoreOriginalCodeRemove; // Do not remove the original code after processing (replace the original instructions with NOPs) + 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_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 + RyujinObfuscatorProcs m_strProceduresToObfuscate; // Names of the procedures to obfuscate - FFI + std::vector m_strdProceduresToObfuscate; // Names of the procedures to obfuscate // todo: passes }; \ No newline at end of file diff --git a/RyujinCore/Ryujin/Ryujin.cc b/RyujinCore/Ryujin/Ryujin.cc index b01665e..5cb8d1a 100644 --- a/RyujinCore/Ryujin/Ryujin.cc +++ b/RyujinCore/Ryujin/Ryujin.cc @@ -83,7 +83,7 @@ bool Ryujin::run(const RyujinObfuscatorConfig& config) { return FALSE; } - if (config.m_strProceduresToObfuscate.size() == 0) { + if (config.m_strdProceduresToObfuscate.size() == 0) { ::OutputDebugStringA( @@ -98,9 +98,9 @@ bool Ryujin::run(const RyujinObfuscatorConfig& config) { 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_strdProceduresToObfuscate.begin(), config.m_strdProceduresToObfuscate.end(), proc.name); - if (it == config.m_strProceduresToObfuscate.end()) continue; + if (it == config.m_strdProceduresToObfuscate.end()) continue; std::printf( diff --git a/RyujinCore/Ryujin/RyujinCore/RyujinObfuscationCore.hh b/RyujinCore/Ryujin/RyujinCore/RyujinObfuscationCore.hh index aa04bee..bf3b85a 100644 --- a/RyujinCore/Ryujin/RyujinCore/RyujinObfuscationCore.hh +++ b/RyujinCore/Ryujin/RyujinCore/RyujinObfuscationCore.hh @@ -16,7 +16,7 @@ class RyujinObfuscationCore { private: - const int MAX_PADDING_SPACE_INSTR = 13; + const int MAX_PADDING_SPACE_INSTR = 14; const int MAX_JUNK_GENERATION_ITERATION = 5; std::vector m_unusedRegisters; std::vector m_obfuscated_bb; diff --git a/RyujinCore/RyujinCore.cc b/RyujinCore/RyujinCore.cc index 6626751..494c3b0 100644 --- a/RyujinCore/RyujinCore.cc +++ b/RyujinCore/RyujinCore.cc @@ -1,6 +1,25 @@ #include "RyujinCore.hh" -RYUJINCORE_API BOOL __stdcall RunRyujinCore(const std::string& strInputFilePath, const std::string& strPdbFilePath, const std::string& strOutputFilePath, RyujinObfuscatorConfig& config) { +/* + Disable all optimizations before compile for release - MSVC sucks - Build ryujincore in debug or use contexpr mainly on fix relocs +*/ + +RYUJINCORE_API BOOL __stdcall RunRyujinCore(const char* strInputFilePath, const char* strPdbFilePath, const char* strOutputFilePath, RyujinObfuscatorConfig& config) { + + if (!strInputFilePath || !strPdbFilePath || !strOutputFilePath) return FALSE; + + if (config.m_strdProceduresToObfuscate.empty()) { + + std::vector strProcsProcessed; + + strProcsProcessed.reserve(config.m_strProceduresToObfuscate.procedureCount); + + for (int i = 0; i < config.m_strProceduresToObfuscate.procedureCount; ++i) + strProcsProcessed.emplace_back(config.m_strProceduresToObfuscate.procedures[i]); + + config.m_strdProceduresToObfuscate.assign(strProcsProcessed.begin(), strProcsProcessed.end()); + + } std::unique_ptr ryujin = std::make_unique(strInputFilePath, strPdbFilePath, strOutputFilePath); diff --git a/RyujinCore/RyujinCore.hh b/RyujinCore/RyujinCore.hh index f25e3ae..a8ece7c 100644 --- a/RyujinCore/RyujinCore.hh +++ b/RyujinCore/RyujinCore.hh @@ -5,4 +5,4 @@ #endif #include "Ryujin/Ryujin.hh" -RYUJINCORE_API BOOL __stdcall RunRyujinCore(const std::string& strInputFilePath, const std::string& strPdbFilePath, const std::string& strOutputFilePath, RyujinObfuscatorConfig &config); +RYUJINCORE_API BOOL __stdcall RunRyujinCore(const char* strInputFilePath, const char* strPdbFilePath, const char* strOutputFilePath, RyujinObfuscatorConfig &config); diff --git a/RyujinCore/RyujinCore.vcxproj b/RyujinCore/RyujinCore.vcxproj index 88392a5..4f03177 100644 --- a/RyujinCore/RyujinCore.vcxproj +++ b/RyujinCore/RyujinCore.vcxproj @@ -94,6 +94,7 @@ true NotUsing pch.h + Disabled Windows @@ -106,20 +107,28 @@ Level3 true - true + false true WIN32;NDEBUG;RYUJINCORE_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) true NotUsing pch.h + Disabled + false + Disabled + Async + MultiThreadedDebug Windows - true - true + + + + true false Ryujin.def + @@ -130,6 +139,8 @@ true NotUsing pch.h + false + Disabled Windows @@ -142,20 +153,29 @@ Level3 true - true + false true NDEBUG;RYUJINCORE_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) true NotUsing pch.h + Disabled + false + false + Disabled + Async + MultiThreadedDebug Windows - true - true + + + + true false Ryujin.def + diff --git a/RyujinGUI/RyujinApp.cc b/RyujinGUI/RyujinApp.cc index 176d2f0..d6ec10b 100644 --- a/RyujinGUI/RyujinApp.cc +++ b/RyujinGUI/RyujinApp.cc @@ -185,6 +185,20 @@ bool RyujinApp::OnInit() { ); + m_isAntiDebugWithTroll = DrawnStyledCheckbox( + + panel, + "Antidebug(User + Kernel) + Troll Reversers" + + ); + + m_isAntiDebugNormal = DrawnStyledCheckbox( + + panel, + "Antidebug(User + Kernel) + Terminate" + + ); + optionsSizer->Add( m_virtualize @@ -214,6 +228,16 @@ bool RyujinApp::OnInit() { m_ignoreOriginalCodeRemove + ); + optionsSizer->Add( + + m_isAntiDebugWithTroll + + ); + optionsSizer->Add( + + m_isAntiDebugNormal + ); optionsBox->Add( @@ -661,20 +685,49 @@ auto RyujinApp::BindRunEvent(wxFrame* frame) -> void { core.m_isRandomSection = m_randomSection->IsChecked(); core.m_isVirtualized = m_virtualize->IsChecked(); - // Procedures to obfuscate - std::vector procsToObfuscate; - auto count = m_procList->GetCount(); - procsToObfuscate.reserve(count); + if (m_isAntiDebugWithTroll->IsChecked()) { - for (auto i = 0; i < count; ++i) { - - auto item = m_procList->GetString(i); - procsToObfuscate.push_back(item.ToStdString()); + core.m_isAntiDebug = TRUE; + core.m_isTrollRerversers = TRUE; - } - core.m_strProceduresToObfuscate.assign(procsToObfuscate.begin(), procsToObfuscate.end()); + } + + if (m_isAntiDebugNormal->IsChecked()) { - auto bSuccess = core.RunRyujin(m_input->GetValue().ToStdString(), m_pdb->GetValue().ToStdString(), m_output->GetValue().ToStdString(), core); + core.m_isAntiDebug = TRUE; + core.m_isTrollRerversers = FALSE; + + } + + auto count = m_procList->GetCount(); + int index = 0; + for (auto i = 0; i < count && index < MAX_PROCEDURES; ++i) { + + auto item = m_procList->GetString(i).ToStdString(); + + if (!item.empty()) { + + strncpy_s( + + core.m_strProceduresToObfuscate.procedures[index], + item.c_str(), + MAX_PROCEDURE_NAME_LEN - 1 + + ); + + ++index; + + } + + } + + core.m_strProceduresToObfuscate.procedureCount = index; + + std::string input = m_input->GetValue().ToStdString(); + std::string pdb = m_pdb->GetValue().ToStdString(); + std::string output = m_output->GetValue().ToStdString(); + + auto bSuccess = core.RunRyujin(input, pdb, output, core); frame->CallAfter([=]() { diff --git a/RyujinGUI/RyujinApp.hh b/RyujinGUI/RyujinApp.hh index 4d76074..337b936 100644 --- a/RyujinGUI/RyujinApp.hh +++ b/RyujinGUI/RyujinApp.hh @@ -20,6 +20,8 @@ private: wxCheckBox* m_randomSection = nullptr; wxCheckBox* m_obfuscateIat = nullptr; wxCheckBox* m_ignoreOriginalCodeRemove = nullptr; + wxCheckBox* m_isAntiDebugWithTroll = nullptr; + wxCheckBox* m_isAntiDebugNormal = nullptr; wxListBox* m_procList = nullptr; wxGauge* m_progress = nullptr; diff --git a/RyujinGUI/RyujinCore.hh b/RyujinGUI/RyujinCore.hh index ba70975..05be5af 100644 --- a/RyujinGUI/RyujinCore.hh +++ b/RyujinGUI/RyujinCore.hh @@ -3,6 +3,14 @@ #include #include +#define MAX_PROCEDURES 128 +#define MAX_PROCEDURE_NAME_LEN 128 + +struct RyujinObfuscatorProcs { + int procedureCount; + char procedures[MAX_PROCEDURES][MAX_PROCEDURE_NAME_LEN]; +}; + class RyujinObfuscatorConfig { public: @@ -12,11 +20,14 @@ public: bool m_isJunkCode; // Insert junk code to confuse bool m_isIgnoreOriginalCodeRemove; // Do not remove the original code after processing (replace the original instructions with NOPs) bool m_isEncryptObfuscatedCode; // The user wants to encrypt all obfuscated code to avoid detection - std::vector m_strProceduresToObfuscate; // Names of the procedures to obfuscate + 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 + RyujinObfuscatorProcs m_strProceduresToObfuscate; // Names of the procedures to obfuscate - FFI + std::vector m_strdProceduresToObfuscate; // Names of the procedures to obfuscate - bool RunRyujin(const std::string& strInputFilePath, const std::string& strPdbFilePath, const std::string& strOutputFilePath, RyujinObfuscatorConfig& config) { + static bool RunRyujin(const std::string& strInputFilePath, const std::string& strPdbFilePath, const std::string& strOutputFilePath, RyujinObfuscatorConfig& config) { - using tpdRunRyujinCore = BOOL(__stdcall*)(const std::string& strInputFilePath, const std::string& strPdbFilePath, const std::string& strOutputFilePath, RyujinObfuscatorConfig& config); + using tpdRunRyujinCore = BOOL(__stdcall*)(const char*, const char*, const char*, RyujinObfuscatorConfig&); auto hModule = LoadLibraryW(L"RyujinCore.dll"); @@ -26,7 +37,7 @@ public: if (!RunRyujinCore) return FALSE; - return RunRyujinCore(strInputFilePath, strPdbFilePath, strOutputFilePath, config); + return RunRyujinCore(strInputFilePath.c_str(), strPdbFilePath.c_str(), strOutputFilePath.c_str(), config); } }; diff --git a/RyujinGUI/RyujinGUI.vcxproj b/RyujinGUI/RyujinGUI.vcxproj index f3164b0..8843dea 100644 --- a/RyujinGUI/RyujinGUI.vcxproj +++ b/RyujinGUI/RyujinGUI.vcxproj @@ -106,6 +106,7 @@ WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true $(WXWIN)\include\msvc;$(WXWIN)\include;%(AdditionalIncludeDirectories) + Disabled Windows @@ -140,6 +141,7 @@ NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true $(WXWIN)\include\msvc;$(WXWIN)\include;%(AdditionalIncludeDirectories) + Disabled Windows