Skip to content

Commit

Permalink
obfuscator: fix bug in decodeObject
Browse files Browse the repository at this point in the history
In some enhanced/modified obfuscators, some variable names may not be unique throughout the program. 
This commit limits the processing and validation of the object to its own scope, thus avoiding inappropriate replacement or deletion.

Signed-off-by: echo094 <[email protected]>
  • Loading branch information
echo094 authored Feb 24, 2024
1 parent 48b4739 commit 278668d
Showing 1 changed file with 28 additions and 42 deletions.
70 changes: 28 additions & 42 deletions src/plugin/obfuscator.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,19 @@ function virtualGlobalEval(jsStr) {
return vm2.run(String(jsStr))
}

/**
* Extract the literal value of an object, and remove an object if all
* references to the object are replaced.
*/
function decodeObject(ast) {
let obj_node = {}
function collectObject(path) {
const id = path.node.id
const init = path.node.init
if (!t.isIdentifier(id) || !t.isObjectExpression(init)) {
return
}
const name = id.name
const obj_name = id.name
const bind = path.scope.getBinding(obj_name)
let valid = true
let count = 0
let obj = {}
Expand All @@ -46,50 +50,32 @@ function decodeObject(ast) {
if (!valid || !count) {
return
}
obj_node[name] = obj
}
traverse(ast, {
VariableDeclarator: collectObject,
})
let obj_used = {}
function replaceObject(path) {
const name = path.node.object
const key = path.node.property
if (!t.isIdentifier(name) || !t.isIdentifier(key)) {
return
}
if (!Object.prototype.hasOwnProperty.call(obj_node, name.name)) {
return
}
if (t.isIdentifier(key) && path.node.computed) {
// In this case, the identifier points to another value
return
}
path.replaceWith(obj_node[name.name][key.name])
obj_used[name.name] = true
}
traverse(ast, {
MemberExpression: replaceObject,
})
function deleteObject(path) {
const id = path.node.id
const init = path.node.init
if (!t.isIdentifier(id) || !t.isObjectExpression(init)) {
return
}
const name = id.name
if (!Object.prototype.hasOwnProperty.call(obj_node, name)) {
return
let safe = true
for (let ref of bind.referencePaths) {
const parent = ref.parentPath
if (ref.key !== 'object' || !parent.isMemberExpression()) {
safe = false
continue
}
const key = parent.node.property
if (!t.isIdentifier(key) || parent.node.computed) {
safe = false
continue
}
if (Object.prototype.hasOwnProperty.call(obj, key.name)) {
parent.replaceWith(obj[key.name])
} else {
safe = false
}
}
path.remove()
let used = 'false'
if (Object.prototype.hasOwnProperty.call(obj_used, name)) {
used = 'true'
bind.scope.crawl()
if (safe) {
path.remove()
console.log(`删除对象: ${obj_name}`)
}
console.log(`删除对象: ${name} -> ${used}`)
}
traverse(ast, {
VariableDeclarator: deleteObject,
VariableDeclarator: collectObject,
})
return ast
}
Expand Down

0 comments on commit 278668d

Please sign in to comment.