feat: Complete RyujinConsole implementation with full CLI support

The implementation of RyujinConsole is now complete. Users can fully customize the obfuscation process using a wide range of command-line options.
- Added full command-line interface support for RyujinConsole.
- Users can now specify input and output paths, and provide a PDB file for symbol mapping.
- Supports various obfuscation techniques via flags:
  - --virtualize: Enables code virtualization.
  - --junk: Inserts junk code.
  - --encrypt: Encrypts the obfuscated code.
  - --iat: Enables Import Address Table obfuscation.
  - --random-section: Uses a randomized PE section for output.
  - --keep-original: Preserves the original code (does not remove it).
- Allows fine-grained control over which procedures to obfuscate via --procs.
- Includes a --help option that provides detailed usage information.
- Example usage is provided in the built-in help message.
This commit is contained in:
keowu
2025-06-28 20:53:53 -03:00
parent 3683e8dbba
commit b078160d6b

View File

@@ -1,36 +1,116 @@
#include <iostream>
#include <string>
#include <vector>
#include <unordered_map>
#include <algorithm>
#include <sstream>
#include <iomanip>
#include "RyujinCore.hh"
auto print_help() -> void {
auto main() -> int {
std::cout << R"(Ryujin Obfuscator CLI
std::cout << "Hello World!\n";
Usage:
RyujinConsole.exe --input <exe_path> --pdb <pdb_path> --output <output_path> [options]
Options:
--input <exe> Input binary to obfuscate (required)
--pdb <pdb> Path to the PDB file (required)
--output <exe> Output path for obfuscated binary (required)
--virtualize Enable virtualization
--junk Add junk code
--encrypt Encrypt obfuscated code
--iat Enable IAT obfuscation
--random-section Use random PE section
--keep-original Keep original code (don't remove it)
--procs <comma,separated,names> Procedures to obfuscate (default: main, invoke_main, ...)
--help Show this help message
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 --procs main,sub,subadd,sum,invoke_main,__scrt_common_main,j___security_init_cookie
)";
}
auto has_flag(const std::unordered_map<std::string, std::string>& args, const std::string& flag) -> bool {
return args.find(flag) != args.end();
}
auto parse_args(int argc, char* argv[]) -> std::unordered_map<std::string, std::string> {
std::unordered_map<std::string, std::string> options;
for (int i = 1; i < argc; ++i) {
std::string key = argv[i];
if (key.rfind("--", 0) == 0)
if (i + 1 < argc && argv[i + 1][0] != '-') options[key] = argv[++i]; else options[key] = "true"; // Flag-only
}
return options;
}
auto main(int argc, char* argv[]) -> int {
auto args = parse_args(argc, argv);
if (has_flag(args, "--help") || argc == 1) {
print_help();
return 0;
}
auto input = args["--input"];
auto pdb = args["--pdb"];
auto output = args["--output"];
if (input.empty() || pdb.empty() || output.empty()) {
std::cerr << "Error: --input, --pdb, and --output are required.\n";
print_help();
return 0;
}
RyujinObfuscatorConfig config;
config.m_isIgnoreOriginalCodeRemove = FALSE;
config.m_isJunkCode = TRUE;
config.m_isRandomSection = FALSE;
config.m_isVirtualized = TRUE;
config.m_isIatObfuscation = TRUE;
config.m_isEncryptObfuscatedCode = TRUE;
std::vector<std::string> procsToObfuscate{
config.m_isIgnoreOriginalCodeRemove = has_flag(args, "--keep-original");
config.m_isJunkCode = has_flag(args, "--junk");
config.m_isRandomSection = has_flag(args, "--random-section");
config.m_isVirtualized = has_flag(args, "--virtualize");
config.m_isIatObfuscation = has_flag(args, "--iat");
config.m_isEncryptObfuscatedCode = has_flag(args, "--encrypt");
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));
start = end + 1;
}
procsToObfuscate.push_back(rawList.substr(start));
}
else {
print_help();
return 0;
}
"sum",
"sub",
"subadd",
"main",
"invoke_main"
"__scrt_common_main",
"j___security_init_cookie"
};
config.m_strProceduresToObfuscate.assign(procsToObfuscate.begin(), procsToObfuscate.end());
auto bSuccess = config.RunRyujin("C:\\Users\\Keowu\\Documents\\GitHub\\Ryujin\\compiled\\release\\DemoObfuscation.exe", "C:\\Users\\Keowu\\Documents\\GitHub\\Ryujin\\compiled\\release\\DemoObfuscation.pdb", "C:\\Users\\Keowu\\Documents\\GitHub\\Ryujin\\compiled\\release\\DemoObfuscation.obfuscated.exe", config);
auto bSuccess = config.RunRyujin(input, pdb, output, config);
std::printf("Ryujin core returned: %d\n", bSuccess);
std::cin.get();
return 0;
}
return bSuccess;
}