Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat options #4

Merged
merged 4 commits into from
Nov 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 6 additions & 19 deletions packages/utils/__tests__/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,29 +79,13 @@ for (void 0;;) {
expect(code).toBe('')
})

it('calcBoolean', () => {
const rawCode = `
let a = !![];
let b = ![] ;
`

const deob = new Deob(rawCode)

deob.calcBoolean()
const code = deob.getCode()

expect(code).toBe(
`
let a = true;
let b = false;
`.trim(),
)
})

it('calcBinary', () => {
const rawCode = `
let a = 1 + 2;
let b = "debu" + "gger"

let c = !![];
let d = ![] ;
`

const deob = new Deob(rawCode)
Expand All @@ -113,6 +97,9 @@ let b = false;
`
let a = 3;
let b = "debugger";

let c = true;
let d = false;
`.trim(),
)
})
Expand Down
93 changes: 42 additions & 51 deletions packages/utils/deob.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
global = window

const globalState = {
objectVariables: [],
objectVariables: {},
decryptFnList: [],
}

Expand Down Expand Up @@ -43,11 +43,14 @@
* @param {string} [options.dir] - 输出目录
* @param {boolean} [options.isWriteFile]
* @param {object} [options.opts] - 是否写入文件
* @param {boolean} [options.isLog] - 是否输出日志
* @throws {Error} 请载入js代码
*/
constructor(rawCode, options = {}) {
if (!rawCode)
throw new Error('请载入js代码')
console.clear()
console.log('start deob')
console.time('useTime')

/**
Expand All @@ -65,6 +68,7 @@

this.dir = options.dir ?? './'
this.isWriteFile = options.isWriteFile ?? false
this.isLog = options.isLog ?? true

try {
this.ast = parser.parse(rawCode, { sourceType: 'script' })
Expand All @@ -78,6 +82,10 @@
}
}

log(...args) {
this.isLog && console.log(...args)
}

get code() {
const code = generator(this.ast, this.opts).code
return code
Expand Down Expand Up @@ -164,27 +172,28 @@
*/
decryptReplace(ast, decryptFnCode) {
if (!decryptFnCode) {
console.log('无解密函数,已跳过')
this.log('无解密函数,已跳过')
return
}

// 执行解密函数的代码,这样就可以在 nodejs 中运行解密函数来还原数据
try {
console.log(`解密函数为: ${globalState.decryptFnList.join(',')}`)
console.log(`解密函数代码为: ${decryptFnCode}`)
this.log(`解密函数为: ${globalState.decryptFnList.join(',')}`)
// this.log(`解密函数代码为: ${decryptFnCode}`)
// eslint-disable-next-line no-eval
const result = global.eval(decryptFnCode)
console.log('解密函数执行结果:', result)
this.log('解密函数执行结果:', result)
}
catch (e) {
this.log(`解密函数代码为: ${decryptFnCode}`)
throw new Error('解密函数无法 eval 运行')
}

const map = new Map()
/**
* 执行数组乱序与解密函数代码并将混淆字符串数值还原
*
*/
const visitor_decString = {
traverse(ast, {
// 解密函数可能是 var _0x3e22 = function(){ } 或 function _0x3e22(){}
'VariableDeclarator|FunctionDeclaration': function (path) {
if (globalState.decryptFnList.includes(path.node.id.name)) {
Expand Down Expand Up @@ -213,7 +222,7 @@

// eslint-disable-next-line no-eval
const decStr = eval(callCode)
console.log(callCode, decStr)
map.set(callCode, decStr)

p.parentPath.replaceWith(t.stringLiteral(decStr))
}
Expand All @@ -226,9 +235,9 @@
})
}
},
}
})

traverse(ast, visitor_decString)
this.log('解密结果:', map)

this.reParse() // 切记一定要在替换后执行, 因为替换后此时 ast 并未更新, 就可能会导致后续处理都使用原先的 ast
}
Expand Down Expand Up @@ -368,7 +377,7 @@
* @description 输入解密函数代码
* TODO:
*/
InjectDecryptFnCode(decryptFnCode) { }

Check warning on line 380 in packages/utils/deob.js

View workflow job for this annotation

GitHub Actions / lint

'decryptFnCode' is defined but never used. Allowed unused args must match /^_/u

