restringer
Version:
Deobfuscate Javascript with emphasis on reconstructing strings
36 lines (34 loc) • 1.3 kB
JavaScript
import {badValue} from '../config.js';
import {Sandbox} from '../utils/sandbox.js';
import {evalInVm} from '../utils/evalInVm.js';
/**
* Replace definite member expressions with their intended value.
* E.g.
* '123'[0]; ==> '1';
* 'hello'.length ==> 5;
* @param {Arborist} arb
* @param {Function} candidateFilter (optional) a filter to apply on the candidates list
* @return {Arborist}
*/
function resolveDefiniteMemberExpressions(arb, candidateFilter = () => true) {
let sharedSb;
const relevantNodes = [
...(arb.ast[0].typeMap.MemberExpression || []),
];
for (let i = 0; i < relevantNodes.length; i++) {
const n = relevantNodes[i];
if (!['UpdateExpression'].includes(n.parentNode.type) && // Prevent replacing (++[[]][0]) with (++1)
!(n.parentKey === 'callee') && // Prevent replacing obj.method() with undefined()
(n.property.type === 'Literal' ||
(n.property.name && !n.computed)) &&
['ArrayExpression', 'Literal'].includes(n.object.type) &&
(n.object?.value?.length || n.object?.elements?.length) &&
candidateFilter(n)) {
sharedSb = sharedSb || new Sandbox();
const replacementNode = evalInVm(n.src, sharedSb);
if (replacementNode !== badValue) arb.markNode(n, replacementNode);
}
}
return arb;
}
export default resolveDefiniteMemberExpressions;