20-控制流多次异步
本文目的主要为xhr断点跟栈调试,不以逆向结果为目的,提前说一下,此文章很长但很重要,要理解跟的过程和js代码逻辑,还有就是这个参数用的是RSA加密,学习网站:中国五矿集团有限公司供应链管理
加密参数

注意:翻页后出现两个数据包,public可以猜一下是什么,我们要的是图片中的数据包(看响应数据就懂了)
定位
接着我们用xhr定位:
send前一个栈的参数由外部传入且带有加密密文,直接看最后一个栈:

看异步前代码:

咱么打上断点看一下是异步成功还是失败:

运行过来之后,鼠标放在n上,进入n函数:

刚才那个栈(异步之后第一个栈)的参数A是外部传入的,其实就是o方法返回的,这里咱来复习一下异步代码
之前博客:06-js语法之异步中讲过异步,这里把代码修改一下更便于这里理解:

// 修改后:
function getAsyncdata() {return new Promise(function (resolve) { // 创建一个promise对象 resolve是正常异步返回数据的resolve('hello world')  // 异步函数内部返回数据不再使用return,而是用resolve(),resolve()是个方法})
}
function aa(data) {console.log(data)
}
getAsyncdata.then(aa)
 
所以我们这里要找o怎么来的:

上图找到了o,而且知道了o由i来,那看一下i怎么来:之前说过括号前面是函数再看一下A[a],果然是个函数,参数是s,那我们进函数看看?看可以但是不能给断点放进来,因为此时断点已经运行过A[a]函数了,再进来的时候已经是运行第二次A[a]函数了,这里讲一下,**看js代码一些变量的值或者进函数是一定要保证断点在此函数上,**否则看到的就是运行过后的值(可能会经一些函数或重新赋值等换成别的值),或者进的是第二次运行此函数的时候,这时再往下跟栈就会跟丢了,所以我们放完所有断点,重新打断点打在A[a]函数上,保证断下来的位置和要观察的值或函数在同一行,运行过来再进:

这个返回值还是个函数,运行过来继续进去看:


接着我们看看这个函数返回什么:

记得前面说的:**保证断下来的位置和要观察的值或函数在同一行,**所以不要在返回值处打断点,直接在l赋值的位置打断点运行过来然后看d函数:

进d函数去看:

进去之后是个控制流语句:


这里是0,走第一个case,然后注意一点:swich中有赋值且第一个case后return的有A.next = 2之后还会再执行第二个控制流:

这里的返回值依旧是个函数y(e),这里我们跟一下y函数
进入y函数case0
进入y函数:
进入p函数:

跳转到了这里,眼熟么,我把之前那个代码贴在上面对比一下:

这里和之前梦开始的地方很像吧,但并不是,逻辑是一样的,之后会回到异步上面代码,我们来验证一下,一步一步运行看看吧:

跳过之后:

点第三个键到p函数调用位置:

然后看p函数到哪儿:

到了这里:

ok,我们步入继续跟:

这里还是一样的逻辑,我们直接进A[a]函数,发现这里打过断点:

直接点击运行进来:

进来之后:
f还有断点,运行进来继续跟:

d函数我们就不进了,因为d函数就是调用e函数,咱直接进e函数:

嘶~这里开始不一样了,注意:咱其实一直都在y函数而已,前面两三个函数只不过是通用所以一样,但是不要被迷了心智,我们进来看这个控制流:

运行第一个,我们看看返回的是什么:
- 这里同样返回一个控制运行的值
 

- 最终返回的是一个post请求,请求了一个接口,其实就是开头我让猜的哪个接口,请求之后响应数据返回的是一串密文:
 


返回的数据并不是我们想要的,只是返回一个xhr请求,请求一个接口,说明我们进的y函数可能不太对,但是没关系,还有希望,因为还有一个等于4的控制流没运行,这个0的控制流没用了那就直接跳过继续往下跟:

这里开始返回xhr请求的数据,并不是运行等于4后面的代码了,再往下一步就知道了:

开始一层一层往外返回,直到这里:

继续往下跟:

执行异步,然后执行异步成功的n,即下面的s函数:

然后在s函数里打上断点运行过去:


就是public接口的响应数据,到此为止我们跟的y函数case 0的逻辑结束了
开始y函数case4
开始执行s函数,s函数调用p函数,记得p函数是什么么,就是上面梦开始的地方:

再打上断点运行到A[a]:

但这次是带着东西来的:

开始跟:

进_invoke


一点一点跳过到这里:

应该已经看到关键字了,我们看看s等于啥:

RSA加密的数据,为啥这么确定是RSA呢(这里RSA加密的数据很长,下面会介绍它的加密思路):

懂否哈哈哈,这里就是我们要的核心代码了,其实这个案例搜关键字就能找到,不用这么麻烦,但是以后的案例关键字不一定很好用,但xhr跟栈一定能定位到,而且本文的逻辑在以后算简单的,只套了两层,之后会有十几二十层的,这个逻辑会了就一通百通,下面来解析一下核心代码逻辑:

这三行是取出case0中xhr请求得到的密钥设置成公钥,然后看这里:


这里sign看着像md5,看看:

看来是md5没跑了,加密的数据是载荷数据,里面有翻页pageIndex参数,然后面是一个时间戳,然后这里:

是将载荷通过md5加密生成的sign和js的时间戳添加到载荷数据(e)中传给变量a,接着往下看:

通过encryptLong方法加密a通过JSON生成的字符串,咱看看encryptLong函数:

这里是将数据分割成好几个1到50长度的字符串分别加密,然后:

再将加密的字符串拼接在一起,这就是他RSA加密的思路,到此本文就基本结束了,可以试着自己扣一下代码
