Magic operation now recognises useful operations such as 'Render Image' even though their output cannot be analysed

This commit is contained in:
n1474335 2018-02-15 13:39:55 +00:00
parent 1760ab2305
commit 27ec4aa923
3 changed files with 34 additions and 14 deletions

View File

@ -294,13 +294,14 @@ const FlowControl = {
let language = "", let language = "",
fileType = "", fileType = "",
matchingOps = "", matchingOps = "",
useful = "",
validUTF8 = option.isUTF8 ? "Valid UTF8\n" : ""; validUTF8 = option.isUTF8 ? "Valid UTF8\n" : "";
if (option.languageScores[0].probability > 0.00001) { if (option.languageScores[0].probability > 0) {
let likelyLangs = option.languageScores.filter(l => l.probability > 0.2); let likelyLangs = option.languageScores.filter(l => l.probability > 0);
if (likelyLangs.length < 1) likelyLangs = [option.languageScores[0]]; if (likelyLangs.length < 1) likelyLangs = [option.languageScores[0]];
language = "Language:\n " + likelyLangs.map(lang => { language = "Possible languages:\n " + likelyLangs.map(lang => {
return `${Magic.codeToLanguage(lang.lang)} ${(lang.probability * 100).toFixed(2)}%`; return Magic.codeToLanguage(lang.lang);
}).join("\n ") + "\n"; }).join("\n ") + "\n";
} }
@ -312,10 +313,14 @@ const FlowControl = {
matchingOps = `Matching ops: ${[...new Set(option.matchingOps.map(op => op.op))].join(", ")}\n`; matchingOps = `Matching ops: ${[...new Set(option.matchingOps.map(op => op.op))].join(", ")}\n`;
} }
if (option.useful) {
useful = "Useful op detected\n";
}
output += `<tr> output += `<tr>
<td><a href="#${recipeURL}">${Utils.generatePrettyRecipe(option.recipe, true)}</a></td> <td><a href="#${recipeURL}">${Utils.generatePrettyRecipe(option.recipe, true)}</a></td>
<td>${Utils.escapeHtml(Utils.printable(Utils.truncate(option.data, 99)))}</td> <td>${Utils.escapeHtml(Utils.printable(Utils.truncate(option.data, 99)))}</td>
<td>${language}${fileType}${matchingOps}${validUTF8}</td> <td>${language}${fileType}${matchingOps}${useful}${validUTF8}</td>
</tr>`; </tr>`;
}); });

View File

@ -4091,7 +4091,8 @@ const OperationConfig = {
{ {
match: "^(?:\\xff\\xd8\\xff|\\x89\\x50\\x4e\\x47|\\x47\\x49\\x46|.{8}\\x57\\x45\\x42\\x50|\\x42\\x4d)", match: "^(?:\\xff\\xd8\\xff|\\x89\\x50\\x4e\\x47|\\x47\\x49\\x46|.{8}\\x57\\x45\\x42\\x50|\\x42\\x4d)",
flags: "", flags: "",
args: ["Raw"] args: ["Raw"],
useful: true
}, },
] ]
}, },

View File

@ -58,6 +58,12 @@ class Magic {
* @returns {Object[]} * @returns {Object[]}
*/ */
detectLanguage(extLang = false) { detectLanguage(extLang = false) {
if (!this.inputBuffer.length) return [{
lang: "Unknown",
score: Math.MAX_VALUE,
probability: Math.MIN_VALUE
}];
const inputFreq = this._freqDist(); const inputFreq = this._freqDist();
const langFreqs = extLang ? EXTENSIVE_LANG_FREQS : COMMON_LANG_FREQS; const langFreqs = extLang ? EXTENSIVE_LANG_FREQS : COMMON_LANG_FREQS;
let chiSqrs = []; let chiSqrs = [];
@ -212,9 +218,10 @@ class Magic {
* @param {boolean} [intensive=false] - Run brute-forcing on each branch (significantly affects * @param {boolean} [intensive=false] - Run brute-forcing on each branch (significantly affects
* performance) * performance)
* @param {Object[]} [recipeConfig=[]] - The recipe configuration up to this point * @param {Object[]} [recipeConfig=[]] - The recipe configuration up to this point
* @param {boolean} [useful=false] - Whether the current recipe should be scored highly
* @returns {Object[]} - A sorted list of the recipes most likely to result in correct decoding * @returns {Object[]} - A sorted list of the recipes most likely to result in correct decoding
*/ */
async speculativeExecution(depth = 0, extLang = false, intensive = false, recipeConfig = []) { async speculativeExecution(depth=0, extLang=false, intensive=false, recipeConfig=[], useful=false) {
if (depth < 0) return []; if (depth < 0) return [];
// Find any operations that can be run on this data // Find any operations that can be run on this data
@ -229,7 +236,8 @@ class Magic {
languageScores: this.detectLanguage(extLang), languageScores: this.detectLanguage(extLang),
fileType: this.detectFileType(), fileType: this.detectFileType(),
isUTF8: this.isUTF8(), isUTF8: this.isUTF8(),
matchingOps: matchingOps matchingOps: matchingOps,
useful: useful
}); });
// Execute each of the matching operations, then recursively call the speculativeExecution() // Execute each of the matching operations, then recursively call the speculativeExecution()
@ -250,7 +258,7 @@ class Magic {
const magic = new Magic(dish.get(Dish.ARRAY_BUFFER), this.opPatterns), const magic = new Magic(dish.get(Dish.ARRAY_BUFFER), this.opPatterns),
speculativeResults = await magic.speculativeExecution( speculativeResults = await magic.speculativeExecution(
depth-1, extLang, intensive, [...recipeConfig, opConfig]); depth-1, extLang, intensive, [...recipeConfig, opConfig], op.useful);
results = results.concat(speculativeResults); results = results.concat(speculativeResults);
})); }));
@ -273,7 +281,8 @@ class Magic {
r.languageScores[0].probability > 0 || r.languageScores[0].probability > 0 ||
r.fileType || r.fileType ||
r.isUTF8 || r.isUTF8 ||
r.matchingOps.length); r.matchingOps.length ||
r.useful);
// Return a sorted list of possible recipes along with their properties // Return a sorted list of possible recipes along with their properties
return results.sort((a, b) => { return results.sort((a, b) => {
@ -289,6 +298,10 @@ class Magic {
if (a.isUTF8) aScore -= 100; if (a.isUTF8) aScore -= 100;
if (b.isUTF8) bScore -= 100; if (b.isUTF8) bScore -= 100;
// If the option is marked useful, give it a good score
if (a.useful) aScore = 100;
if (b.useful) bScore = 100;
return aScore - bScore; return aScore - bScore;
}); });
} }
@ -332,7 +345,8 @@ class Magic {
op: op, op: op,
match: pattern.match, match: pattern.match,
flags: pattern.flags, flags: pattern.flags,
args: pattern.args args: pattern.args,
useful: pattern.useful || false
}); });
}); });
} }