Skip to content

Commit c39e3ae

Browse files
committed
refactor: improve decoder detection and rename designDecoderName to decoderNames
- Rename `designDecoderName` option to `decoderNames` for clarity - Rename `design-decoder.ts` to `collect-decoders.ts` with function rename - Add wrapped string array function pattern detection in find-decoder-by-array - Extract `processReferences` helper function to reduce code duplication - Add detailed JSDoc comments to find-decoder-by-call-count explaining detection logic - Move inlineObjectProps transform earlier in the deobfuscation pipeline - Remove unused webcrack deobfuscate call and mergeObjectAssignments transform
1 parent 77d8dd9 commit c39e3ae

10 files changed

Lines changed: 225 additions & 105 deletions

File tree

example/lamz/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ const __dirname = dirname(__filename)
1616
const { code, save } = await deob(rawCode, {
1717
decoderLocationMethod: 'evalCode',
1818
setupCode,
19-
designDecoderName: '_0x1663',
19+
decoderNames: '_0x1663',
2020
})
2121
save(__dirname)
2222
})()

example/pdd/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ const __dirname = dirname(__filename)
1616
const options: Options = {
1717
decoderLocationMethod: 'evalCode',
1818
setupCode,
19-
designDecoderName: 'qt',
19+
decoderNames: 'qt',
2020
}
2121

2222
await fs.writeFile(`${__dirname}/pretty.js`, codePrettier(parseCode(rawCode)))

packages/deob/src/index.ts

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@ import type { Options } from './options'
77
import { join, normalize } from 'node:path'
88
import { codeFrameColumns } from '@babel/code-frame'
99
import { parse } from '@babel/parser'
10-
import { applyTransform, applyTransformAsync, applyTransforms, codePrettier, enableLogger, generate, deobLogger as logger } from './ast-utils'
11-
import deobfuscate from './deobfuscate'
10+
import { applyTransform, applyTransforms, codePrettier, enableLogger, generate, deobLogger as logger } from './ast-utils'
1211
import controlFlowObject from './deobfuscate/control-flow-object'
1312
import controlFlowSwitch from './deobfuscate/control-flow-switch'
1413
import deadCode from './deobfuscate/dead-code'
@@ -23,8 +22,8 @@ import varFunctions from './deobfuscate/var-functions'
2322

2423
import { evalCode } from './deobfuscate/vm'
2524
import { defaultOptions, mergeOptions } from './options'
25+
import { collectDecoders } from './transforms/collect-decoders'
2626
import { decodeStrings } from './transforms/decode-strings'
27-
import { designDecoder } from './transforms/design-decoder'
2827
import { findDecoderByArray } from './transforms/find-decoder-by-array'
2928
import { findDecoderByCallCount } from './transforms/find-decoder-by-call-count'
3029
import mangle from './transforms/mangle'
@@ -113,8 +112,6 @@ export async function deob(rawCode: string, options: Options = {}): Promise<Deob
113112
{ name: 'prepare' },
114113
)
115114
},
116-
// webcrack 反混淆
117-
() => applyTransformAsync(ast, deobfuscate, opts.sandbox),
118115
// 定位解密器
119116
async () => {
120117
let stringArray: StringArray | undefined
@@ -127,17 +124,17 @@ export async function deob(rawCode: string, options: Options = {}): Promise<Deob
127124

128125
stringArray = s as any
129126
rotators = r
130-
decoders = designDecoder(ast, ds.map(d => d.name))
127+
decoders = collectDecoders(ast, ds.map(d => d.name))
131128
setupCode = scode
132129
}
133130
else if (opts.decoderLocationMethod === 'callCount') {
134131
const { decoders: ds, setupCode: scode } = findDecoderByCallCount(ast, opts.decoderCallCount)
135-
decoders = designDecoder(ast, ds.map(d => d.name))
132+
decoders = collectDecoders(ast, ds.map(d => d.name))
136133
setupCode = scode
137134
}
138135
else if (opts.decoderLocationMethod === 'evalCode') {
139136
await evalCode(opts.sandbox!, opts.setupCode!)
140-
decoders = designDecoder(ast, opts.designDecoderName!)
137+
decoders = collectDecoders(ast, opts.decoderNames!)
141138
}
142139

143140
logger(`${stringArray ? `字符串数组: ${stringArray?.name} (共 ${stringArray?.length} 项) 被引用 ${stringArray?.references.length} 处` : '没找到字符串数组'} | ${decoders.length ? `解密器函数: ${decoders.map(d => d.name)}` : '没找到解密器函数'}`)
@@ -152,6 +149,9 @@ export async function deob(rawCode: string, options: Options = {}): Promise<Deob
152149
)
153150
}
154151

152+
// 对象引用替换
153+
applyTransform(ast, inlineObjectProps)
154+
155155
// 执行解密器
156156
const map = await decodeStrings(opts.sandbox!, decoders as Decoder[])
157157

@@ -169,16 +169,12 @@ export async function deob(rawCode: string, options: Options = {}): Promise<Deob
169169

170170
return { changes: (map as any)?.size ?? decoders.length }
171171
},
172-
// 对象引用替换
173-
() => applyTransform(ast, inlineObjectProps),
174172
// 控制流平坦化
175173
() => applyTransforms(
176174
ast,
177175
[mergeStrings, deadCode, controlFlowObject, controlFlowSwitch],
178176
{ noScope: true },
179177
),
180-
// 合并对象
181-
() => applyTransform(ast, mergeObjectAssignments),
182178
// unminify
183179
() => applyTransforms(ast, [transpile, unminify]),
184180
// 变量命名优化

packages/deob/src/options.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ export interface Options {
1010
/** 执行代码函数 */
1111
setupCode?: string
1212
/** 指明解密函数 */
13-
designDecoderName?: string | string[]
13+
decoderNames?: string | string[]
1414

1515
/** 是否标记关键信息 */
1616
isMarkEnable?: boolean
@@ -30,7 +30,7 @@ export const defaultOptions: Required<Options> = {
3030
decoderLocationMethod: 'stringArray',
3131
decoderCallCount: 150,
3232
setupCode: '',
33-
designDecoderName: '',
33+
decoderNames: '',
3434

3535
isMarkEnable: true,
3636
keywords: ['debugger'],
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import type * as t from '@babel/types'
2+
import traverse from '@babel/traverse'
3+
import { Decoder } from '../deobfuscate/decoder'
4+
5+
export function collectDecoders(ast: t.Node, decoderNames: string | string[]): Decoder[] {
6+
const names = Array.isArray(decoderNames) ? decoderNames : [decoderNames]
7+
8+
const foundDecoders: Decoder[] = []
9+
10+
traverse(ast, {
11+
FunctionDeclaration(path) {
12+
const { id } = path.node
13+
const fnName = id?.name
14+
15+
if (fnName && names.includes(fnName)) {
16+
foundDecoders.push(new Decoder(fnName, fnName, path))
17+
}
18+
},
19+
})
20+
21+
return foundDecoders
22+
}

packages/deob/src/transforms/design-decoder.ts

Lines changed: 0 additions & 38 deletions
This file was deleted.

0 commit comments

Comments
 (0)