实现目的:自执行空实参替换顺序语句
处理前:
( function ( ) {
b = 123 ;
c = 456 ;
} ( ))
处理后:
b = 123 ;
c = 456 ;
demo. js
( function ( ) {
b = 123 ;
c = 456 ;
console. log ( c) ;
} ( ) ) ;
( function ( a ) {
if ( ! a) {
a = 10
}
b = 123 ;
c = 456 ;
console. log ( a) ;
} ( ) ) ;
! function ( ) {
b = 123 ;
c = 456 ;
console. log ( b) ;
} ( ) ;
! function ( a ) {
if ( ! a) {
a = 20
}
b = 123 ;
c = 456 ;
console. log ( a) ;
} ( ) ;
dec_main. js
const fs = require ( "fs" ) ;
const parse = require ( "@babel/parser" ) ;
const traverse = require ( '@babel/traverse' ) . default;
const t = require ( '@babel/types' ) ;
const generator = require ( '@babel/generator' ) . default;
const jscode = fs. readFileSync (
'./demo.js' , {
encoding: 'utf-8'
}
) ;
let ast = parse. parse ( jscode) ;
function delConvParam ( path ) {
let node = path. node;
let node_exp = node. expression;
if ( ! t. isCallExpression ( node_exp) && ! t. isUnaryExpression ( node_exp) )
return ;
if ( node. expression. arguments !== undefined && node. expression. arguments. length > 0 )
return ;
if ( t. isUnaryExpression ( node_exp) && node_exp. operator== '!' ) {
node_exp= node_exp. argument;
}
if ( t. isCallExpression ( node_exp) ) {
if ( ! t. isFunctionExpression ( node_exp. callee) )
return ;
let paramsList= node_exp. callee. params
if ( paramsList. length> 0 ) {
paramsList. map ( function ( letname ) {
if ( t. isIdentifier ( letname) ) {
let varDec = t. VariableDeclarator ( t. identifier ( letname. name) )
let localAST = t. VariableDeclaration ( 'var' , [ varDec] ) ;
node_exp. callee. body. body. unshift ( localAST) ;
}
} )
}
path. replaceInline ( node_exp. callee. body. body) ;
}
}
traverse ( ast, { ExpressionStatement: delConvParam, } )
let { code} = generator ( ast, opts = { jsescOption: { "minimal" : true } } )
fs. writeFile ( './demoNew.js' , code, ( err ) => {
} ) ;
demoNew. js
b = 123 ;
c = 456 ;
console. log ( c) ;
var a;
if ( ! a) {
a = 10 ;
}
b = 123 ;
c = 456 ;
console. log ( a) ;
b = 123 ;
c = 456 ;
console. log ( b) ;
var a;
if ( ! a) {
a = 20 ;
}
b = 123 ;
c = 456 ;
console. log ( a) ;
优化及说明:
一、优化自执行种类适配
原来:只适配第一种自执行类型
现在:适配两种自执行类型
二、可以携带形参
原来:形参与实参都为空
现在:现在可以允许有形参,处理后,会将形参重新定义
需要注意:形参重新定义,会涉及作用域,存在同名等问题会冲突报错,
三、尽可能维护上下文,不修改执行逻辑依赖的变量,更安全
ast反混淆进阶--自执行实参替换形参
https://jia666666.blog.csdn.net/article/details/120301341
推荐搭配:自执行实参替换形参+执行自执行空实参替换顺序语句,效果较佳
须知:自执行空实参替换顺序语句作用域问题
1 .原来语句的作用域会提升到上一级作用域( 局部-> 全局等情况)
2 .若上一级作用域存在同名/已定义的变量,会影响上下文,且失去简化意义
3 .谨慎执行此操作,若风险自己可控,建议执行
------------------------------------------------------------
特别说明及感谢:
此处核心源码来自于作者:丁仔
参考ob解混淆源码
https://github.com/DingZaiHub/ob-decrypt
----------------------------------------------------------