mirror of
https://github.com/gchq/CyberChef
synced 2025-12-05 23:53:27 +00:00
Compare commits
21 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bd1790b692 | ||
|
|
90763dee6a | ||
|
|
2afd23fcf7 | ||
|
|
39fd0f9b34 | ||
|
|
ee57a92daa | ||
|
|
ab7cc878c3 | ||
|
|
877ab57f0a | ||
|
|
e2ac297102 | ||
|
|
b86dceb3c6 | ||
|
|
35c9dca955 | ||
|
|
d54d7011d9 | ||
|
|
392652ed8e | ||
|
|
7557e1e9e5 | ||
|
|
d924da2f25 | ||
|
|
be4d1eabaa | ||
|
|
db98e56e72 | ||
|
|
e2a35ea844 | ||
|
|
7966b2bde6 | ||
|
|
9391b947c6 | ||
|
|
e61e3bcf9b | ||
|
|
d79a0e737a |
@@ -1,3 +1,5 @@
|
||||
"use strict";
|
||||
|
||||
const webpack = require("webpack");
|
||||
const HtmlWebpackPlugin = require("html-webpack-plugin");
|
||||
const NodeExternals = require("webpack-node-externals");
|
||||
@@ -309,7 +311,10 @@ module.exports = function (grunt) {
|
||||
"webpack-dev-server": {
|
||||
options: {
|
||||
webpack: webpackConfig,
|
||||
host: "0.0.0.0",
|
||||
disableHostCheck: true,
|
||||
overlay: true,
|
||||
inline: false,
|
||||
clientLogLevel: "error",
|
||||
stats: {
|
||||
children: false,
|
||||
|
||||
48
package-lock.json
generated
48
package-lock.json
generated
@@ -1,18 +1,9 @@
|
||||
{
|
||||
"name": "cyberchef",
|
||||
"version": "6.0.2",
|
||||
"version": "6.3.1",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"HTML_CodeSniffer": {
|
||||
"version": "github:squizlabs/HTML_CodeSniffer#d209ce54876657858a8a01528ad812cd234f37f0",
|
||||
"dev": true
|
||||
},
|
||||
"JSONSelect": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/JSONSelect/-/JSONSelect-0.4.0.tgz",
|
||||
"integrity": "sha1-oI7cxn6z/L6Z7WMIVTRKDPKCu40="
|
||||
},
|
||||
"abab": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/abab/-/abab-1.0.3.tgz",
|
||||
@@ -41,12 +32,12 @@
|
||||
"integrity": "sha1-IJ4W63DAlaA79/yCnsrLfHeS9e4=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"HTML_CodeSniffer": "github:squizlabs/HTML_CodeSniffer#d209ce54876657858a8a01528ad812cd234f37f0",
|
||||
"axios": "0.9.1",
|
||||
"bluebird": "3.5.0",
|
||||
"chalk": "1.1.3",
|
||||
"commander": "2.11.0",
|
||||
"glob": "7.1.2",
|
||||
"HTML_CodeSniffer": "github:squizlabs/HTML_CodeSniffer#d209ce54876657858a8a01528ad812cd234f37f0",
|
||||
"jsdom": "9.12.0",
|
||||
"mkdirp": "0.5.1",
|
||||
"phantomjs-prebuilt": "2.1.15",
|
||||
@@ -1764,9 +1755,9 @@
|
||||
}
|
||||
},
|
||||
"crypto-api": {
|
||||
"version": "0.7.3",
|
||||
"resolved": "https://registry.npmjs.org/crypto-api/-/crypto-api-0.7.3.tgz",
|
||||
"integrity": "sha1-nHMgTE73lxYjIkOYuDS6fJ2B9uU="
|
||||
"version": "0.7.5",
|
||||
"resolved": "https://registry.npmjs.org/crypto-api/-/crypto-api-0.7.5.tgz",
|
||||
"integrity": "sha1-TCc3K8s85mnSKNV7NZG8YRjFKdU="
|
||||
},
|
||||
"crypto-browserify": {
|
||||
"version": "3.11.1",
|
||||
@@ -3873,6 +3864,10 @@
|
||||
"wbuf": "1.7.2"
|
||||
}
|
||||
},
|
||||
"HTML_CodeSniffer": {
|
||||
"version": "github:squizlabs/HTML_CodeSniffer#d209ce54876657858a8a01528ad812cd234f37f0",
|
||||
"dev": true
|
||||
},
|
||||
"html-comment-regex": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/html-comment-regex/-/html-comment-regex-1.1.1.tgz",
|
||||
@@ -4610,12 +4605,12 @@
|
||||
"resolved": "https://registry.npmjs.org/jison/-/jison-0.4.13.tgz",
|
||||
"integrity": "sha1-kEFwfWIkE2f1iDRTK58ZwsNvrHg=",
|
||||
"requires": {
|
||||
"JSONSelect": "0.4.0",
|
||||
"cjson": "0.2.1",
|
||||
"ebnf-parser": "0.1.10",
|
||||
"escodegen": "0.0.21",
|
||||
"esprima": "1.0.4",
|
||||
"jison-lex": "0.2.1",
|
||||
"JSONSelect": "0.4.0",
|
||||
"lex-parser": "0.1.4",
|
||||
"nomnom": "1.5.2"
|
||||
},
|
||||
@@ -4883,6 +4878,11 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"JSONSelect": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/JSONSelect/-/JSONSelect-0.4.0.tgz",
|
||||
"integrity": "sha1-oI7cxn6z/L6Z7WMIVTRKDPKCu40="
|
||||
},
|
||||
"jsprim": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
|
||||
@@ -7829,6 +7829,15 @@
|
||||
"integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=",
|
||||
"dev": true
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
|
||||
"integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"safe-buffer": "5.1.1"
|
||||
}
|
||||
},
|
||||
"string-width": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
|
||||
@@ -7856,15 +7865,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
|
||||
"integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"safe-buffer": "5.1.1"
|
||||
}
|
||||
},
|
||||
"stringstream": {
|
||||
"version": "0.0.5",
|
||||
"resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "cyberchef",
|
||||
"version": "6.0.2",
|
||||
"version": "6.3.1",
|
||||
"description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.",
|
||||
"author": "n1474335 <n1474335@gmail.com>",
|
||||
"homepage": "https://gchq.github.io/CyberChef",
|
||||
@@ -61,8 +61,8 @@
|
||||
"url-loader": "^0.5.9",
|
||||
"val-loader": "^1.0.2",
|
||||
"web-resource-inliner": "^4.1.1",
|
||||
"webpack": "^3.5.6",
|
||||
"webpack-dev-server": "^2.5.0",
|
||||
"webpack": "^3.6.0",
|
||||
"webpack-dev-server": "^2.8.2",
|
||||
"webpack-node-externals": "^1.6.0",
|
||||
"worker-loader": "^0.8.0"
|
||||
},
|
||||
@@ -71,7 +71,7 @@
|
||||
"bootstrap": "^3.3.7",
|
||||
"bootstrap-colorpicker": "^2.5.1",
|
||||
"bootstrap-switch": "^3.3.4",
|
||||
"crypto-api": "^0.7.3",
|
||||
"crypto-api": "^0.7.5",
|
||||
"crypto-js": "^3.1.9-1",
|
||||
"diff": "^3.3.1",
|
||||
"escodegen": "^1.9.0",
|
||||
|
||||
@@ -92,7 +92,7 @@ async function bake(data) {
|
||||
} catch (err) {
|
||||
self.postMessage({
|
||||
action: "bakeError",
|
||||
data: err.message
|
||||
data: err.message.split(":").slice(1).join(":").slice(1) // Cut off worker blurb
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -176,3 +176,22 @@ self.setOption = function(option, value) {
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Send register values back to the app.
|
||||
*
|
||||
* @param {number} opIndex
|
||||
* @param {number} numPrevRegisters
|
||||
* @param {string[]} registers
|
||||
*/
|
||||
self.setRegisters = function(opIndex, numPrevRegisters, registers) {
|
||||
self.postMessage({
|
||||
action: "setRegisters",
|
||||
data: {
|
||||
opIndex: opIndex,
|
||||
numPrevRegisters: numPrevRegisters,
|
||||
registers: registers
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
@@ -90,6 +90,74 @@ const FlowControl = {
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Register operation.
|
||||
*
|
||||
* @param {Object} state - The current state of the recipe.
|
||||
* @param {number} state.progress - The current position in the recipe.
|
||||
* @param {Dish} state.dish - The Dish being operated on.
|
||||
* @param {Operation[]} state.opList - The list of operations in the recipe.
|
||||
* @returns {Object} The updated state of the recipe.
|
||||
*/
|
||||
runRegister: function(state) {
|
||||
const ings = state.opList[state.progress].getIngValues(),
|
||||
extractorStr = ings[0],
|
||||
i = ings[1],
|
||||
m = ings[2];
|
||||
|
||||
let modifiers = "";
|
||||
if (i) modifiers += "i";
|
||||
if (m) modifiers += "m";
|
||||
|
||||
const extractor = new RegExp(extractorStr, modifiers),
|
||||
input = state.dish.get(Dish.STRING),
|
||||
registers = input.match(extractor);
|
||||
|
||||
if (!registers) return state;
|
||||
|
||||
if (ENVIRONMENT_IS_WORKER()) {
|
||||
self.setRegisters(state.progress, state.numRegisters, registers.slice(1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces references to registers (e.g. $R0) with the contents of those registers.
|
||||
*
|
||||
* @param {string} str
|
||||
* @returns {string}
|
||||
*/
|
||||
function replaceRegister(str) {
|
||||
// Replace references to registers ($Rn) with contents of registers
|
||||
return str.replace(/(\\*)\$R(\d{1,2})/g, (match, slashes, regNum) => {
|
||||
const index = parseInt(regNum, 10) + 1;
|
||||
if (index <= state.numRegisters || index >= state.numRegisters + registers.length)
|
||||
return match;
|
||||
if (slashes.length % 2 !== 0) return match.slice(1); // Remove escape
|
||||
return slashes + registers[index - state.numRegisters];
|
||||
});
|
||||
}
|
||||
|
||||
// Step through all subsequent ops and replace registers in args with extracted content
|
||||
for (let i = state.progress + 1; i < state.opList.length; i++) {
|
||||
if (state.opList[i].isDisabled()) continue;
|
||||
|
||||
let args = state.opList[i].getIngValues();
|
||||
args = args.map(arg => {
|
||||
if (typeof arg !== "string" && typeof arg !== "object") return arg;
|
||||
|
||||
if (typeof arg === "object" && arg.hasOwnProperty("string")) {
|
||||
arg.string = replaceRegister(arg.string);
|
||||
return arg;
|
||||
}
|
||||
return replaceRegister(arg);
|
||||
});
|
||||
state.opList[i].setIngValues(args);
|
||||
}
|
||||
|
||||
state.numRegisters += registers.length - 1;
|
||||
return state;
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Jump operation.
|
||||
*
|
||||
|
||||
@@ -145,7 +145,7 @@ Recipe.prototype.lastOpIndex = function(startIndex) {
|
||||
*/
|
||||
Recipe.prototype.execute = async function(dish, startFrom) {
|
||||
startFrom = startFrom || 0;
|
||||
let op, input, output, numJumps = 0;
|
||||
let op, input, output, numJumps = 0, numRegisters = 0;
|
||||
|
||||
for (let i = startFrom; i < this.opList.length; i++) {
|
||||
op = this.opList[i];
|
||||
@@ -162,15 +162,17 @@ Recipe.prototype.execute = async function(dish, startFrom) {
|
||||
if (op.isFlowControl()) {
|
||||
// Package up the current state
|
||||
let state = {
|
||||
"progress": i,
|
||||
"dish": dish,
|
||||
"opList": this.opList,
|
||||
"numJumps": numJumps
|
||||
"progress": i,
|
||||
"dish": dish,
|
||||
"opList": this.opList,
|
||||
"numJumps": numJumps,
|
||||
"numRegisters": numRegisters
|
||||
};
|
||||
|
||||
state = await op.run(state);
|
||||
i = state.progress;
|
||||
numJumps = state.numJumps;
|
||||
numRegisters = state.numRegisters;
|
||||
} else {
|
||||
output = await op.run(input, op.getIngValues());
|
||||
dish.set(output, op.outputType);
|
||||
|
||||
@@ -255,6 +255,9 @@ const Categories = [
|
||||
"Keccak",
|
||||
"Shake",
|
||||
"RIPEMD",
|
||||
"HAS-160",
|
||||
"Whirlpool",
|
||||
"Snefru",
|
||||
"HMAC",
|
||||
"Fletcher-8 Checksum",
|
||||
"Fletcher-16 Checksum",
|
||||
@@ -314,6 +317,7 @@ const Categories = [
|
||||
ops: [
|
||||
"Fork",
|
||||
"Merge",
|
||||
"Register",
|
||||
"Jump",
|
||||
"Conditional Jump",
|
||||
"Return",
|
||||
|
||||
@@ -116,6 +116,30 @@ const OperationConfig = {
|
||||
flowControl: true,
|
||||
args: []
|
||||
},
|
||||
"Register": {
|
||||
module: "Default",
|
||||
description: "Extract data from the input and store it in registers which can then be passed into subsequent operations as arguments. Regular expression capture groups are used to select the data to extract.<br><br>To use registers in arguments, refer to them using the notation <code>$Rn</code> where n is the register number, starting at 0.<br><br>For example:<br>Input: <code>Test</code><br>Extractor: <code>(.*)</code><br>Argument: <code>$R0</code> becomes <code>Test</code><br><br>Registers can be escaped in arguments using a backslash. e.g. <code>\\$R0</code> would become <code>$R0</code> rather than <code>Test</code>.",
|
||||
inputType: "string",
|
||||
outputType: "string",
|
||||
flowControl: true,
|
||||
args: [
|
||||
{
|
||||
name: "Extractor",
|
||||
type: "binaryString",
|
||||
value: "([\\s\\S]*)"
|
||||
},
|
||||
{
|
||||
name: "Case insensitive",
|
||||
type: "boolean",
|
||||
value: true
|
||||
},
|
||||
{
|
||||
name: "Multiline matching",
|
||||
type: "boolean",
|
||||
value: false
|
||||
},
|
||||
]
|
||||
},
|
||||
"Jump": {
|
||||
module: "Default",
|
||||
description: "Jump forwards or backwards over the specified number of operations.",
|
||||
@@ -2991,6 +3015,44 @@ const OperationConfig = {
|
||||
}
|
||||
]
|
||||
},
|
||||
"HAS-160": {
|
||||
module: "Hashing",
|
||||
description: "HAS-160 is a cryptographic hash function designed for use with the Korean KCDSA digital signature algorithm. It is derived from SHA-1, with assorted changes intended to increase its security. It produces a 160-bit output.<br><br>HAS-160 is used in the same way as SHA-1. First it divides input in blocks of 512 bits each and pads the final block. A digest function updates the intermediate hash value by processing the input blocks in turn.<br><br>The message digest algorithm consists of 80 rounds.",
|
||||
inputType: "string",
|
||||
outputType: "string",
|
||||
args: []
|
||||
},
|
||||
"Whirlpool": {
|
||||
module: "Hashing",
|
||||
description: "Whirlpool is a cryptographic hash function designed by Vincent Rijmen (co-creator of AES) and Paulo S. L. M. Barreto, who first described it in 2000.<br><br>Several variants exist:<ul><li>Whirlpool-0 is the original version released in 2000.</li><li>Whirlpool-T is the first revision, released in 2001, improving the generation of the s-box.</li><li>Wirlpool is the latest revision, released in 2003, fixing a flaw in the difusion matrix.</li></ul>",
|
||||
inputType: "string",
|
||||
outputType: "string",
|
||||
args: [
|
||||
{
|
||||
name: "Variant",
|
||||
type: "option",
|
||||
value: Hash.WHIRLPOOL_VARIANT
|
||||
}
|
||||
]
|
||||
},
|
||||
"Snefru": {
|
||||
module: "Hashing",
|
||||
description: "Snefru is a cryptographic hash function invented by Ralph Merkle in 1990 while working at Xerox PARC. The function supports 128-bit and 256-bit output. It was named after the Egyptian Pharaoh Sneferu, continuing the tradition of the Khufu and Khafre block ciphers.<br><br>The original design of Snefru was shown to be insecure by Eli Biham and Adi Shamir who were able to use differential cryptanalysis to find hash collisions. The design was then modified by increasing the number of iterations of the main pass of the algorithm from two to eight.",
|
||||
inputType: "string",
|
||||
outputType: "string",
|
||||
args: [
|
||||
{
|
||||
name: "Rounds",
|
||||
type: "option",
|
||||
value: Hash.SNEFRU_ROUNDS
|
||||
},
|
||||
{
|
||||
name: "Size",
|
||||
type: "option",
|
||||
value: Hash.SNEFRU_SIZE
|
||||
}
|
||||
]
|
||||
},
|
||||
"HMAC": {
|
||||
module: "Hashing",
|
||||
description: "Keyed-Hash Message Authentication Codes (HMAC) are a mechanism for message authentication using cryptographic hash functions.",
|
||||
|
||||
@@ -154,6 +154,7 @@ OpModules.Default = {
|
||||
"Generate HOTP": OTP.runHOTP,
|
||||
"Fork": FlowControl.runFork,
|
||||
"Merge": FlowControl.runMerge,
|
||||
"Register": FlowControl.runRegister,
|
||||
"Jump": FlowControl.runJump,
|
||||
"Conditional Jump": FlowControl.runCondJump,
|
||||
"Return": FlowControl.runReturn,
|
||||
|
||||
@@ -31,6 +31,9 @@ OpModules.Hashing = {
|
||||
"Keccak": Hash.runKeccak,
|
||||
"Shake": Hash.runShake,
|
||||
"RIPEMD": Hash.runRIPEMD,
|
||||
"HAS-160": Hash.runHAS,
|
||||
"Whirlpool": Hash.runWhirlpool,
|
||||
"Snefru": Hash.runSnefru,
|
||||
"HMAC": Hash.runHMAC,
|
||||
"Fletcher-8 Checksum": Checksum.runFletcher8,
|
||||
"Fletcher-16 Checksum": Checksum.runFletcher16,
|
||||
|
||||
@@ -263,6 +263,62 @@ const Hash = {
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* HAS-160 operation.
|
||||
*
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*/
|
||||
runHAS: function (input, args) {
|
||||
return CryptoApi.hash("has160", input, {}).stringify("hex");
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* @constant
|
||||
* @default
|
||||
*/
|
||||
WHIRLPOOL_VARIANT: ["Whirlpool", "Whirlpool-T", "Whirlpool-0"],
|
||||
|
||||
/**
|
||||
* Whirlpool operation.
|
||||
*
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*/
|
||||
runWhirlpool: function (input, args) {
|
||||
const variant = args[0].toLowerCase();
|
||||
return CryptoApi.hash(variant, input, {}).stringify("hex");
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* @constant
|
||||
* @default
|
||||
*/
|
||||
SNEFRU_ROUNDS: ["8", "4", "2"],
|
||||
/**
|
||||
* @constant
|
||||
* @default
|
||||
*/
|
||||
SNEFRU_SIZE: ["256", "128"],
|
||||
|
||||
/**
|
||||
* Snefru operation.
|
||||
*
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*/
|
||||
runSnefru: function (input, args) {
|
||||
const rounds = args[0],
|
||||
size = args[1];
|
||||
return CryptoApi.hash(`snefru-${rounds}-${size}`, input, {}).stringify("hex");
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* @constant
|
||||
* @default
|
||||
@@ -283,6 +339,10 @@ const Hash = {
|
||||
"RIPEMD160",
|
||||
"RIPEMD256",
|
||||
"RIPEMD320",
|
||||
"HAS160",
|
||||
"Whirlpool",
|
||||
"Whirlpool-0",
|
||||
"Whirlpool-T"
|
||||
],
|
||||
|
||||
/**
|
||||
@@ -335,6 +395,10 @@ const Hash = {
|
||||
"\nRIPEMD-160: " + Hash.runRIPEMD(input, ["160"]) +
|
||||
"\nRIPEMD-256: " + Hash.runRIPEMD(input, ["256"]) +
|
||||
"\nRIPEMD-320: " + Hash.runRIPEMD(input, ["320"]) +
|
||||
"\nHAS-160: " + Hash.runHAS(input, []) +
|
||||
"\nWhirlpool-0: " + Hash.runWhirlpool(input, ["Whirlpool-0"]) +
|
||||
"\nWhirlpool-T: " + Hash.runWhirlpool(input, ["Whirlpool-T"]) +
|
||||
"\nWhirlpool: " + Hash.runWhirlpool(input, ["Whirlpool"]) +
|
||||
"\n\nChecksums:" +
|
||||
"\nFletcher-8: " + Checksum.runFletcher8(byteArray, []) +
|
||||
"\nFletcher-16: " + Checksum.runFletcher16(byteArray, []) +
|
||||
|
||||
@@ -122,7 +122,12 @@ App.prototype.bake = function(step) {
|
||||
* Runs Auto Bake if it is set.
|
||||
*/
|
||||
App.prototype.autoBake = function() {
|
||||
if (this.autoBake_ && !this.autoBakePause && !this.baking) {
|
||||
// If autoBakePause is set, we are loading a full recipe (and potentially input), so there is no
|
||||
// need to set the staleness indicator. Just exit and wait until auto bake is called after loading
|
||||
// has completed.
|
||||
if (this.autoBakePause) return false;
|
||||
|
||||
if (this.autoBake_ && !this.baking) {
|
||||
this.bake();
|
||||
} else {
|
||||
this.manager.controls.showStaleIndicator();
|
||||
@@ -369,10 +374,6 @@ App.prototype.loadURIParams = function() {
|
||||
window.location.hash;
|
||||
this.uriParams = Utils.parseURIParams(params);
|
||||
|
||||
// Pause auto-bake while loading but don't modify `this.autoBake_`
|
||||
// otherwise `manualBake` cannot trigger.
|
||||
this.autoBakePause = true;
|
||||
|
||||
// Read in recipe from URI params
|
||||
if (this.uriParams.recipe) {
|
||||
try {
|
||||
@@ -401,14 +402,16 @@ App.prototype.loadURIParams = function() {
|
||||
|
||||
// Read in input data from URI params
|
||||
if (this.uriParams.input) {
|
||||
this.autoBakePause = true;
|
||||
try {
|
||||
const inputData = Utils.fromBase64(this.uriParams.input);
|
||||
this.setInput(inputData);
|
||||
} catch (err) {}
|
||||
} catch (err) {
|
||||
} finally {
|
||||
this.autoBakePause = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Unpause auto-bake
|
||||
this.autoBakePause = false;
|
||||
this.autoBake();
|
||||
};
|
||||
|
||||
@@ -441,6 +444,10 @@ App.prototype.getRecipeConfig = function() {
|
||||
App.prototype.setRecipeConfig = function(recipeConfig) {
|
||||
document.getElementById("rec-list").innerHTML = null;
|
||||
|
||||
// Pause auto-bake while loading but don't modify `this.autoBake_`
|
||||
// otherwise `manualBake` cannot trigger.
|
||||
this.autoBakePause = true;
|
||||
|
||||
for (let i = 0; i < recipeConfig.length; i++) {
|
||||
const item = this.manager.recipe.addOperation(recipeConfig[i].op);
|
||||
|
||||
@@ -473,6 +480,9 @@ App.prototype.setRecipeConfig = function(recipeConfig) {
|
||||
|
||||
this.progress = 0;
|
||||
}
|
||||
|
||||
// Unpause auto bake
|
||||
this.autoBakePause = false;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -361,6 +361,7 @@ ControlsWaiter.prototype.loadButtonClick = function() {
|
||||
try {
|
||||
const recipeConfig = Utils.parseRecipeConfig(document.getElementById("load-text").value);
|
||||
this.app.setRecipeConfig(recipeConfig);
|
||||
this.app.autoBake();
|
||||
|
||||
$("#rec-list [data-toggle=popover]").popover();
|
||||
} catch (e) {
|
||||
|
||||
@@ -158,13 +158,11 @@ InputWaiter.prototype.inputDrop = function(e) {
|
||||
const CHUNK_SIZE = 20480; // 20KB
|
||||
|
||||
const setInput = function() {
|
||||
this.app.autoBakePause = true;
|
||||
const recipeConfig = this.app.getRecipeConfig();
|
||||
if (!recipeConfig[0] || recipeConfig[0].op !== "From Hex") {
|
||||
recipeConfig.unshift({op: "From Hex", args: ["Space"]});
|
||||
this.app.setRecipeConfig(recipeConfig);
|
||||
}
|
||||
this.app.autoBakePause = false;
|
||||
|
||||
this.set(inputCharcode);
|
||||
|
||||
|
||||
@@ -119,9 +119,8 @@ Manager.prototype.initialiseEventListeners = function() {
|
||||
this.addDynamicListener("li.operation", "operationadd", this.recipe.opAdd.bind(this.recipe));
|
||||
|
||||
// Recipe
|
||||
this.addDynamicListener(".arg", "keyup", this.recipe.ingChange, this.recipe);
|
||||
this.addDynamicListener(".arg", "change", this.recipe.ingChange, this.recipe);
|
||||
this.addDynamicListener(".arg", "input", this.recipe.ingChange, this.recipe);
|
||||
this.addDynamicListener(".arg:not(select)", "input", this.recipe.ingChange, this.recipe);
|
||||
this.addDynamicListener(".arg[type=checkbox], .arg[type=radio], select.arg", "change", this.recipe.ingChange, this.recipe);
|
||||
this.addDynamicListener(".disable-icon", "click", this.recipe.disableClick, this.recipe);
|
||||
this.addDynamicListener(".breakpoint", "click", this.recipe.breakpointClick, this.recipe);
|
||||
this.addDynamicListener("#rec-list li.operation", "dblclick", this.recipe.operationDblclick, this.recipe);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import HTMLOperation from "./HTMLOperation.js";
|
||||
import Sortable from "sortablejs";
|
||||
import Utils from "../core/Utils.js";
|
||||
|
||||
|
||||
/**
|
||||
@@ -191,7 +192,7 @@ RecipeWaiter.prototype.favDrop = function(e) {
|
||||
*
|
||||
* @fires Manager#statechange
|
||||
*/
|
||||
RecipeWaiter.prototype.ingChange = function() {
|
||||
RecipeWaiter.prototype.ingChange = function(e) {
|
||||
window.dispatchEvent(this.manager.statechange);
|
||||
};
|
||||
|
||||
@@ -435,4 +436,30 @@ RecipeWaiter.prototype.opRemove = function(e) {
|
||||
window.dispatchEvent(this.manager.statechange);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets register values.
|
||||
*
|
||||
* @param {number} opIndex
|
||||
* @param {number} numPrevRegisters
|
||||
* @param {string[]} registers
|
||||
*/
|
||||
RecipeWaiter.prototype.setRegisters = function(opIndex, numPrevRegisters, registers) {
|
||||
const op = document.querySelector(`#rec-list .operation:nth-child(${opIndex + 1})`),
|
||||
prevRegList = op.querySelector(".register-list");
|
||||
|
||||
// Remove previous div
|
||||
if (prevRegList) prevRegList.remove();
|
||||
|
||||
let registerList = [];
|
||||
for (let i = 0; i < registers.length; i++) {
|
||||
registerList.push(`$R${numPrevRegisters + i} = ${Utils.escapeHtml(Utils.truncate(Utils.printable(registers[i]), 100))}`);
|
||||
}
|
||||
const registerListEl = `<div class="register-list">
|
||||
${registerList.join("<br>")}
|
||||
</div>`;
|
||||
|
||||
op.insertAdjacentHTML("beforeend", registerListEl);
|
||||
};
|
||||
|
||||
export default RecipeWaiter;
|
||||
|
||||
@@ -61,6 +61,9 @@ WorkerWaiter.prototype.handleChefMessage = function(e) {
|
||||
case "optionUpdate":
|
||||
this.app.options[r.data.option] = r.data.value;
|
||||
break;
|
||||
case "setRegisters":
|
||||
this.manager.recipe.setRegisters(r.data.opIndex, r.data.numPrevRegisters, r.data.registers);
|
||||
break;
|
||||
case "highlightsCalculated":
|
||||
this.manager.highlighter.displayHighlights(r.data.pos, r.data.direction);
|
||||
break;
|
||||
|
||||
@@ -414,6 +414,7 @@
|
||||
<li><a href="#recipe=From_Hexdump()Gunzip()&input=MDAwMDAwMDAgIDFmIDhiIDA4IDAwIDEyIGJjIGYzIDU3IDAwIGZmIDBkIGM3IGMxIDA5IDAwIDIwICB8Li4uLi6881cu/y7HwS4uIHwKMDAwMDAwMTAgIDA4IDA1IGQwIDU1IGZlIDA0IDJkIGQzIDA0IDFmIGNhIDhjIDQ0IDIxIDViIGZmICB8Li7QVf4uLdMuLsouRCFb/3wKMDAwMDAwMjAgIDYwIGM3IGQ3IDAzIDE2IGJlIDQwIDFmIDc4IDRhIDNmIDA5IDg5IDBiIDlhIDdkICB8YMfXLi6%2BQC54Sj8uLi4ufXwKMDAwMDAwMzAgIDRlIGM4IDRlIDZkIDA1IDFlIDAxIDhiIDRjIDI0IDAwIDAwIDAwICAgICAgICAgICB8TshObS4uLi5MJC4uLnw">Convert data from a hexdump, then decompress</a></li>
|
||||
<li><a href="#recipe=Fork('%5C%5Cn','%5C%5Cn',false)From_UNIX_Timestamp('Seconds%20(s)')&input=OTc4MzQ2ODAwCjEwMTI2NTEyMDAKMTA0NjY5NjQwMAoxMDgxMDg3MjAwCjExMTUzMDUyMDAKMTE0OTYwOTYwMA">Display multiple timestamps as full dates</a></li>
|
||||
<li><a href="#recipe=Fork('%5C%5Cn','%5C%5Cn',false)Conditional_Jump('1',2,10)To_Hex('Space')Return()To_Base64('A-Za-z0-9%2B/%3D')&input=U29tZSBkYXRhIHdpdGggYSAxIGluIGl0ClNvbWUgZGF0YSB3aXRoIGEgMiBpbiBpdA">Carry out different operations on data of different types</a></li>
|
||||
<li><a href="#recipe=Register('key%3D(%5B%5C%5Cda-f%5D*)',true,false)Find_/_Replace(%7B'option':'Regex','string':'.*data%3D(.*)'%7D,'$1',true,false,true)RC4(%7B'option':'Hex','string':'$R0'%7D,'Hex','Latin1')&input=aHR0cDovL21hbHdhcmV6LmJpei9iZWFjb24ucGhwP2tleT0wZTkzMmE1YyZkYXRhPThkYjdkNWViZTM4NjYzYTU0ZWNiYjMzNGUzZGIxMQ">Use parts of the input as arguments to operations</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<blockquote>
|
||||
|
||||
@@ -124,6 +124,12 @@ button.dropdown-toggle {
|
||||
background-color: var(--secondary-background-colour);
|
||||
}
|
||||
|
||||
.register-list {
|
||||
background-color: var(--fc-operation-border-colour);
|
||||
font-family: var(--fixed-width-font-family);
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.op-icon {
|
||||
float: right;
|
||||
margin-left: 10px;
|
||||
@@ -195,3 +201,13 @@ button.dropdown-toggle {
|
||||
background-color: var(--disabled-bg-colour) !important;
|
||||
border-color: var(--disabled-border-colour) !important;
|
||||
}
|
||||
|
||||
.break .register-list {
|
||||
color: var(--fc-breakpoint-operation-font-colour) !important;
|
||||
background-color: var(--fc-breakpoint-operation-border-colour) !important;
|
||||
}
|
||||
|
||||
.disabled .register-list {
|
||||
color: var(--disabled-font-colour) !important;
|
||||
background-color: var(--disabled-border-colour) !important;
|
||||
}
|
||||
|
||||
@@ -294,6 +294,116 @@ TestRegister.addTests([
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "HAS-160",
|
||||
input: "Hello, World!",
|
||||
expectedOutput: "8f6dd8d7c8a04b1cb3831adc358b1e4ac2ed5984",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "HAS-160",
|
||||
"args": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Whirlpool-0",
|
||||
input: "Hello, World!",
|
||||
expectedOutput: "1c327026f565a0105a827efbfb3d3635cdb042c0aabb8416e96deb128e6c5c8684b13541cf31c26c1488949df050311c6999a12eb0e7002ad716350f5c7700ca",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Whirlpool",
|
||||
"args": ["Whirlpool-0"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Whirlpool-T",
|
||||
input: "Hello, World!",
|
||||
expectedOutput: "16c581089b6a6f356ae56e16a63a4c613eecd82a2a894b293f5ee45c37a31d09d7a8b60bfa7e414bd4a7166662cea882b5cf8c96b7d583fc610ad202591bcdb1",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Whirlpool",
|
||||
"args": ["Whirlpool-T"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Whirlpool",
|
||||
input: "Hello, World!",
|
||||
expectedOutput: "3d837c9ef7bb291bd1dcfc05d3004af2eeb8c631dd6a6c4ba35159b8889de4b1ec44076ce7a8f7bfa497e4d9dcb7c29337173f78d06791f3c3d9e00cc6017f0b",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Whirlpool",
|
||||
"args": ["Whirlpool"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Snefru 2 128",
|
||||
input: "Hello, World!",
|
||||
expectedOutput: "a4ad2b8848580511d0884fb4233a7e7a",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Snefru",
|
||||
"args": ["2", "128"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Snefru 4 128",
|
||||
input: "Hello, World!",
|
||||
expectedOutput: "d154eae2c9ffbcd2e1bdaf0b84736126",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Snefru",
|
||||
"args": ["4", "128"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Snefru 8 128",
|
||||
input: "Hello, World!",
|
||||
expectedOutput: "6f3d55b69557abb0a3c4e9de9d29ba5d",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Snefru",
|
||||
"args": ["8", "128"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Snefru 2 256",
|
||||
input: "Hello, World!",
|
||||
expectedOutput: "65736daba648de28ef4c4a316b4684584ecf9f22ddb5c457729e6bf0f40113c4",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Snefru",
|
||||
"args": ["2", "256"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Snefru 4 256",
|
||||
input: "Hello, World!",
|
||||
expectedOutput: "71b0ea4b3e33f2e58bcc67c8a8de060b99ec0107355bbfdc18d8f65f0194ffcc",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Snefru",
|
||||
"args": ["4", "256"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Snefru 8 256",
|
||||
input: "Hello, World!",
|
||||
expectedOutput: "255cd401414c79588cf689e8d5ff0536a2cfab83fcae36e654f202b09bc4b8a7",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Snefru",
|
||||
"args": ["8", "256"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "HMAC SHA256",
|
||||
input: "Hello, World!",
|
||||
|
||||
Reference in New Issue
Block a user