/**
* @description 嵌套函数花指令替换
Expand Down Expand Up @@ -506,10 +515,10 @@
* }
*/
saveAllObject() {
globalState.objectVariables = []
globalState.objectVariables = {}
traverse(this.ast, {
VariableDeclaration: {
exit(path, state) {

Check warning on line 521 in packages/utils/deob.js

View workflow job for this annotation

GitHub Actions / lint

'state' is defined but never used. Allowed unused args must match /^_/u
path.node.declarations.forEach((declaration) => {
if (declaration.id.type === 'Identifier') {
const variableName = declaration.id.name
Expand All @@ -521,7 +530,7 @@
},
},
})
console.log(`已保存所有对象`)
this.log(`已保存所有对象: `, Object.entries(globalState.objectVariables).map(([key, value]) => ({ key, value: generator(value).code })))
}

/**
Expand All @@ -543,7 +552,8 @@
*/
objectMemberReplace() {
// 记录被替换的对象, 如何对象没被修改过则删除
const replaceObjects = new Set()
const set = new Set()
const map = new Map()

// 先执行 _0x52627b["QqaUY"] ---> "attribute"
traverse(this.ast, {
Expand Down Expand Up @@ -590,9 +600,8 @@
&& binding.constant
&& binding.constantViolations.length === 0
) {
console.log(objectName, propertyName)

replaceObjects.add(objectName)
map.set(`${objectName}.${propertyName}`, generator(prop.value).code)
set.add(objectName)

path.replaceWith(prop.value)
}
Expand Down Expand Up @@ -647,7 +656,7 @@
if (!(firstStatement?.type === 'ReturnStatement'))
return

console.log(objectName, propertyName)
map.set(`${objectName}.${propertyName}`, generator(orgFn).code)

// 返回参数
const returnArgument = firstStatement.argument
Expand Down Expand Up @@ -710,7 +719,7 @@
}

if (isReplace)
replaceObjects.add(objectName)
set.add(objectName)
}
}
}
Expand All @@ -720,9 +729,10 @@

this.reParse()

this.log(`已被替换对象: `, map)
// 删除无用变量名已替换过的对象变量
// console.log(`已被替换的对象列表: ${[...replaceObjects]}`)
// this.removeUnusedVariables([...replaceObjects])
// this.log(`已被替换的对象列表:`, set)
// this.removeUnusedVariables([...set])
}

