AST还原实战| 实战还原一个中等难度的ob变种混淆代码

关注它,不迷路。       

本文章中所有内容仅供学习交流,不可用于任何商业用途和非法用途,否则后果自负,如有侵权,请联系作者立即删除!

1. 需求分析

之前有星友发了这个链接在群里:

https://thetanuts.org/

发现有混淆的代码,拿来做实战还原的案例不错,因此有了这篇文章。

但是现在网站访问不了了,大家可以自行到知识星球里下载混淆样本。

https://t.zsxq.com/10m1trpX3

2. 思路详解

拿到混淆代码,首先的是去分析,那些地方是可以进行还原处理的,一步一步来,会有种 "柳暗花明又一村"的感觉。

将代码格式化以后,它长这样:

e4aa6096dc40d617a961412de6d41a3c.png

这种十六进制字符串和Unicode字符串先还原,使用下面的插件:

const simplifyLiteral = {
  NumericLiteral({node}) {
    if (node.extra && /^0[obx]/i.test(node.extra.raw)) {
      node.extra = undefined;
    }
  },
  StringLiteral({node}) 
  {
    if (node.extra && /\\[ux]/gi.test(node.extra.raw)) {
      node.extra = undefined;
    }
  },
}

这一步还原后,继续分析:

90af7bea104766ffcb4545189545bde9.png

可以看到,它有很多的 CallExpression,并且,其callee子节点的类型是有差异的,如:

__p_6473343178["call"](undefined, 226)

和:

__p_6473343178["apply"](undefined, [144]);

或者:

__p_6473343178(134);

这是三种不同的函数调用,因此,写个代码将其统一一下,更有利于我们进行下一步分析:

__p_6473343178(226);
__p_6473343178(144);
__p_6473343178(134);

还原的AST代码如下:

const changeForCall = 
{
  CallExpression(path)
  {
    let {callee,arguments} = path.node;
    if (!types.isMemberExpression(callee) || arguments.length < 2 || !types.isIdentifier(arguments[0],{"name":"undefined"}))
    {
      return;
    }
    
    let {object,property} = callee;
    
    if (types.isStringLiteral(property,{"value":"call"}))
    {
      let callNode = types.CallExpression(object,arguments.slice(1));
      path.replaceWith(callNode);
      return;
    }
    
    if (types.isStringLiteral(property,{"value":"apply"}) &&
        arguments.length == 2 && types.isArrayExpression(arguments[1]))
    {
      let callNode = types.CallExpression(object,arguments[1].elements);
      path.replaceWith(callNode);
    }    


  }
}




traverse(ast, changeForCall);

这一波还原之后,代码成这样了:

90a7696c566e7281b8b37ef5368513b9.png

可以发现,对于每一个  CallExpression,它的实参都是字面量,之前见过,如果函数是个纯函数,且与浏览器环境无关,那我们是可以进行还原的

这种函数调用还原,就考验大家的抠代码能力了,思路就是先把函数定义抠出来,在node下运行,然后缺啥补啥。最后打印出来的字符串不是乱码,至少可以确认代码成功抠取了

如下图所示:

9bf094f8498d249e0164e42e261ea806.png

代码抠出来后,能在node下正常运行并打印的字符串不是乱码,可以判断抠取对了。

接下来就是还原所有的函数调用了:

const callToString = {
    "CallExpression"(path) {


        let node = path.node;


        let {callee, arguments} = node;
        if (!types.isIdentifier(callee, {
            "name": "__p_6473343178"
        })) {
            return;
        }


        if (arguments.length != 1 || !types.isNumericLiteral(arguments[0])) {
            return;
        }


        let value = __p_6473343178(arguments[0].value);
        console.log(path.toString(), "-->", value);
        path.replaceWith(types.valueToNode(value));
    },
}

这个插件运行后,还原的代码如下:

54a231f626baf725642a9aad7386bd67.png

剩下的部分我相信大部分人都能够还原了,无非就是变量定义的还原,常量折叠,Array类型的还原等。这在星球的置顶二里面都能找到现成的插件。这里不做讲述。

今天的文章就分享到这里,后续分享更多的技巧,敬请期待。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
AST混淆还原是指通过对JavaScript代码的抽象语法树(AST)进行还原,来反混淆经过混淆处理的代码AST混淆还原入门可以通过以下几个步骤实现: 1. 了解抽象语法树(AST):抽象语法树是用于表示代码结构的一种数据结构。它将代码转换为树状结构,每个节点代表代码的不同部分。了解AST的基本概念和节点类型对于进行混淆还原非常重要。 2. 学习JavaScript语法:要进行AST混淆还原,需要对JavaScript的语法有一定的了解。熟悉JavaScript的语法规则和常见的代码结构将有助于理解和还原混淆代码。 3. 使用AST还原工具:在进行AST混淆还原时,可以使用一些开源的AST还原工具,如丁仔大佬的AST还原工具。这些工具可以将混淆后的代码转换为AST,然后通过对AST进行分析和还原,最终得到可读性较高的代码。 4. 学习AST还原技术:了解AST还原的原理和技术对于深入理解和应用AST还原工具非常重要。可以学习一些AST还原的基本技术,如遍历AST、修改AST节点等,以及一些高级的AST还原技术,如模式匹配、符号执行等。 5. 实践与练习:通过实践与练习,逐渐提升对AST混淆还原的理解和技巧。可以选择一些混淆代码进行还原,尝试使用AST还原工具进行还原,并对还原结果进行分析和验证。 需要注意的是,AST混淆还原一个复杂的过程,对于不同的混淆代码可能会有不同的还原策略和技术。因此,除了入门的基础知识外,还需要不断学习和积累经验,才能在实际应用中取得更好的效果。<span class="em">1</span> #### 引用[.reference_title] - *1* [AST混淆js还原工具2.2(20230203)](https://download.csdn.net/download/jia666666/87413335)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值