在JS逆向中,当遇到异步栈时很容易跟丟,今天以图示的方式,演示一个异步栈的调试。
先来看一下异步栈的特点:
异步栈是指在异步编程中用于管理和追踪异步操作的执行顺序和状态的数据结构。下面是异步栈的一些特点:
执行顺序的反转:在同步编程中,代码按照自上而下的顺序依次执行。而在异步编程中,当遇到一个异步操作时,它会被放入异步栈中,并立即返回控制权给调用者,允许之后的代码继续执行。然后,在异步操作完成后,异步栈会按照先进先出(FIFO)的顺序逐个执行已排队的异步操作。
我们的迷惑就来自于执行顺序的反转。同步就是one by one很好理解,而异步操作(理解为一个耗时的操作)一般放在一个队列中,由事件循环(Event Loop)来调度和执行。
事件循环是一种用于管理和调度异步操作的机制,它负责处理事件、回调函数和异步任务的执行。
在JavaScript中,浏览器和Node.js环境都有自己的事件循环实现。下面是一个简化的事件循环的过程:
执行同步代码:事件循环首先会执行当前的同步代码块,直到遇到异步操作。
将异步操作加入队列:当遇到异步操作时,它会被添加到特定的队列中,例如任务队列(Task Queue)或微任务队列(Microtask Queue)。
等待执行:一旦异步操作被添加到队列中,事件循环将继续执行下一个同步代码块,而不会等待异步操作完成。
选择并执行下一个任务:当主线程空闲时,事件循环会从队列中选择一个任务,将其取出并执行。这个任务可以是一个回调函数或者其他类型的异步操作。
循环重复:一旦任务执行完成,事件循环会重复上述步骤,不断地从队列中选择和执行下一个任务,直到队列为空。
回调函数的使用:异步栈通常使用回调函数来表示异步操作的结果或处理逻辑。当异步操作完成时,相关的回调函数被调用,可以在其中处理操作的结果或进行下一步的操作。
事件驱动:异步栈基于事件驱动的模型,通过监听和触发事件来管理异步操作。当某个事件发生时,将相应的回调函数添加到异步栈中,等待执行。
非阻塞:异步栈允许同时进行多个异步操作,它们可以并行执行而不会相互阻塞。这使得程序能够更高效地利用计算资源。
错误处理:异步栈可以捕获和处理异步操作中发生的错误。通过在回调函数中检查错误参数或使用try-catch语句,可以对错误进行适当的处理和响应。
可扩展性:由于异步栈不会阻塞主线程或其他异步操作,因此可以轻松地添加更多的异步操作,以构建复杂的异步程序。这使得异步栈非常适合处理并发、IO密集型或需要处理大量请求的场景。
总的来说,异步栈的特点包括执行顺序的反转、使用回调函数、事件驱动、非阻塞、错误处理和可扩展性。这些特点使得异步栈成为处理异步编程的一种有效方式,使代码更具响应性和高效性。
目标网站:IGh0dHBzOi8vd3d3Lmppemh5LmNvbS8=
目标值:sign
对于异步网站,下小黄人(xhr)断点。
在以下阅读中,主要看回调函数在哪里?对于头部加密,请求参数在哪里?
断在send()处。往前跟栈(图中向下方向),下断点。
断在 n = n.then(e.shift(), e.shift());观察e中的回调函数
点击其中一个函数,可以来到请求拦截器。
对于请求拦截器代码段的解释:
onRequest: function(t) { this.interceptors.request.use((function(e) { return t(e) || e } )) }
这段代码使用一个 onRequest
函数来定义请求的处理逻辑。在函数内部,使用了 this.interceptors.request.use
方法来注册一个请求拦截器。use
方法接收一个回调函数作为参数,该函数会在发送请求之前执行。回调函数中的逻辑是将请求数据 e
传递给外部的回调函数 t
进行处理。如果外部的回调函数 t
返回一个值,那么该值将被用作最终的请求数据;否则,将保持原始的请求数据 e
不变。
可以做出如下的推测:
interceptors
是一个对象或类的属性,可能是用于处理请求和响应拦截的功能。
request
是指向请求拦截器的链式调用。
use
方法用于注册请求拦截器的回调函数。
在函数t处下断点
点击跟进t函数,此时右侧params:参数中并无sign.
当执行完"get" === e ? t.params = Qt(t.params) : "post" === e && (t.data = Qt(t.data))
后,sign出现,说明加密逻辑就在这一句中,很显然是Qt(),闹的。