1
0
mirror of synced 2025-02-04 13:25:34 +01:00

Fixed formatting issues

This commit is contained in:
mshwed 2019-04-06 23:09:46 -04:00
parent b7fb9635e5
commit 8fc0e012e3

View File

@ -26,8 +26,8 @@ class AdvancedEntropy extends Operation {
this.name = "Advanced Entropy"; this.name = "Advanced Entropy";
this.module = "Default"; this.module = "Default";
this.description = "Adds advanced views for examining entropy"; this.description = "Shannon Entropy, in the context of information theory, is a measure of the rate at which information is produced by a source of data. It can be used, in a broad sense, to detect whether data is likely to be structured or unstructured. 8 is the maximum, representing highly unstructured, 'random' data. English language text usually falls somewhere between 3.5 and 5. Properly encrypted or compressed data should have an entropy of over 7.5.";
this.infoURL = ""; this.infoURL = "https://wikipedia.org/wiki/Entropy_(information_theory)";
this.inputType = "byteArray"; this.inputType = "byteArray";
this.outputType = "html"; this.outputType = "html";
this.args = [ this.args = [
@ -41,16 +41,16 @@ class AdvancedEntropy extends Operation {
/** /**
* Calculates the frequency of bytes in the input. * Calculates the frequency of bytes in the input.
* *
* @param {byteArray} input * @param {byteArray} input
* @returns {frequency} * @returns {frequency}
*/ */
calculateShannonEntropy(input) { calculateShannonEntropy(input) {
const prob = [], const prob = [],
uniques = input.unique(), uniques = input.unique(),
str = Utils.byteArrayToChars(input); str = Utils.byteArrayToChars(input);
let i;
let i;
for (i = 0; i < uniques.length; i++) { for (i = 0; i < uniques.length; i++) {
prob.push(str.count(Utils.chr(uniques[i])) / input.length); prob.push(str.count(Utils.chr(uniques[i])) / input.length);
} }
@ -66,21 +66,20 @@ class AdvancedEntropy extends Operation {
return -entropy; return -entropy;
} }
/** /**
* *
* @param inputBytes * @param inputBytes
* @returns {entropyData} * @returns {entropyData}
*/ */
calculateScanningEntropy(inputBytes, binWidth) { calculateScanningEntropy(inputBytes, binWidth) {
const entropyData = []; const entropyData = [];
binWidth = binWidth binWidth = binWidth ?
? Math.floor(inputBytes.length / binWidth) Math.floor(inputBytes.length / binWidth) :
: Math.floor(inputBytes.length / 256); Math.floor(inputBytes.length / 256);
for (let bytePos = 0; bytePos < inputBytes.length; bytePos+=binWidth) { for (let bytePos = 0; bytePos < inputBytes.length; bytePos+=binWidth) {
const block = inputBytes.slice(bytePos, bytePos+binWidth) const block = inputBytes.slice(bytePos, bytePos+binWidth);
const blockEntropy = this.calculateShannonEntropy(block); entropyData.push(this.calculateShannonEntropy(block));
entropyData.push(blockEntropy);
} }
return { entropyData, binWidth }; return { entropyData, binWidth };
@ -89,7 +88,7 @@ class AdvancedEntropy extends Operation {
/** /**
* Calculates the frequency of bytes in the input. * Calculates the frequency of bytes in the input.
* *
* @param {object} svg * @param {object} svg
* @param {function} xScale * @param {function} xScale
* @param {function} yScale * @param {function} yScale
@ -106,7 +105,7 @@ class AdvancedEntropy extends Operation {
.scale(yScale); .scale(yScale);
const xAxis = d3.axisBottom() const xAxis = d3.axisBottom()
.scale(xScale) .scale(xScale);
svg.append("g") svg.append("g")
.attr("transform", `translate(0, ${svgHeight - margins.bottom})`) .attr("transform", `translate(0, ${svgHeight - margins.bottom})`)
@ -123,39 +122,37 @@ class AdvancedEntropy extends Operation {
.attr("x", 0 - (svgHeight / 2)) .attr("x", 0 - (svgHeight / 2))
.attr("dy", "1em") .attr("dy", "1em")
.style("text-anchor", "middle") .style("text-anchor", "middle")
.text(yTitle) .text(yTitle);
svg.append("text") svg.append("text")
.attr("transform", `translate(${svgWidth / 2}, ${svgHeight - margins.bottom + 40})`) .attr("transform", `translate(${svgWidth / 2}, ${svgHeight - margins.bottom + 40})`)
.style("text-anchor", "middle") .style("text-anchor", "middle")
.text(xTitle) .text(xTitle);
// Add title // Add title
svg.append("text") svg.append("text")
.attr("transform", `translate(${svgWidth / 2}, ${margins.top - 10})`) .attr("transform", `translate(${svgWidth / 2}, ${margins.top - 10})`)
.style("text-anchor", "middle") .style("text-anchor", "middle")
.text(title) .text(title);
} }
/** /**
* Calculates the frequency of bytes in the input. * Calculates the frequency of bytes in the input.
* *
* @param {byteArray} inputBytes * @param {byteArray} inputBytes
* @returns {frequency} * @returns {frequency}
*/ */
calculateByteFrequency(inputBytes) { calculateByteFrequency(inputBytes) {
console.log(inputBytes); const byteFrequency = [];
let byteFrequency = [];
for (let i = 0; i < 256; i++) { for (let i = 0; i < 256; i++) {
let count = 0; let count = 0;
for (let byte of inputBytes) { for (const byte of inputBytes) {
if (byte === i) { if (byte === i) {
count++; count++;
} }
} }
byteFrequency.push(count / (inputBytes.length + 1)) byteFrequency.push(count / (inputBytes.length + 1));
} }
return byteFrequency; return byteFrequency;
@ -163,14 +160,12 @@ class AdvancedEntropy extends Operation {
/** /**
* Calculates the frequency of bytes in the input. * Calculates the frequency of bytes in the input.
* *
* @param {byteArray} input * @param {byteArray} byteFrequency
* @returns {frequency} * @returns {frequency}
*/ */
createByteFrequencyLineHistogram(entropyData) { createByteFrequencyLineHistogram(byteFrequency) {
const byteFrequency = entropyData.byteFrequency; const margins = { top: 30, right: 20, bottom: 50, left: 30 };
const margins = {top: 30, right: 20, bottom: 50, left: 30};
const svgWidth = 500, const svgWidth = 500,
svgHeight = 500; svgHeight = 500;
@ -192,28 +187,28 @@ class AdvancedEntropy extends Operation {
.range([margins.left, svgWidth - margins.right]); .range([margins.left, svgWidth - margins.right]);
const line = d3.line() const line = d3.line()
.x((d, i) => { return xScale(i)}) .x((_, i) => xScale(i))
.y((d) => { return yScale(d)}) .y(d => yScale(d))
.curve(d3.curveMonotoneX); .curve(d3.curveMonotoneX);
svg.append('path') svg.append("path")
.datum(byteFrequency) .datum(byteFrequency)
.attr("d", line) .attr("d", line)
.attr("fill", "steelblue"); .attr("fill", "steelblue");
this.createAxes(svg, xScale, yScale, svgHeight, svgWidth, margins, "", "Byte", "Byte Frequency"); this.createAxes(svg, xScale, yScale, svgHeight, svgWidth, margins, "", "Byte", "Byte Frequency");
return svg._groups[0][0].outerHTML; return svg._groups[0][0].outerHTML;
} }
/** /**
* Creates a byte frequency histogram * Creates a byte frequency histogram
* *
* @param {byteArray} entropyData * @param {byteArray} byteFrequency
* @returns {HTML} * @returns {HTML}
*/ */
createByteFrequencyBarHistogram(entropyData) { createByteFrequencyBarHistogram(byteFrequency) {
const byteFrequency = entropyData.byteFrequency; const margins = { top: 30, right: 20, bottom: 50, left: 30 };
const svgWidth = 500, const svgWidth = 500,
svgHeight = 500, svgHeight = 500,
@ -225,8 +220,6 @@ class AdvancedEntropy extends Operation {
.attr("width", "100%") .attr("width", "100%")
.attr("height", "100%") .attr("height", "100%")
.attr("viewBox", `0 0 ${svgWidth} ${svgHeight}`); .attr("viewBox", `0 0 ${svgWidth} ${svgHeight}`);
const margins = {top: 30, right: 20, bottom: 50, left: 30};
const yScale = d3.scaleLinear() const yScale = d3.scaleLinear()
.domain(d3.extent(byteFrequency, d => d)) .domain(d3.extent(byteFrequency, d => d))
@ -240,7 +233,7 @@ class AdvancedEntropy extends Operation {
.data(byteFrequency) .data(byteFrequency)
.enter().append("rect") .enter().append("rect")
.attr("x", (_, i) => xScale(i) + binWidth) .attr("x", (_, i) => xScale(i) + binWidth)
.attr("y", (dataPoint) => yScale(dataPoint)) .attr("y", dataPoint => yScale(dataPoint))
.attr("width", binWidth) .attr("width", binWidth)
.attr("height", dataPoint => yScale(0) - yScale(dataPoint)) .attr("height", dataPoint => yScale(0) - yScale(dataPoint))
.attr("fill", "blue"); .attr("fill", "blue");
@ -252,13 +245,13 @@ class AdvancedEntropy extends Operation {
/** /**
* Creates a byte frequency histogram * Creates a byte frequency histogram
* *
* @param {byteArray} input * @param {byteArray} input
* @param {number} blockSize * @param {number} blockSize
* @returns {HTML} * @returns {HTML}
*/ */
createEntropyCurve(input) { createEntropyCurve(entropyData) {
const { entropyData, binWidth } = this.calculateScanningEntropy(input); const margins = { top: 30, right: 20, bottom: 50, left: 30 };
const svgWidth = 500, const svgWidth = 500,
svgHeight = 500; svgHeight = 500;
@ -270,8 +263,6 @@ class AdvancedEntropy extends Operation {
.attr("height", "100%") .attr("height", "100%")
.attr("viewBox", `0 0 ${svgWidth} ${svgHeight}`); .attr("viewBox", `0 0 ${svgWidth} ${svgHeight}`);
const margins = {top: 30, right: 20, bottom: 50, left: 30};
const yScale = d3.scaleLinear() const yScale = d3.scaleLinear()
.domain([0, d3.max(entropyData, d => d)]) .domain([0, d3.max(entropyData, d => d)])
.range([svgHeight - margins.bottom, margins.top]); .range([svgHeight - margins.bottom, margins.top]);
@ -281,37 +272,35 @@ class AdvancedEntropy extends Operation {
.range([margins.left, svgWidth - margins.right]); .range([margins.left, svgWidth - margins.right]);
const line = d3.line() const line = d3.line()
.x((d, i) => { return xScale(i)}) .x((_, i) => xScale(i))
.y((d) => { return yScale(d)}) .y(d => yScale(d))
.curve(d3.curveMonotoneX); .curve(d3.curveMonotoneX);
if (entropyData.length > 0 ) { if (entropyData.length > 0) {
svg.append('path') svg.append("path")
.datum(entropyData) .datum(entropyData)
.attr("d", line); .attr("d", line);
svg.selectAll("path").attr("fill", "none").attr("stroke", "steelblue"); svg.selectAll("path").attr("fill", "none").attr("stroke", "steelblue");
} }
this.createAxes(svg, xScale, yScale, svgHeight, svgWidth, margins, "Scanning Entropy" , `Block (${binWidth}B)`, "Entropy"); this.createAxes(svg, xScale, yScale, svgHeight, svgWidth, margins, "Scanning Entropy", "Block", "Entropy");
return svg._groups[0][0].outerHTML; return svg._groups[0][0].outerHTML;
} }
/** /**
* Creates an image representation of the entropy * Creates an image representation of the entropy
* *
* @param {byteArray} input * @param {byteArray} input
* @param {number} blockSize * @param {number} blockSize
* @returns {HTML} * @returns {HTML}
*/ */
createEntropyImage(inputBytes) { createEntropyImage(entropyData) {
const svgHeight = 100, const svgHeight = 100,
svgWidth = 100, svgWidth = 100,
cellSize = 1, cellSize = 1,
nodes = []; nodes = [];
const { entropyData } = this.calculateScanningEntropy(inputBytes, svgWidth*svgHeight);
for (let i = 0; i < entropyData.length; i++) { for (let i = 0; i < entropyData.length; i++) {
nodes.push({ nodes.push({
@ -337,11 +326,11 @@ class AdvancedEntropy extends Operation {
.selectAll("rect") .selectAll("rect")
.data(nodes) .data(nodes)
.enter().append("rect") .enter().append("rect")
.attr("x", (d, i) => d.x * cellSize) .attr("x", d => d.x * cellSize)
.attr("y", (d, i) => d.y * cellSize) .attr("y", d => d.y * cellSize)
.attr("width", cellSize) .attr("width", cellSize)
.attr("height", cellSize) .attr("height", cellSize)
.style("fill", (d) => greyScale(d.entropy)) .style("fill", d => greyScale(d.entropy));
return svg._groups[0][0].outerHTML; return svg._groups[0][0].outerHTML;
} }
@ -351,21 +340,18 @@ class AdvancedEntropy extends Operation {
* @param {Object[]} args * @param {Object[]} args
* @returns {html} * @returns {html}
*/ */
run(input, args) { run(input, args) {
const visualizationType = args[0]; const visualizationType = args[0];
const entropyData = { if (visualizationType === "Histogram (Bar)") {
entropy: this.calculateShannonEntropy(input), return this.createByteFrequencyBarHistogram(this.calculateByteFrequency(input));
byteFrequency: this.calculateByteFrequency(input) } else if (visualizationType === "Histogram (Line)") {
}; return this.createByteFrequencyLineHistogram(this.calculateByteFrequency(input));
} else if (visualizationType === "Curve") {
let svgData; return this.createEntropyCurve(this.calculateScanningEntropy(input).entropyData);
if (visualizationType === "Histogram (Bar)") svgData = this.createByteFrequencyBarHistogram(entropyData); } else if (visualizationType === "Image") {
else if (visualizationType === "Histogram (Line)") svgData = this.createByteFrequencyLineHistogram(entropyData); return this.createEntropyImage(this.calculateScanningEntropy(input, 10000).entropyData);
else if (visualizationType === "Curve") svgData = this.createEntropyCurve(input); }
else if (visualizationType === "Image") svgData = this.createEntropyImage(input);
return svgData;
} }
} }