Skip to content

Commit

Permalink
feat: evaluate atob, unescape, decodeURI and `decodeURIComponen…
Browse files Browse the repository at this point in the history
…t` calls (#53)
  • Loading branch information
j4k0xb committed Aug 16, 2024
1 parent e426513 commit 65e4c72
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 1 deletion.
46 changes: 46 additions & 0 deletions packages/webcrack/src/deobfuscate/evaluate-globals.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import * as t from '@babel/types';
import * as m from '@codemod/matchers';
import type { Transform } from '../ast-utils';

const FUNCTIONS = {
atob,
unescape,
decodeURI,
decodeURIComponent,
};

export default {
name: 'evaluate-globals',
tags: ['safe'],
scope: true,
visitor() {
const name = m.capture(
m.or(...(Object.keys(FUNCTIONS) as (keyof typeof FUNCTIONS)[])),
);
const arg = m.capture(m.anyString());
const matcher = m.callExpression(m.identifier(name), [
m.stringLiteral(arg),
]);

return {
CallExpression: {
exit(path) {
if (!matcher.match(path.node)) return;
if (path.scope.hasBinding(name.current!, { noGlobals: true })) return;

try {
// Causes a "TypeError: Illegal invocation" without the globalThis receiver
const value = FUNCTIONS[name.current!].call(
globalThis,
arg.current!,
);
path.replaceWith(t.stringLiteral(value));
this.changes++;
} catch {
// ignore
}
},
},
};
},
} satisfies Transform;
20 changes: 20 additions & 0 deletions packages/webcrack/src/deobfuscate/test/evaluate-globals.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { test } from 'vitest';
import { testTransform } from '../../../test/index';
import evaluateGlobals from '../evaluate-globals';

const expectJS = testTransform(evaluateGlobals);

test('atob', () =>
expectJS('atob("aGVsbG8=")').toMatchInlineSnapshot('"hello";'));

test('atob that throws', () =>
expectJS('atob("-")').toMatchInlineSnapshot(`atob("-");`));

test('unescape', () =>
expectJS('unescape("%41")').toMatchInlineSnapshot('"A";'));

test('decodeURI', () =>
expectJS('decodeURI("%41")').toMatchInlineSnapshot('"A";'));

test('decodeURIComponent', () =>
expectJS('decodeURIComponent("%41")').toMatchInlineSnapshot('"A";'));
4 changes: 3 additions & 1 deletion packages/webcrack/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import deobfuscate, {
createNodeSandbox,
} from './deobfuscate';
import debugProtection from './deobfuscate/debug-protection';
import evaluateGlobals from './deobfuscate/evaluate-globals';
import mergeObjectAssignments from './deobfuscate/merge-object-assignments';
import selfDefending from './deobfuscate/self-defending';
import varFunctions from './deobfuscate/var-functions';
Expand Down Expand Up @@ -179,7 +180,8 @@ export async function webcrack(
].flat(),
);
}),
options.deobfuscate && (() => applyTransform(ast, mergeObjectAssignments)),
options.deobfuscate &&
(() => applyTransforms(ast, [mergeObjectAssignments, evaluateGlobals])),
() => (outputCode = generate(ast)),
// Unpacking modifies the same AST and may result in imports not at top level
// so the code has to be generated before
Expand Down

0 comments on commit 65e4c72

Please sign in to comment.