AST还原技术专题:如何解决 "Container is falsy" 的报错问题

提出问题

在早期的一键解ob混淆脚本里,有大佬曾经问我:在还原object时,为啥不用scope来查找引用再替换?类似代码:

for (const referPath of referencePaths)
  {
     .......
     referPath.replaceWith(......);
     ......
  }

因为之前也尝试过用binding来替换,但总是会报错:

分析问题

为什么会引起错误,这个暂时未知,但是怎么分析报错问题,我之前一直提到过,直接打印最后一个遍历的path,看看是遍历的什么导致报错。添加如下打印代码:

for (const referPath of referencePaths)
  {
     console.log(referPath.parentPath.toString());
     console.log(referPath.parentPath.parentPath.toString());
     .......
     referPath.replaceWith(......);
     ......
  }

此时,在我遍历的样本中,打印信息如下:

红框处打印的是最后一次遍历的path,就是因为遍历了这里,才导致报错。

现在来自行分析下,在这之前遍历的是这个path:

_0x122f03["OnLhw"](_0x122f03["ueUti"], _0x122f03["nHsqG"])

替换成了 :

_0x122f03["ueUti"] !== _0x122f03["nHsqG"]

也就是处理 _0x122f03["OnLhw"] 这个之后,再遍历 _0x122f03["ueUti"] 时,就报错了,为啥?

我猜想的主要原因是 之前的节点是这样的:

_0x122f03["OnLhw"](_0x122f03["ueUti"], _0x122f03["nHsqG"])

这是一个包含关系,而在替换完 _0x122f03["OnLhw"] 后,节点的位置变了,但是使用scope的引用时,在这个新的节点位置进行替换操作,而这个节点并没有真正在AST中的生成,所以报了 Container is falsy 的错误(只是猜想,解释错误勿喷!)。

解决问题

在分析问题之后,解决问题就很简单了。既然这个包含关系,先遍历外面的,再遍历里面的,那反着来就可以了,即先遍历:

_0x122f03["OnLhw"](_0x122f03["ueUti"], _0x122f03["nHsqG"])

这个路径里的 _0x122f03["ueUti"] 和 _0x122f03["nHsqG"],再遍历 _0x122f03["OnLhw"],这样就不存在包含关系了。

referencePaths是一个Array类型,通过打印可以看出,引用的路径是按照代码顺序来的,"OnLhw" 在 "ueUti" 和 "nHsqG" 前面,也就先遍历了。

因此,只需将代码修改如下:

for (const referPath of referencePaths.reverse())
  {
     .......
     referPath.replaceWith(......);
     ......
  }

即可。经多个样本测试,不再报错,完美解决。Bingo!

欢迎关注本人微信公众号,谢谢!

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值