js中的关键代码快速定位
开发者工具使用
settings的Network里勾选preserve log
和disable cache
,Console里勾选Log XMLHttpRequests
有的网页,直接查看源码里有的标签元素,通过爬虫直接去获取的时候反而不存在,可能是由于该元素是由js代码去动态生成的,初始的页面源码里并没有
如果想查看按钮绑定的事件,在Elements里面右侧的Event listeners
里,可以取消勾选Ancestors,这个选项是监听祖先节点的事件的,对于按钮来说不需要,然后可以找到该按钮对应的事件代码在哪里
搜索和普通断点
点击右上角三个点,把show console drawer
打开,然后在下面控制台框的左上角三个点选search
,可以搜索url或者参数
以https://cj.eloancn.com/网站的登录为例
全局搜索url,找到对应代码,跳转过去
找到定义login_url_: "/pcgway/login/v1/02"
,继续搜索login_url_
,找到dosubmit
函数
在this.$fech
处打上断点,点击登录之后成功断在该行代码
此时查看变量值发现password还是被加密的状态,所以加密函数不在这里,应该在上层函数,查看右侧函数栈,往上回溯函数,一直找到login函数,这里很可能是加密逻辑的代码,对象e存储password,现在找对象e在哪里生成的,用正则表达式搜索e,代表只匹配e这个单词,\be\b
,当然这里用这个方法是多此一举
在password: r.PUBLIC.encryptByDES(this.checkPwd.password.trim(), r.PUBLIC.DESkey)
打断点即可,或者直接鼠标选中this.checkPwd.password.trim()
,会显示计算出来的值,从而知道该行代码就是加密的代码
还有一种方法是搜变量,比如password,还可以衍生出很多种搜索方法
1 | password= |
或者搜其他参数、搜码表、搜S盒、K表
xhr和callstack
当登录请求是xhr请求的时候,可以进行xhr断点,在source面板右侧有xhr/fetch breakpoints
点击加号可以添加字符串,当xhr请求的url中有这个字符串的时候会断下来
Initiator和callstack
Network面板里会显示发起请求的时候的js代码所在位置
事件断点
事件触发,比如按钮点击事件,不一定是在按钮元素上绑定事件,也可能是在祖先元素上绑定事件,也可以触发(事件委派)
右键按钮元素,检查,右侧可以找到Event Listener
,进而找到代码
此外还有全局事件断点,在source
面板中的右侧Event Listener Breakpoints
里有各种全局事件
debugger和条件断点
什么是条件断点,比如一个for循环,循环500次,我希望其在第400次的时候断下来,肯定不希望执行400次,就需要设置一个条件,在达到这个条件的时候断下来,在webstorm里就是在断点处右键即可,浏览器中设置条件断点的方式也是一样的
debugger的作用就是,在js代码中,正常执行的时候,debugger的位置不会断下来,但是调试的时候就断在这里了
js Hook
一般不去在局部代码内去hook,比如
1 | !function(){ |
因为内部代码块里很难知道哪个函数是关键函数,都是被混淆了的代码
大部分时候js hook用来去hook全局变量、全局对象下的一些方法
能够在全局作用域下访问的东西,很适合做js hook
比如在canvas创建的时候,hook drawImage
函数,要想hook一个函数,首先要知道这个函数是在哪个对象下面的,一般是在原型对象下面定义的,hook的时候是先保存原来的方法,再去覆盖该方法
以某宁为例,打开全局事件canvas create
断点,会断在canvas被初始化的地方,这个地方有时候离drawImage
的代码还很远,这个时候可以用hook去获取该方法的参数,在控制台可以运行t.call(e, u, y).__proto__
查看原型对象
控制台输入如下代码,然后会在调用drawImage
的时候输出参数
1 | const __drawImage = CanvasRenderingContext2D.prototype.drawImage; |
hook和debug结合,会在调用drawImage
的时候断下来,然后通过回溯函数栈,可以定位到触发drawImage
函数的位置
1 | const __drawImage = CanvasRenderingContext2D.prototype.drawImage; |