逆向心得
js 逆向技巧分享
当我们抓取网页端数据时,经常被加密参数、加密数据所困扰,如何快速定位这些加解密函数,尤为重要。本片文章是我逆向 js 时一些技巧的总结,如有遗漏,欢迎补充。
所需环境:Chrome 浏览器
1. 搜索
1.1 全局搜索
适用于根据关键词快速定位关键文件及代码
当前页面右键->检查,弹出检查工具
搜索支持 关键词、正则表达式
1.2 代码内搜索
适用于根据关键词快速定位关键代码
点击代码,然后按 ctrl+f 或 command+f 调出搜索框。搜索支持 关键词、css 表达式、xpath
2. debug
2.1 常规 debug
适用于分析关键函数代码逻辑
- 埋下断点
- 调试
如图所示,我标记了 1 到 6,下面分别介绍其含义
1.执行到下一个端点 2.执行下一步,不会进入所调用的函数内部 3.进入所调用的函数内部 4.跳出函数内部 5.一步步执行代码,遇到有函数调用,则进入函数 6.Call Stack 为代码调用的堆栈信息,代码执行顺序为由下至上,这对于着关键函数前后调用关系很有帮助
2.2 XHR debug
匹配 url 中关键词,匹配到则跳转到参数生成处,适用于 url 中的加密参数全局搜索搜不到,可采用这种方式拦截
2.3 行为 debug
适用于点击按钮时,分析代码执行逻辑
如图所示,可快速定位点击探索按钮后,所执行的 js。
3 查看请求调用的堆栈
可以在 Network 选项卡下,该请求的 Initiator 列里看到它的调用栈,调用顺序由上而下:
4. 执行堆内存中的函数
当 debug 到某一个函数时,我们想主动调用,比如传递下自定义的参数,这时可以在检查工具里的 console 里调用
此处要注意,只有 debug 打这个函数时,控制台里才可以调用。如果想保留这个函数,可使用 this.xxx=xxx 的方式。之后调用时无需 debug 到 xxx 函数,直接使用http://this.xxx 即可。
5. 修改堆栈中的参数值
6. 写 js 代码
7. 打印 windows 对象的值
在 console 中输入如下代码,如只打印_$开头的变量值
for (var p in window) {
if (p.substr(0, 2) !== "_$")
continue;
console.log(p + " >>> " + eval(p))
}
8. 勾子
以 chrome 插件的方式,在匹配到关键词处插入断点
8.1 cookie 钩子
用于定位 cookie 中关键参数生成位置
var code = function(){
var org = document.cookie.__lookupSetter__('cookie');
document.__defineSetter__("cookie",function(cookie){
if(cookie.indexOf('TSdc75a61a')>-1){
debugger;
}
org = cookie;
});
document.__defineGetter__("cookie",function(){return org;});
}
var script = document.createElement('script');
script.textContent = '(' + code + ')()';
(document.head||document.documentElement).appendChild(script);
script.parentNode.removeChild(script);
当 cookie 中匹配到了 TSdc75a61a
, 则插入断点。
8.2 请求钩子
用于定位请求中关键参数生成位置
var code = function(){
var open = window.XMLHttpRequest.prototype.open;
window.XMLHttpRequest.prototype.open = function (method, url, async){
if (url.indexOf("MmEwMD")>-1){
debugger;
}
return open.apply(this, arguments);
};
}
var script = document.createElement('script');
script.textContent = '(' + code + ')()';
(document.head||document.documentElement).appendChild(script);
script.parentNode.removeChild(script);
当请求的 url 里包含MmEwMD
时,则插入断点
8.3 header 钩子
用于定位 header 中关键参数生成位置
var code = function(){
var org = window.XMLHttpRequest.prototype.setRequestHeader;
window.XMLHttpRequest.prototype.setRequestHeader = function(key,value){
if(key=='Authorization'){
debugger;
}
return org.apply(this,arguments);
}
}
var script = document.createElement('script');
script.textContent = '(' + code + ')()';
(document.head||document.documentElement).appendChild(script);
script.parentNode.removeChild(script);
当 header 中包含Authorization
时,则插入断点
8.4 manifest.json
插件的配置文件
{
"name": "Injection",
"version": "2.0",
"description": "RequestHeader钩子",
"manifest_version": 2,
"content_scripts": [
{
"matches": [
"<all_urls>"
],
"js": [
"inject.js"
],
"all_frames": true,
"permissions": [
"tabs"
],
"run_at": "document_start"
}
]
}
使用方法
- 如图所示,创建一个文件夹,文件夹中创建一个钩子函数文件 inject.js 及 插件的配置文件 manifest.json 即可
- 打开 chrome 的扩展程序, 加载已解压的扩展程序,选择步骤 1 创建的文件夹即可
- 切换回原网页,刷新页面,若钩子函数关键词匹配到了,则触发 debug
9. 破解无限 debugger 防调试
如果你打开 chrome 的检查工具,发现自动断到了如下的位置,那么这种手段为常用的反调试手段
对应的破解手段如下:
9.1 方法置空
从原函数中可以看到这是一个无限递归的函数,目的就是当你开启了检查工具时,出现无数次 debug,阻止你 debug 调试。那么我们重写这个函数就可以了,在 Console 一栏中使用匿名函数给本函数重新赋值,这样就把_0x355d23
函数变为了一个空函数,达到了破解无限 debugger 的目的
9.2 干掉定时器
适用于定时器类触发的 debug
for (var i = 1; i < 99999; i++)window.clearInterval(i);
9.3 中间人拦截替换无限 debug 函数
推荐使用 mitmproxy 拦截
10. console 中使用 xpath 或 css
xpath: $x("your_xpath_selector")
css: $$("css_selector")
总结
以上为我做 js 逆向分析时用到的手段,如有不足之处或更多技巧,欢迎指教补充。愿本文的分享对您之后分析 js 有所帮助。谢谢~