吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 2365|回复: 13
收起左侧

[Web逆向] [新手向]复杂化平坦流还原的小案例

[复制链接]
wolfSpicy 发表于 2024-3-23 21:05

最近在尝试用AST来玩下,我就试了下尝试把一个小案例中的复杂化平坦流来进行还原。
这是案例下载 链接:https://pan.baidu.com/s/1kZ_3m7Hn5xyMzttDOfikxA?pwd=bvf3

我希望可以用更加易懂的话来解释我的思路(大佬勿喷,纯粹是新人练手),下面是我的思路

我们首先是进行debugger来一步步调试,观察规律,可以看到是12开始
Snipaste_2024-03-23_20-14-04.jpg

可以看到这是12最后进入要执行的部分条件是<13,不过这时候我们还看不出啥规律,继续
Snipaste_2024-03-23_20-20-48.jpg

在12执行完后看到了f变成了4,然后继续单步
Snipaste_2024-03-23_20-20-48.jpg

这时候能看到4是进入了条件是<5这块的,我们可以猜测有可能是会进入(f-1)的条件?,或者也有可能是巧合?继续
Snipaste_2024-03-23_20-23-28.jpg

然后我们看到f这时候已经是15了,会如我们所愿吗?
Snipaste_2024-03-23_20-25-34.jpg

会不会和上俩个情况一样进入条件是<16这块呢?
Snipaste_2024-03-23_20-26-42.jpg

很遗憾,并不会,但我们可以再看看,为什么没有进入<16呢,这个先不知道,再多试几次
Snipaste_2024-03-23_20-26-49.jpg

这时候神奇事情又发生了,又出现了我们猜测的情况,应该是这样了,那那个15是什么情况呢,在我们多试几次后会发现
Snipaste_2024-03-23_20-33-57.jpg

Snipaste_2024-03-23_20-34-31.jpg

f是25 不会进入f<25 而是进入他的else
Snipaste_2024-03-23_20-36-44.jpg

我们可以进行总结下规律,f进入最后执行的情况要么是f<(f+1)的情况 要么是if条件是f<(f)的else

比如f=5的时候 会在if条件是f<(f)的else
Snipaste_2024-03-23_20-40-00.jpg

比如f=8的时候,会在if条件是f<(f+1)的情况下进入
Snipaste_2024-03-23_20-41-31.jpg

如果不相信可以多试几次,会发现这个规律是正确的

接下来就是如何用ast还原,这边我只是还原出if流程,因为思路才是最关键的

traverse(ast,{
    "ForStatement":function (path) {
        path.get('body').replaceWith(types.blockStatement([path.node.body],[]))
    }
})
p=[]
traverse(ast,{
    "IfStatement": {
        'exit':function (path){
                    //条件为什么是这几个,不会有什么问题吗?
                    //首先path.node.alternate是为了防止else{}为空的情况 因为我们接下来要取他的body【0】防止取不到而报错的情况
                    //为什么是left.name==='f' 因为我们在之前可以看到他的条件判断一定是 if(f<xxx) 这种情况一定会携带f 是怕有别的比如出现if (s<xxx)的情况
                    if(path.node.alternate&&path.get('alternate.body').length
                        &&!types.isIfStatement(path.get('alternate.body.0'))&&
                        path.node.test.left.name==='f'
                    ){

                            let left=path.node.test.left.name
                            let right=path.node.test.right.value

                            //创建continue是为了后面做准备这个可以暂时忽略
                            let continueStatement=types.continueStatement()
                            let consequent=path.get('consequent')
                            let alternate=path.get('alternate')
                            consequent.insertAfter(continueStatement)
                            alternate.insertAfter(continueStatement)

                            //这个是创建if语句 是做成比如 f=12 最后进入if(f<13)的情况,我之前图片有这样的
                            let elseState=types.ifStatement(
                                types.binaryExpression("===",
                                    types.identifier(left),
                                    types.identifier((right-1).toString()),
                                    ),consequent.node)

                        //这个也是是创建if语句 是做成比如 f=5 最后进入if(f<5)的else情况,我之前图片有这样的
                            let ifState=types.ifStatement(
                                types.binaryExpression("===",types.identifier(left),
                                    types.identifier((right).toString())),alternate.node)
                        //p是个列表 里面存储了自己弄的ifStatement
                                /**
                                 * 把这个最后变成
                                 *                     if (f < 1) {
                                 *                         var i = function (f) {
                                 *                             var i = e || 0;
                                 *                             for (; ;) return S(E(s(f), f.length * r))
                                 *                         };
                                 *                         f += 22
                                 *                     } else {
                                 *                         var l = function (f, i, l, s, r, n, t) {
                                 *                             var o = e || 0;
                                 *                             for (; ;) return a(i & l | ~i & s, f, i, r, n, t)
                                 *                         };
                                 *                         f += 22
                                 *                     }
                                 *
                                 * 
                                 * 这种格式的
                                 * if(f===0){
                                 *         var i = function (f) {
                                 *                             var i = e || 0;
                                 *                             for (; ;) return S(E(s(f), f.length * r))
                                 *                         };
                                 *                         f += 22
                                 *
                                 * }
                                 *if(f===1)){
                                 *                      var l = function (f, i, l, s, r, n, t) {
                                 *                             var o = e || 0;
                                 *                             for (; ;) return a(i & l | ~i & s, f, i, r, n, t)
                                 *                         };
                                 *                         f += 22
                                 *
                                 *
                                 *}
                                 *
                                 */
                                /
                        p.push(elseState)
                        p.push(ifState)

                        // console.log(path.scope.getBinding(left).path.parentPath.toString())
                    }
        }
        }
})
traverse(ast,{
'Program':function (path) {
    let forstate=path.get("body.0.expression.callee.body.body.1")
    let body=forstate.get('body.body')
    body[0].replaceInline(p)
}
})



为什么我在代码中continue呢?

下面是没有continue的ast还原后执行情况
Snipaste_2024-03-22_22-38-22.jpg


但在浏览器中执行是这样的
Snipaste_2024-03-23_19-41-48.jpg



为什么是这样?你们可以调下没有continue的ast还原后的代码看看
举个例子 比如f=1的时候 f===1的时候会进入 最后出现个f+=20;
此时f是21 但因为没有continue会继续往下跑,虽然这个好像没啥问题,但如果你是在for的时候就console.log这就不一样了,你可以去调试感受下

这是continue加后的效果图
Snipaste_2024-03-23_20-02-00.jpg

Snipaste_2024-03-23_20-41-31.jpg

免费评分

参与人数 5威望 +1 吾爱币 +23 热心值 +5 收起 理由
lingyun011 + 1 + 1 热心回复!
allspark + 1 + 1 用心讨论,共获提升!
lihuhu + 1 我很赞同!
明天十九 + 1 + 1 谢谢@Thanks!
涛之雨 + 1 + 20 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

s1lencee 发表于 2024-3-23 23:25
感谢大佬分享,学到了很多东西
头像被屏蔽
zz8283 发表于 2024-3-24 10:06
Lty20000423 发表于 2024-3-24 11:22
lihuhu 发表于 2024-3-24 22:16
学习学习
jackchen66 发表于 2024-3-25 18:38
感谢楼主提供的思路
L153518 发表于 2024-3-25 20:53
感谢大佬
aoustes 发表于 2024-3-25 21:28
厉害了大佬,牛
goldcrane1 发表于 2024-3-26 10:03
感谢分享
havealook 发表于 2024-3-26 23:44
感谢分享
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-22 21:27

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表