@@ -2,8 +2,7 @@ import { join, normalize } from 'node:path'
22import * as parser from '@babel/parser'
33import { codeFrameColumns } from '@babel/code-frame'
44import type * as t from '@babel/types'
5- import debug from 'debug'
6- import { applyTransform , applyTransforms , codePrettier , generate } from './ast-utils'
5+ import { applyTransform , applyTransforms , codePrettier , codePreview , enableLogger , generate , deobLogger as logger } from './ast-utils'
76import type { Options } from './options'
87import { defaultOptions , mergeOptions } from './options'
98import type { StringArray } from './deobfuscate/string-array'
@@ -59,8 +58,6 @@ function handleError(error: any, rawCode: string) {
5958 }
6059}
6160
62- const logger = debug ( 'Deob' )
63-
6461function shorten ( value : string , max = 120 ) {
6562 const clean = value . replace ( / \s + / g, ' ' ) . trim ( )
6663 if ( clean . length <= max )
@@ -69,7 +66,7 @@ function shorten(value: string, max = 120) {
6966}
7067
7168function buildDecryptionSummaryLog ( map : Map < string , string > ) {
72- const lines = [ ]
69+ const lines = [ '=== 解密结果预览 ===' ]
7370
7471 lines . push ( `- 解密条目: ${ map . size } 个` )
7572 if ( map . size ) {
@@ -101,8 +98,7 @@ export class Deob {
10198 mergeOptions ( options )
10299 this . options = options
103100
104- // debug.enable('webcrack:*')
105- debug . enable ( 'Deob' )
101+ enableLogger ( 'Deob' )
106102
107103 if ( ! rawCode )
108104 throw new Error ( '请载入js代码' )
@@ -143,11 +139,11 @@ export class Deob {
143139 }
144140
145141 prepare ( ) {
146- applyTransforms ( this . ast , [ blockStatements , sequence , splitVariableDeclarations , varFunctions , rawLiterals ] )
142+ return applyTransforms ( this . ast , [ blockStatements , sequence , splitVariableDeclarations , varFunctions , rawLiterals ] )
147143 }
148144
149145 unminify ( ) {
150- applyTransform ( this . ast , unminify )
146+ return applyTransform ( this . ast , unminify )
151147 }
152148
153149 run ( ) : DeobResult {
@@ -187,7 +183,9 @@ export class Deob {
187183 decoders = designDecoder ( this . ast , options . designDecoderName ! )
188184 }
189185
190- logger ( `${ stringArray ? `字符串数组: ${ stringArray ?. name } ` : '没找到字符串数组' } | ${ decoders . length ? `解密器函数: ${ decoders . map ( d => d . name ) } ` : '没找到解密器函数' } ` )
186+ logger ( `${ stringArray ? `字符串数组: ${ stringArray ?. name } (${ stringArray ?. length } 个) 引用 ${ stringArray ?. references . length } 处` : '没找到字符串数组' } | ${ decoders . length ? `解密器函数: ${ decoders . map ( d => d . name ) } ` : '没找到解密器函数' } ` )
187+ if ( rotators . length )
188+ logger ( `字符串数组旋转器: ${ rotators . length } 个` )
191189
192190 evalCode ( setupCode )
193191
@@ -206,17 +204,37 @@ export class Deob {
206204 logger ( buildDecryptionSummaryLog ( map ) )
207205
208206 if ( options . isRemoveDecoder && ! options . isStrongRemove ) {
209- stringArray ?. path . remove ( )
210- rotators . forEach ( r => r . remove ( ) )
211- decoders . forEach ( d => d . path ?. remove ( ) )
207+ const removedSnippets : string [ ] = [ ]
208+ const MAX_SNIPPETS = 3
209+ const addSnippet = ( node : t . Node ) => {
210+ if ( removedSnippets . length < MAX_SNIPPETS )
211+ removedSnippets . push ( codePreview ( node ) )
212+ }
213+
214+ if ( stringArray ?. path ) {
215+ addSnippet ( stringArray . path . node )
216+ stringArray . path . remove ( )
217+ }
218+ rotators . forEach ( ( r ) => {
219+ addSnippet ( r . node )
220+ r . remove ( )
221+ } )
222+ decoders . forEach ( ( d ) => {
223+ addSnippet ( d . path . node )
224+ d . path ?. remove ( )
225+ } )
226+ logger ( `已移除解密相关节点${ removedSnippets . length ? `,片段:\n${ removedSnippets . join ( '\n' ) } ` : '' } ` )
212227 }
228+ return { changes : ( map as any ) ?. size ?? decoders . length + rotators . length }
213229 } ,
214230 /** 对象引用替换 */
215231 ( ) => applyTransform ( this . ast , inlineObjectProps ) ,
216232 /** 控制流平坦化 */
217233 ( ) => {
234+ logger ( `控制流平坦化执行次数: ${ options . execCount } ` )
235+ let changes = 0
218236 for ( let i = 0 ; i < options . execCount ; i ++ ) {
219- applyTransforms (
237+ const state = applyTransforms (
220238 this . ast ,
221239 [
222240 mergeStrings ,
@@ -225,31 +243,40 @@ export class Deob {
225243 controlFlowSwitch ,
226244 ] ,
227245 )
246+ changes += state . changes
228247 }
248+ return { changes }
229249 } ,
230250 /** 合并对象 */
231251 ( ) => applyTransform ( this . ast , mergeObjectAssignments ) ,
232252 /** 去 minify */
233- ( ) => applyTransform ( this . ast , unminify ) ,
253+ ( ) => this . unminify ( ) ,
234254 /** 对象命名优化 */
235255 ( ) => {
236256 const matcher = getMangleMatcher ( options )
237- if ( matcher )
238- applyTransform ( this . ast , mangle , matcher )
257+ if ( matcher ) {
258+ return applyTransform ( this . ast , mangle , matcher )
259+ }
239260 } ,
240261 /** 移除自卫代码 */
241- ( ) => {
242- return applyTransforms (
243- this . ast ,
244- [
245- [ selfDefending , debugProtection ] ,
246- ] . flat ( ) ,
247- )
248- } ,
262+ ( ) => applyTransforms (
263+ this . ast ,
264+ [
265+ [ selfDefending , debugProtection ] ,
266+ ] . flat ( ) ,
267+ ) ,
249268 /** 标记关键字 */
250- options . isMarkEnable && ( ( ) => markKeyword ( this . ast , options . keywords ) ) ,
269+ options . isMarkEnable && ( ( ) => {
270+ logger ( `关键字列表: [${ options . keywords . join ( ', ' ) } ]` )
271+ markKeyword ( this . ast , options . keywords )
272+ return { changes : options . keywords . length }
273+ } ) ,
251274 /** 输出代码 */
252- ( ) => ( outputCode = generate ( this . ast ) ) ,
275+ ( ) => {
276+ outputCode = generate ( this . ast )
277+ logger ( `输出代码长度: ${ outputCode . length } 字符` )
278+ return { changes : outputCode . length }
279+ } ,
253280 ] . filter ( Boolean ) as ( ( ) => unknown ) [ ]
254281
255282 for ( let i = 0 ; i < stages . length ; i ++ ) {
0 commit comments