From 0c0f330ae2e4abefef1409df4783e8528786ff35 Mon Sep 17 00:00:00 2001 From: Fufu <49839857+Fufu-btw@users.noreply.github.com> Date: Wed, 10 Jun 2026 12:21:29 +0200 Subject: [PATCH] Implementing ROR13 feature (#2539) --- src/core/config/Categories.json | 2 + src/core/operations/ROR13.mjs | 83 ++++++++++++++++++++++++++++++++ tests/operations/tests/ROR13.mjs | 45 +++++++++++++++++ 3 files changed, 130 insertions(+) create mode 100644 src/core/operations/ROR13.mjs create mode 100644 tests/operations/tests/ROR13.mjs diff --git a/src/core/config/Categories.json b/src/core/config/Categories.json index d3e7648a..ceecd005 100644 --- a/src/core/config/Categories.json +++ b/src/core/config/Categories.json @@ -119,6 +119,7 @@ "GOST Verify", "GOST Key Wrap", "GOST Key Unwrap", + "ROR13", "ROT13", "ROT13 Brute Force", "ROT47", @@ -240,6 +241,7 @@ "Bit shift right", "Rotate left", "Rotate right", + "ROR13", "ROT13", "ROT8000" ] diff --git a/src/core/operations/ROR13.mjs b/src/core/operations/ROR13.mjs new file mode 100644 index 00000000..ccaa5beb --- /dev/null +++ b/src/core/operations/ROR13.mjs @@ -0,0 +1,83 @@ +/** + * ROR13 Hash operation (Windows API hashing convention) + * @author fufu_btw + * @license Apache-2.0 + */ + +import Operation from "../Operation.mjs"; + +/** + * Implements a ROR13 hash used for API name hashing techniques. + */ +class ROR13 extends Operation { + + /** + * Constructor + */ + constructor() { + super(); + + this.name = "ROR13"; + this.module = "Default"; + this.description = "Computes a ROR13 hash used in API hashing techniques."; + this.infoURL = ""; + this.inputType = "byteArray"; + this.outputType = "string"; + + this.args = []; + } + + /** + * Rotate right (32-bit) + * + * @param {number} value - input value + * @param {number} bits - rotation bits + * @returns {number} rotated value + */ + ror(value, bits) { + return ((value >>> bits) | (value << (32 - bits))) >>> 0; + } + + /** + * Execute ROR13 hash + * + * @param {byteArray} input - input bytes + * @param {Object[]} args - operation arguments + * @returns {string} hex hash + */ + run(input, args) { + let hash = 0; + + for (let i = 0; i < input.length; i++) { + const chr = input[i] & 0xFF; + hash = this.ror(hash, 13); + hash = (hash + chr) >>> 0; + } + + return "0x" + hash.toString(16).padStart(8, "0").toUpperCase(); + } + + /** + * Highlight input + * + * @param {Object[]} pos + * @param {Object[]} args + * @returns {Object[]} + */ + highlight(pos, args) { + return pos; + } + + /** + * Reverse highlight + * + * @param {Object[]} pos + * @param {Object[]} args + * @returns {Object[]} + */ + highlightReverse(pos, args) { + return pos; + } +} + +export default ROR13; diff --git a/tests/operations/tests/ROR13.mjs b/tests/operations/tests/ROR13.mjs new file mode 100644 index 00000000..18b50c27 --- /dev/null +++ b/tests/operations/tests/ROR13.mjs @@ -0,0 +1,45 @@ +/** + * ROR13 tests. + * + * @author fufu_btw [contact@fufu.red] + * @copyright Crown Copyright 2026 + * @license Apache-2.0 + */ +import TestRegister from "../../lib/TestRegister.mjs"; + + +TestRegister.addTests([ + { + name: "ROR13: AddConsoleAliasW", + input: "AddConsoleAliasW", + expectedOutput: "0x9916128C", + recipeConfig: [ + { + op: "ROR13", + args: [] + }, + ], + }, + { + name: "ROR13 Hash: LoadLibraryA", + input: "LoadLibraryA", + expectedOutput: "0xEC0E4E8E", + recipeConfig: [ + { + op: "ROR13", + args: [] + }, + ], + }, + { + name: "ROR13 Hash: CloseHandle", + input: "CloseHandle", + expectedOutput: "0x0FFD97FB", + recipeConfig: [ + { + op: "ROR13", + args: [] + }, + ], + }, +]);