小言_互联网的博客

JavaScript反混淆插件四:JavaScript全局函数计算值替换

400人阅读  评论(0)

插件功能

获取实参,计算出全局函数调用的结果,并用结果替换该全局函数的调用表达式。

处理实例

处理前:


   
  1. var a = parseInt( "12345", 16),b = Number( "123"),c = String( true),d = unescape( "hello%2CAST%21");
  2. eval( "a = 1");

处理后:


   
  1. var a =  74565,b = 123,c = "true",d = "hello,AST!";
  2. eval("a = 1");

插件源码


   
  1. const types = require( "@babel/types");
  2. const evaluate_global_func =
  3. {
  4. "CallExpression"(path)
  5. {
  6. let {callee, arguments} = path.node;
  7. if (!types.isIdentifier(callee) || callee.name == "eval") return;
  8. if (! arguments.every( arg=>types.isLiteral(arg))) return;
  9. let func = global[callee.name];
  10. if ( typeof func !== "function") return;
  11.      let args = [];
  12. arguments.forEach( (ele,index) =>{args[index] = ele.value;});
  13. let value = func.apply( null,args);
  14. if ( typeof value == "function") return;
  15. path.replaceInline(types.valueToNode(value));
  16. },
  17. }

插件原理

JavaScript有几个的全局函数,当它的实参是字面量时,是可以直接计算出结果的,而且都是唯一的,也就是纯函数。根据这个可以将计算出来的结果替换全局函数的调用表达式。这样的好处是让程序简单些,甚至可以做进行进一步的还原,达到简化程序的目的。思路如下:

  1. CallExpression表达式的callee节点必须是Identifier类型

  2. 函数名不能是eval,因为eval函数无返回值,无法进行替换。

  3. 判断global[funcname]的类型,如果是"function",则表示它是全局函数。

  4. 获取实参,计算结果。

  5. 计算出来的结果不能是function类型,不能进行替换。

  6. 构造节点,进行替换即可。


转载:https://blog.csdn.net/qq523176585/article/details/110103055
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场