Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(analysis) : rename 'analysis' variable to 'sourceFile' #232

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/ProbeRunner.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ export class ProbeRunner {

if (isMatching) {
return probe.main(node, {
analysis: this.sourceFile,
sourceFile: this.sourceFile,
data
});
}
Expand Down Expand Up @@ -144,7 +144,7 @@ export class ProbeRunner {
}
finally {
if (probe.teardown) {
probe.teardown({ analysis: this.sourceFile });
probe.teardown({ sourceFile: this.sourceFile });
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/obfuscators/freejsobfuscator.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
// Import Third-party Dependencies
import { Utils } from "@nodesecure/sec-literal";

export function verify(analysis, prefix) {
export function verify(sourceFile, prefix) {
const pValue = Object.keys(prefix).pop();
const regexStr = `^${Utils.escapeRegExp(pValue)}[a-zA-Z]{1,2}[0-9]{0,2}$`;

return analysis.identifiersName.every(({ name }) => new RegExp(regexStr).test(name));
return sourceFile.identifiersName.every(({ name }) => new RegExp(regexStr).test(name));
}
26 changes: 13 additions & 13 deletions src/obfuscators/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,21 @@ import * as trojan from "./trojan-source.js";
// CONSTANTS
const kMinimumIdsCount = 5;

export function isObfuscatedCode(analysis) {
export function isObfuscatedCode(sourceFile) {
let encoderName = null;

if (jsfuck.verify(analysis)) {
if (jsfuck.verify(sourceFile)) {
encoderName = "jsfuck";
}
else if (jjencode.verify(analysis)) {
else if (jjencode.verify(sourceFile)) {
encoderName = "jjencode";
}
else if (analysis.morseLiterals.size >= 36) {
else if (sourceFile.morseLiterals.size >= 36) {
encoderName = "morse";
}
else {
// TODO: also implement Dictionnary checkup
const identifiers = analysis.identifiersName
const identifiers = sourceFile.identifiersName
.map((value) => value?.name ?? null)
.filter((name) => typeof name === "string");

Expand All @@ -34,18 +34,18 @@ export function isObfuscatedCode(analysis) {
);
const uPrefixNames = new Set(Object.keys(prefix));

if (analysis.counter.identifiers > kMinimumIdsCount && uPrefixNames.size > 0) {
analysis.hasPrefixedIdentifiers = calcAvgPrefixedIdentifiers(analysis, prefix) > 80;
if (sourceFile.counter.identifiers > kMinimumIdsCount && uPrefixNames.size > 0) {
sourceFile.hasPrefixedIdentifiers = calcAvgPrefixedIdentifiers(sourceFile, prefix) > 80;
}

if (uPrefixNames.size === 1 && freejsobfuscator.verify(analysis, prefix)) {
if (uPrefixNames.size === 1 && freejsobfuscator.verify(sourceFile, prefix)) {
encoderName = "freejsobfuscator";
}
else if (obfuscatorio.verify(analysis)) {
else if (obfuscatorio.verify(sourceFile)) {
encoderName = "obfuscator.io";
}
// else if ((analysis.counter.identifiers > (kMinimumIdsCount * 3) && analysis.hasPrefixedIdentifiers)
// && (oneTimeOccurence <= 3 || analysis.counter.encodedArrayValue > 0)) {
// else if ((sourceFile.counter.identifiers > (kMinimumIdsCount * 3) && sourceFile.hasPrefixedIdentifiers)
// && (oneTimeOccurence <= 3 || sourceFile.counter.encodedArrayValue > 0)) {
// encoderName = "unknown";
// }
}
Expand All @@ -57,13 +57,13 @@ export function hasTrojanSource(sourceString) {
return trojan.verify(sourceString);
}

function calcAvgPrefixedIdentifiers(analysis, prefix) {
function calcAvgPrefixedIdentifiers(sourceFile, prefix) {
const valuesArr = Object.values(prefix).slice().sort((left, right) => left - right);
if (valuesArr.length === 0) {
return 0;
}
const nbOfPrefixedIds = valuesArr.length === 1 ? valuesArr.pop() : (valuesArr.pop() + valuesArr.pop());
const maxIds = analysis.counter.identifiers - analysis.idtypes.property;
const maxIds = sourceFile.counter.identifiers - sourceFile.idtypes.property;

return ((nbOfPrefixedIds / maxIds) * 100);
}
10 changes: 5 additions & 5 deletions src/obfuscators/jjencode.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,23 @@ import { notNullOrUndefined } from "../utils/index.js";
// CONSTANTS
const kJJRegularSymbols = new Set(["$", "_"]);

export function verify(analysis) {
if (analysis.counter.variableDeclarator > 0 || analysis.counter.functionDeclaration > 0) {
export function verify(sourceFile) {
if (sourceFile.counter.variableDeclarator > 0 || sourceFile.counter.functionDeclaration > 0) {
return false;
}
if (analysis.idtypes.assignExpr > analysis.idtypes.property) {
if (sourceFile.idtypes.assignExpr > sourceFile.idtypes.property) {
return false;
}

const matchCount = analysis.identifiersName.filter(({ name }) => {
const matchCount = sourceFile.identifiersName.filter(({ name }) => {
if (!notNullOrUndefined(name)) {
return false;
}
const charsCode = [...new Set([...name])];

return charsCode.every((char) => kJJRegularSymbols.has(char));
}).length;
const pourcent = ((matchCount / analysis.identifiersName.length) * 100);
const pourcent = ((matchCount / sourceFile.identifiersName.length) * 100);

return pourcent > 80;
}
Expand Down
12 changes: 6 additions & 6 deletions src/obfuscators/jsfuck.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
// CONSTANTS
const kJSFuckMinimumDoubleUnaryExpr = 5;

export function verify(analysis) {
const hasZeroAssign = analysis.idtypes.assignExpr === 0
&& analysis.idtypes.functionDeclaration === 0
&& analysis.idtypes.property === 0
&& analysis.idtypes.variableDeclarator === 0;
export function verify(sourceFile) {
const hasZeroAssign = sourceFile.idtypes.assignExpr === 0
&& sourceFile.idtypes.functionDeclaration === 0
&& sourceFile.idtypes.property === 0
&& sourceFile.idtypes.variableDeclarator === 0;

return hasZeroAssign && analysis.counter.doubleUnaryArray >= kJSFuckMinimumDoubleUnaryExpr;
return hasZeroAssign && sourceFile.counter.doubleUnaryArray >= kJSFuckMinimumDoubleUnaryExpr;
}
14 changes: 7 additions & 7 deletions src/obfuscators/obfuscator-io.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
export function verify(analysis) {
if (analysis.counter.memberExpr > 0) {
export function verify(sourceFile) {
if (sourceFile.counter.memberExpr > 0) {
return false;
}

const hasSomePatterns = analysis.counter.doubleUnaryArray > 0
|| analysis.counter.deepBinaryExpr > 0
|| analysis.counter.encodedArrayValue > 0
|| analysis.hasDictionaryString;
const hasSomePatterns = sourceFile.counter.doubleUnaryArray > 0
|| sourceFile.counter.deepBinaryExpr > 0
|| sourceFile.counter.encodedArrayValue > 0
|| sourceFile.hasDictionaryString;

// TODO: hasPrefixedIdentifiers only work for hexadecimal id names generator
return analysis.hasPrefixedIdentifiers && hasSomePatterns;
return sourceFile.hasPrefixedIdentifiers && hasSomePatterns;
}
4 changes: 2 additions & 2 deletions src/probes/isArrayExpression.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ function validateNode(node) {
];
}

function main(node, { analysis }) {
function main(node, { sourceFile }) {
kLiteralExtractor(
(literalNode) => analysis.analyzeLiteral(literalNode, true),
(literalNode) => sourceFile.analyzeLiteral(literalNode, true),
node.elements
);
}
Expand Down
6 changes: 3 additions & 3 deletions src/probes/isAssignmentExpression.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ function validateNode(node) {
}

function main(node, options) {
const { analysis } = options;
const { sourceFile } = options;

analysis.idtypes.assignExpr++;
sourceFile.idtypes.assignExpr++;
for (const { name } of getVariableDeclarationIdentifiers(node.left)) {
analysis.identifiersName.push({ name, type: "assignExpr" });
sourceFile.identifiersName.push({ name, type: "assignExpr" });
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/probes/isBinaryExpression.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ function validateNode(node) {
}

function main(node, options) {
const { analysis } = options;
const { sourceFile } = options;

const [binaryExprDeepness, hasUnaryExpression] = walkBinaryExpression(node);
if (binaryExprDeepness >= 3 && hasUnaryExpression) {
analysis.counter.deepBinaryExpr++;
sourceFile.counter.deepBinaryExpr++;
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/probes/isClassDeclaration.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ function validateNode(node) {
}

function main(node, options) {
const { analysis } = options;
const { sourceFile } = options;

kIdExtractor(
({ name }) => analysis.identifiersName.push({ name, type: "class" }),
({ name }) => sourceFile.identifiersName.push({ name, type: "class" }),
[node.id, node.superClass]
);
}
Expand Down
8 changes: 4 additions & 4 deletions src/probes/isFunction.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,18 @@ function validateNode(node) {
}

function main(node, options) {
const { analysis } = options;
const { sourceFile } = options;

kIdExtractor(
({ name }) => analysis.identifiersName.push({ name, type: "params" }),
({ name }) => sourceFile.identifiersName.push({ name, type: "params" }),
node.params
);

if (node.id === null || node.id.type !== "Identifier") {
return;
}
analysis.idtypes.functionDeclaration++;
analysis.identifiersName.push({ name: node.id.name, type: "functionDeclaration" });
sourceFile.idtypes.functionDeclaration++;
sourceFile.identifiersName.push({ name: node.id.name, type: "functionDeclaration" });
}

export default {
Expand Down
6 changes: 3 additions & 3 deletions src/probes/isImportDeclaration.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@ function validateNode(node) {
}

function main(node, options) {
const { analysis } = options;
const { sourceFile } = options;

// Searching for dangerous import "data:text/javascript;..." statement.
// see: https://2ality.com/2019/10/eval-via-import.html
if (node.source.value.startsWith("data:text/javascript")) {
analysis.addWarning("unsafe-import", node.source.value, node.loc);
sourceFile.addWarning("unsafe-import", node.source.value, node.loc);
}
analysis.addDependency(node.source.value, node.loc);
sourceFile.addDependency(node.source.value, node.loc);
}

export default {
Expand Down
14 changes: 7 additions & 7 deletions src/probes/isLiteral.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,34 +24,34 @@ function validateNode(node) {
}

function main(node, options) {
const { analysis } = options;
const { sourceFile } = options;

// We are searching for value obfuscated as hex of a minimum length of 4.
if (/^[0-9A-Fa-f]{4,}$/g.test(node.value)) {
const value = Buffer.from(node.value, "hex").toString();
analysis.analyzeString(value);
sourceFile.analyzeString(value);

// If the value we are retrieving is the name of a Node.js dependency,
// then we add it to the dependencies list and we throw an unsafe-import at the current location.
if (kNodeDeps.has(value)) {
analysis.addDependency(value, node.loc);
analysis.addWarning("unsafe-import", null, node.loc);
sourceFile.addDependency(value, node.loc);
sourceFile.addWarning("unsafe-import", null, node.loc);
}
else if (value === "require" || !Hex.isSafe(node.value)) {
analysis.addWarning("encoded-literal", node.value, node.loc);
sourceFile.addWarning("encoded-literal", node.value, node.loc);
}
}
// Else we are checking all other string with our suspect method
else {
for (const regex of kShadyLinkRegExps) {
if (regex.test(node.value)) {
analysis.addWarning("shady-link", node.value, node.loc);
sourceFile.addWarning("shady-link", node.value, node.loc);

return;
}
}

analysis.analyzeLiteral(node);
sourceFile.analyzeLiteral(node);
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/probes/isLiteralRegex.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ function validateNode(node) {
}

function main(node, options) {
const { analysis } = options;
const { sourceFile } = options;

// We use the safe-regex package to detect whether or not regex is safe!
if (!safeRegex(node.regex.pattern)) {
analysis.addWarning("unsafe-regex", node.regex.pattern, node.loc);
sourceFile.addWarning("unsafe-regex", node.regex.pattern, node.loc);
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/probes/isMemberExpression.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ function validateNode(node) {
}

function main(node, options) {
const { analysis } = options;
const { sourceFile } = options;

analysis.counter[node.computed ? "computedMemberExpr" : "memberExpr"]++;
sourceFile.counter[node.computed ? "computedMemberExpr" : "memberExpr"]++;
}

export default {
Expand Down
4 changes: 2 additions & 2 deletions src/probes/isMethodDefinition.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ function validateNode(node) {
}

function main(node, options) {
const { analysis } = options;
const { sourceFile } = options;

kIdExtractor(
({ name }) => analysis.identifiersName.push({ name, type: "method" }),
({ name }) => sourceFile.identifiersName.push({ name, type: "method" }),
[node.key]
);
}
Expand Down
6 changes: 3 additions & 3 deletions src/probes/isObjectExpression.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ function validateNode(node) {
}

function main(node, options) {
const { analysis } = options;
const { sourceFile } = options;

for (const property of node.properties) {
if (property.type !== "Property" || property.key.type !== "Identifier") {
continue;
}

analysis.idtypes.property++;
analysis.identifiersName.push({ name: property.key.name, type: "property" });
sourceFile.idtypes.property++;
sourceFile.identifiersName.push({ name: property.key.name, type: "property" });
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/probes/isRegexObject.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ function validateNode(node) {
}

function main(node, options) {
const { analysis } = options;
const { sourceFile } = options;

const arg = node.arguments[0];
/**
Expand All @@ -29,7 +29,7 @@ function main(node, options) {

// We use the safe-regex package to detect whether or not regex is safe!
if (!safeRegex(pattern)) {
analysis.addWarning("unsafe-regex", pattern, node.loc);
sourceFile.addWarning("unsafe-regex", pattern, node.loc);
}
}

Expand Down
Loading
Loading