Skip to content

Commit 404a331

Browse files
committed
feat: repeated deobfuscation
1 parent 646b724 commit 404a331

File tree

3 files changed

+45
-33
lines changed

3 files changed

+45
-33
lines changed
+40-33
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import type * as t from '@babel/types';
12
import debug from 'debug';
23
import type { AsyncTransform } from '../ast-utils';
34
import {
@@ -30,46 +31,52 @@ export default {
3031
if (!sandbox) return;
3132

3233
const logger = debug('webcrack:deobfuscate');
33-
const stringArray = findStringArray(ast);
34-
logger(
35-
stringArray
36-
? `String Array: ${stringArray.length} strings`
37-
: 'String Array: no',
38-
);
39-
if (!stringArray) return;
34+
const visitedStringArrays = new Set<t.Node>();
4035

41-
const rotator = findArrayRotator(stringArray);
42-
logger(`String Array Rotate: ${rotator ? 'yes' : 'no'}`);
36+
while (true) {
37+
const stringArray = findStringArray(ast);
38+
logger(
39+
stringArray
40+
? `String Array: ${stringArray.length} strings`
41+
: 'String Array: no',
42+
);
43+
if (!stringArray) break;
44+
if (visitedStringArrays.has(stringArray.path.node)) break;
45+
visitedStringArrays.add(stringArray.path.node);
4346

44-
const decoders = findDecoders(stringArray);
45-
logger(`String Array Encodings: ${decoders.length}`);
47+
const rotator = findArrayRotator(stringArray);
48+
logger(`String Array Rotate: ${rotator ? 'yes' : 'no'}`);
4649

47-
state.changes += applyTransform(ast, inlineObjectProps).changes;
50+
const decoders = findDecoders(stringArray);
51+
logger(`String Array Encodings: ${decoders.length}`);
4852

49-
for (const decoder of decoders) {
50-
state.changes += applyTransform(
51-
ast,
52-
inlineDecoderWrappers,
53-
decoder.path,
53+
state.changes += applyTransform(ast, inlineObjectProps).changes;
54+
55+
for (const decoder of decoders) {
56+
state.changes += applyTransform(
57+
ast,
58+
inlineDecoderWrappers,
59+
decoder.path,
60+
).changes;
61+
}
62+
63+
const vm = new VMDecoder(sandbox, stringArray, decoders, rotator);
64+
state.changes += (
65+
await applyTransformAsync(ast, inlineDecodedStrings, { vm })
5466
).changes;
55-
}
5667

57-
const vm = new VMDecoder(sandbox, stringArray, decoders, rotator);
58-
state.changes += (
59-
await applyTransformAsync(ast, inlineDecodedStrings, { vm })
60-
).changes;
68+
if (decoders.length > 0) {
69+
stringArray.path.remove();
70+
rotator?.remove();
71+
decoders.forEach((decoder) => decoder.path.remove());
72+
state.changes += 2 + decoders.length;
73+
}
6174

62-
if (decoders.length > 0) {
63-
stringArray.path.remove();
64-
rotator?.remove();
65-
decoders.forEach((decoder) => decoder.path.remove());
66-
state.changes += 2 + decoders.length;
75+
state.changes += applyTransforms(
76+
ast,
77+
[mergeStrings, deadCode, controlFlowObject, controlFlowSwitch],
78+
{ noScope: true },
79+
).changes;
6780
}
68-
69-
state.changes += applyTransforms(
70-
ast,
71-
[mergeStrings, deadCode, controlFlowObject, controlFlowSwitch],
72-
{ noScope: true },
73-
).changes;
7481
},
7582
} satisfies AsyncTransform<Sandbox>;

packages/webcrack/src/deobfuscate/test/samples/obfuscator.io-multiple-passes.js

+1
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
function hi() {
2+
console.log("Hello World!");
3+
}
4+
hi();

0 commit comments

Comments
 (0)