UNPKG

restringer

Version:

Deobfuscate Javascript with emphasis on reconstructing strings

42 lines (40 loc) 1.83 kB
import {areReferencesModified} from '../utils/areReferencesModified.js'; import {doesDescendantMatchCondition} from '../utils/doesDescendantMatchCondition.js'; import {getMainDeclaredObjectOfMemberExpression} from '../utils/getMainDeclaredObjectOfMemberExpression.js'; /** * Replace variables which only point at other variables and do not change, with their target. * E.g. * const a = [...]; * const b = a; * const c = b[0]; // <-- will be replaced with `const c = a[0];` * @param {Arborist} arb * @param {Function} candidateFilter (optional) a filter to apply on the candidates list * @return {Arborist} */ function resolveProxyReferences(arb, candidateFilter = () => true) { const relevantNodes = [ ...(arb.ast[0].typeMap.VariableDeclarator || []), ]; for (let i = 0; i < relevantNodes.length; i++) { const n = relevantNodes[i]; if (['Identifier', 'MemberExpression'].includes(n.id.type) && ['Identifier', 'MemberExpression'].includes(n.init?.type) && !/For.*Statement/.test(n.parentNode?.parentNode?.type) && candidateFilter(n)) { const relevantIdentifier = getMainDeclaredObjectOfMemberExpression(n.id)?.declNode || n.id; const refs = relevantIdentifier.references || []; const replacementNode = n.init; const replacementMainIdentifier = getMainDeclaredObjectOfMemberExpression(n.init)?.declNode; if (replacementMainIdentifier && replacementMainIdentifier === relevantIdentifier) continue; // Exclude changes in the identifier's own init if (doesDescendantMatchCondition(n.init, n => n === relevantIdentifier)) continue; if (refs.length && !areReferencesModified(arb.ast, refs) && !areReferencesModified(arb.ast, [replacementNode])) { for (const ref of refs) { arb.markNode(ref, replacementNode); } } } } return arb; } export default resolveProxyReferences;