feat: MSVC optimization bug fixes, FFI standard support, and Anti-Debug options in RyujinGui

- Fixed a bug related to MSVC optimizations that broke Ryujin's relocation algorithm and its fix-up logic.
- Introduced a standardized FFI argument-passing method for Ryujin Core; the legacy method remains compatible.
- Ryujin GUI now fully supports the Anti-Debug features.
- Various minor bug fixes and improvements to project structure.
This commit is contained in:
keowu
2025-07-10 20:55:39 -03:00
parent d6caf05940
commit a96d97b9b0
14 changed files with 194 additions and 67 deletions

View File

@@ -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

View File

@@ -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<std::string> 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);

View File

@@ -3,6 +3,14 @@
#include <Windows.h>
#include <string>
#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<std::string> 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<std::string> 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);
}
};
};