Skip to content

Commit 8f5c6fa

Browse files
committed
DuplicateLiteralsRemoval
1 parent b1b2f50 commit 8f5c6fa

File tree

1 file changed

+116
-4
lines changed

1 file changed

+116
-4
lines changed

src/plugin/jsconfuser.js

Lines changed: 116 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,6 @@ const t = require('@babel/types')
55
const ivm = require('isolated-vm')
66

77
const isolate = new ivm.Isolate()
8-
const globalContext = isolate.createContextSync()
9-
function virtualGlobalEval(jsStr) {
10-
return globalContext.evalSync(String(jsStr))
11-
}
128

139
const collect_id = {
1410
arrowFunc: null,
@@ -148,6 +144,120 @@ const deMinifyArrow = {
148144
},
149145
}
150146

147+
function checkArrayName(path) {
148+
if (path.key !== 'argument') {
149+
return null
150+
}
151+
const ret_path = path.parentPath
152+
if (!ret_path.isReturnStatement() || ret_path.key !== 0) {
153+
return null
154+
}
155+
const array_fn_path = ret_path.getFunctionParent()
156+
const array_fn_name = array_fn_path.node.id?.name
157+
if (!array_fn_name) {
158+
return null
159+
}
160+
const binding = array_fn_path.parentPath.scope.bindings[array_fn_name]
161+
if (binding.references !== 1) {
162+
return null
163+
}
164+
let ref = binding.referencePaths[0]
165+
while (ref && !ref.isAssignmentExpression()) {
166+
ref = ref.parentPath
167+
}
168+
if (!ref) {
169+
return null
170+
}
171+
const array_name = ref.node.left?.name
172+
if (!array_name) {
173+
return null
174+
}
175+
return {
176+
func_name: array_fn_name,
177+
func_path: array_fn_path,
178+
array_name: array_name,
179+
array_path: ref,
180+
}
181+
}
182+
183+
function parseArrayWarp(vm, path) {
184+
let func = path.getFunctionParent(path)
185+
let name = null
186+
let binding = null
187+
if (func.isArrowFunctionExpression()) {
188+
func = func.parentPath
189+
name = func.node.id.name
190+
binding = func.scope.getBinding(name)
191+
} else {
192+
name = func.node.id.name
193+
binding = func.parentPath.scope.getBinding(name)
194+
}
195+
console.log(`Process array warp function: ${name}`)
196+
vm.evalSync(generator(func.node).code)
197+
for (const ref of binding.referencePaths) {
198+
const call = ref.parentPath
199+
if (ref.key !== 'callee') {
200+
console.warn(`Unexpected ref of array warp function: ${call}`)
201+
continue
202+
}
203+
const ret = vm.evalSync(generator(call.node).code)
204+
if (typeof ret === 'string') {
205+
call.replaceWith(t.stringLiteral(ret))
206+
} else {
207+
call.replaceWithSourceString(ret)
208+
}
209+
}
210+
binding.scope.crawl()
211+
binding = binding.scope.getBinding(name)
212+
if (!binding.references) {
213+
func.remove()
214+
}
215+
}
216+
217+
/**
218+
* Template:
219+
* ```javascript
220+
* var arrayName = getArrayFn()
221+
* function getArrayFn (){
222+
* return [...arrayExpression]
223+
* }
224+
* ```
225+
*/
226+
const deDuplicateLiteral = {
227+
ArrayExpression(path) {
228+
let obj = checkArrayName(path)
229+
if (!obj) {
230+
return
231+
}
232+
console.log(`Find arrayName: ${obj.array_name}`)
233+
let decl_node = t.variableDeclarator(
234+
obj.array_path.node.left,
235+
obj.array_path.node.right
236+
)
237+
decl_node = t.variableDeclaration('var', [decl_node])
238+
const code = [generator(obj.func_path.node).code, generator(decl_node).code]
239+
let binding = obj.array_path.scope.getBinding(obj.array_name)
240+
for (const ref of binding.referencePaths) {
241+
const vm = isolate.createContextSync()
242+
vm.evalSync(code[0])
243+
vm.evalSync(code[1])
244+
parseArrayWarp(vm, ref)
245+
}
246+
binding.scope.crawl()
247+
binding = binding.scope.bindings[obj.array_name]
248+
if (!binding.references) {
249+
obj.array_path.remove()
250+
binding.path.remove()
251+
}
252+
binding = obj.func_path.parentPath.scope.getBinding(obj.func_name)
253+
binding.scope.crawl()
254+
binding = binding.scope.getBinding(obj.func_name)
255+
if (!binding.references) {
256+
obj.func_path.remove()
257+
}
258+
},
259+
}
260+
151261
function checkFuncLen(path) {
152262
if (path.node?.name !== 'configurable' || path.key !== 'key') {
153263
return null
@@ -222,6 +332,8 @@ module.exports = function (code) {
222332
traverse(ast, deAntiTooling)
223333
// Minify
224334
traverse(ast, deMinifyArrow)
335+
// DuplicateLiteralsRemoval
336+
traverse(ast, deDuplicateLiteral)
225337
// Stack
226338
traverse(ast, deStackFuncLen)
227339
code = generator(ast, {

0 commit comments

Comments
 (0)