/**
* @author n1474335 [n1474335@gmail.com]
* @copyright Crown Copyright 2016
* @license Apache-2.0
*/
import Operation from "../Operation";
import Utils from "../Utils";
import Dish from "../Dish";
import MagicLib from "../lib/Magic";
/**
* Magic operation
*/
class Magic extends Operation {
/**
* Magic constructor
*/
constructor() {
super();
this.name = "Magic";
this.flowControl = true;
this.module = "Default";
this.description = "The Magic operation attempts to detect various properties of the input data and suggests which operations could help to make more sense of it.
Options
Depth: If an operation appears to match the data, it will be run and the result will be analysed further. This argument controls the maximum number of levels of recursion.
Intensive mode: When this is turned on, various operations like XOR, bit rotates, and character encodings are brute-forced to attempt to detect valid data underneath. To improve performance, only the first 100 bytes of the data is brute-forced.
Extensive language support: At each stage, the relative byte frequencies of the data will be compared to average frequencies for a number of languages. The default set consists of ~40 of the most commonly used languages on the Internet. The extensive list consists of 284 languages and can result in many languages matching the data if their byte frequencies are similar.";
this.inputType = "ArrayBuffer";
this.outputType = "JSON";
this.presentType = "html";
this.args = [
{
"name": "Depth",
"type": "number",
"value": 3
},
{
"name": "Intensive mode",
"type": "boolean",
"value": false
},
{
"name": "Extensive language support",
"type": "boolean",
"value": false
}
];
}
/**
* @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.
*/
async run(state) {
const ings = state.opList[state.progress].ingValues,
[depth, intensive, extLang] = ings,
dish = state.dish,
magic = new MagicLib(await dish.get(Dish.ARRAY_BUFFER)),
options = await magic.speculativeExecution(depth, extLang, intensive);
// Record the current state for use when presenting
this.state = state;
dish.set(options, Dish.JSON);
return state;
}
/**
* Displays Magic results in HTML for web apps.
*
* @param {JSON} options
* @returns {html}
*/
present(options) {
const currentRecipeConfig = this.state.opList.map(op => op.config);
let output = `
Recipe (click to load) | Result snippet | Properties |
---|---|---|
${Utils.generatePrettyRecipe(option.recipe, true)} | ${Utils.escapeHtml(Utils.printable(Utils.truncate(option.data, 99)))} | ${language}${fileType}${matchingOps}${useful}${validUTF8}${entropy} |