/**
Expand Down Expand Up @@ -817,7 +827,7 @@

const toRemoveVariableDeclarators = []
const declarations = []
expressions.forEach((expression, index) => {

Check warning on line 830 in packages/utils/deob.js

View workflow job for this annotation

GitHub Actions / lint

'index' is defined but never used. Allowed unused args must match /^_/u
if (expression.type === 'AssignmentExpression') {
toRemoveVariableDeclarators.push(expression.left.name)

Expand Down Expand Up @@ -848,15 +858,13 @@
VariableDeclarator(p) {
const name = p.node.id?.name
if (p.node.init === null) {
if (toRemoveVariableDeclarators.includes(name)) {
console.log(generator(p.node).code)
if (toRemoveVariableDeclarators.includes(name))
p.remove()
}
}
},
})

const statement = path.getStatementParent()

Check warning on line 867 in packages/utils/deob.js

View workflow job for this annotation

GitHub Actions / lint

'statement' is assigned a value but never used. Allowed unused vars must match /^_/u

path.insertBefore(declarations)
}
Expand All @@ -869,31 +877,31 @@
* @description switch 混淆扁平化
* @example
* function a() {
var _0x263cfa = "1|3|2|0"["split"]("|"),

Check warning on line 880 in packages/utils/deob.js

View workflow job for this annotation

GitHub Actions / lint

Expected JSDoc block to be aligned
_0x105b9b = 0;

while (true) {
switch (_0x263cfa[_0x105b9b++]) {
case "0":
return _0x4b70fb;

case "1":
if (_0x3d66ff !== "link" && _0x3d66ff !== "script") {
return;
}

continue;

case "2":
_0x4b70fb["charset"] = "utf-8";
continue;

case "3":
var _0x4b70fb = document["createElement"](_0x3d66ff);

continue;
}

break;
}
}
Expand Down Expand Up @@ -924,7 +932,6 @@
p.isBlockStatement(),
)

let shufferString = ''
let shufferArr = []

// 从整个函数的 BlockStatement 中遍历寻找 "1|3|2|0"["split"]
Expand All @@ -939,21 +946,15 @@
) {
if (t.isStringLiteral(path.node.object)) {
// path.node.object.value 为 "1|3|2|0"
shufferString = path.node.object.value
const shufferString = path.node.object.value
shufferArr = shufferString.split('|')

// 顺带移除 var _0x263cfa = "1|3|2|0"["split"]("|"),
const VariableDeclarator = path.findParent(p =>
p.isVariableDeclarator(),
)
if (VariableDeclarator) {
console.log(
`switch 平坦化: ${shufferString} ; 删除代码 ${generator(VariableDeclarator.node).code
}`,
)

if (VariableDeclarator)
VariableDeclarator.remove()
}

path.stop()
}
Expand Down Expand Up @@ -994,7 +995,7 @@
exit(path) {
const exporessions = path.node.expressions
const finalExpression = exporessions[exporessions.length - 1]
const statement = path.getStatementParent()

Check warning on line 998 in packages/utils/deob.js

View workflow job for this annotation

GitHub Actions / lint

'statement' is assigned a value but never used. Allowed unused vars must match /^_/u

this.expression.forEach((e) => {
statemente.insertBefore(t.ExpressionStatement(e))
Expand Down Expand Up @@ -1101,7 +1102,7 @@
}

/**
* @description 计算二项式字面量
* @description 计算二项式字面量 计算布尔值
* @example
* 1 + 2 "debu" + "gger"
* ⬇️
Expand All @@ -1120,16 +1121,6 @@
path.skip()
}
},
})
}

/**
* @description 计算布尔值
* @example
* !![] ---> true ![] ---> false
*/
calcBoolean() {
traverse(this.ast, {
UnaryExpression(path) {
if (path.node.operator !== '!')
return // 避免判断成 void
Expand Down Expand Up @@ -1241,7 +1232,7 @@
* @description 给关键函数、标识符 设置注释
* @example // TOLOOK
*/
addComments(keywords = [], label = ' TOLOOK') {
markComment(keywords = [], label = ' TOLOOK') {
const defaultKeywords = ['debugger']
keywords = [
...new Set([...keywords.map(k => k.toLowerCase()), ...defaultKeywords]),
Expand Down
3 changes: 1 addition & 2 deletions play/cx/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ class MyDeOb extends Deob {

// 最后通用处理
deob.calcBinary()
deob.calcBoolean()
deob.replaceConstant()
deob.reParse()
await deob.record(fileName, 4)
Expand All @@ -52,7 +51,7 @@ class MyDeOb extends Deob {
// 优化
// deob.changeObjectAccessMode()
deob.deleteExtra()
deob.addComments()
deob.markComment()

const code = deob.getCode()
fs.writeFile(`${__dirname}/output.js`, code)
Expand Down
3 changes: 1 addition & 2 deletions play/cycgo/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ class MyDeOb extends Deob { }

// 最后通用处理
deob.calcBinary()
deob.calcBoolean()
deob.replaceConstant()
deob.reParse()
await deob.record(fileName, 4)
Expand All @@ -56,7 +55,7 @@ class MyDeOb extends Deob { }
// 优化
// deob.changeObjectAccessMode()
deob.deleteExtra()
deob.addComments()
deob.markComment()

const code = deob.getCode()
fs.writeFile(`${__dirname}/output.js`, code)
Expand Down
4 changes: 2 additions & 2 deletions play/gk/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ class MyDeOb extends Deob { }

// 最后通用处理
deob.calcBinary()
deob.calcBoolean()

deob.replaceConstant()
deob.reParse()
await deob.record(fileName, 4)
Expand All @@ -50,7 +50,7 @@ class MyDeOb extends Deob { }
// 优化
// deob.changeObjectAccessMode()
deob.deleteExtra()
deob.addComments()
deob.markComment()

const code = deob.getCode()
fs.writeFile(`${__dirname}/output.js`, code)
Expand Down
3 changes: 1 addition & 2 deletions play/jsonv6/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ class MyDeOb extends Deob { }

// 最后通用处理
deob.calcBinary()
deob.calcBoolean()
deob.replaceConstant()
await deob.record(fileName, 4)

Expand All @@ -46,7 +45,7 @@ class MyDeOb extends Deob { }
// 优化
// deob.changeObjectAccessMode()
deob.deleteExtra()
deob.addComments()
deob.markComment()

const code = deob.getCode()
await fs.writeFile(`${__dirname}/output.js`, code)
Expand Down
Loading
Loading