當(dāng)我們抓取網(wǎng)頁(yè)端數(shù)據(jù)時(shí),經(jīng)常被加密參數(shù)、加密數(shù)據(jù)所困擾,如何快速定位這些加解密函數(shù),尤為重要。本片文章是我逆向js時(shí)一些技巧的總結(jié),如有遺漏,歡迎補(bǔ)充。
所需環(huán)境:瀏覽器
1. 搜索1.1 全局搜索 適用于根據(jù)關(guān)鍵詞快速定位關(guān)鍵文件及代碼
當(dāng)前頁(yè)面右鍵->檢查,彈出檢查工具
搜索支持 關(guān)鍵詞、正則表達(dá)式
1.2 代碼內(nèi)搜索 適用于根據(jù)關(guān)鍵詞快速定位關(guān)鍵代碼
點(diǎn)擊代碼,然后按ctrl+f 或 +f 調(diào)出搜索框。搜索支持 關(guān)鍵詞、css表達(dá)式、xpath
2. .1 常規(guī)debug 適用于分析關(guān)鍵函數(shù)代碼邏輯
埋下斷點(diǎn)
調(diào)試
如圖所示,我標(biāo)記了1到6js點(diǎn)擊滑動(dòng)到指定位置js點(diǎn)擊滑動(dòng)到指定位置,下面分別介紹其含義
1.執(zhí)行到下一個(gè)端點(diǎn) 2.執(zhí)行下一步,不會(huì)進(jìn)入所調(diào)用的函數(shù)內(nèi)部 3.進(jìn)入所調(diào)用的函數(shù)內(nèi)部 4.跳出函數(shù)內(nèi)部 5.一步步執(zhí)行代碼,遇到有函數(shù)調(diào)用,則進(jìn)入函數(shù) 6.Call Stack 為代碼調(diào)用的堆棧信息,代碼執(zhí)行順序?yàn)橛上轮辽希@對(duì)于著關(guān)鍵函數(shù)前后調(diào)用關(guān)系很有幫助
2.2 XHR debug 匹配url中關(guān)鍵詞,匹配到則跳轉(zhuǎn)到參數(shù)生成處,適用于url中的加密參數(shù)全局搜索搜不到,可采用這種方式攔截
2.3 行為debug 適用于點(diǎn)擊按鈕時(shí),分析代碼執(zhí)行邏輯
如圖所示,可快速定位點(diǎn)擊探索按鈕后,所執(zhí)行的js。
3 查看請(qǐng)求調(diào)用的堆棧
可以在 選項(xiàng)卡下,該請(qǐng)求的 列里看到它的調(diào)用棧,調(diào)用順序由上而下:
4. 執(zhí)行堆內(nèi)存中的函數(shù)
當(dāng)debug到某一個(gè)函數(shù)時(shí),我們想主動(dòng)調(diào)用,比如傳遞下自定義的參數(shù),這時(shí)可以在檢查工具里的里調(diào)用
此處要注意,只有debug打這個(gè)函數(shù)時(shí),控制臺(tái)里才可以調(diào)用。如果想保留這個(gè)函數(shù),可使用this.xxx=xxx 的方式。之后調(diào)用時(shí)無(wú)需debug到xxx函數(shù),直接使用this.xxx 即可。
5. 修改堆棧中的參數(shù)值
6. 寫js代碼
7. 打印對(duì)象的值
在中輸入如下代碼,如只打印_$開(kāi)頭的變量值
for (var p in window) {
if (p.substr(0, 2) !== "_$")
continue;
console.log(p + " >>> " + eval(p))
}
8. 勾子 以插件的方式,在匹配到關(guān)鍵詞處插入斷點(diǎn)
8.1 鉤子 用于定位中關(guān)鍵參數(shù)生成位置
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);
當(dāng)中匹配到了 , 則插入斷點(diǎn)。
8.2 請(qǐng)求鉤子 用于定位請(qǐng)求中關(guān)鍵參數(shù)生成位置
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);
當(dāng)請(qǐng)求的url里包含時(shí),則插入斷點(diǎn)
8.3 鉤子 用于定位中關(guān)鍵參數(shù)生成位置
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);
當(dāng)中包含時(shí),則插入斷點(diǎn)
8.4 .json 插件的配置文件
{
"name": "Injection",

"version": "2.0",
"description": "RequestHeader鉤子",
"manifest_version": 2,
"content_scripts": [
{
"matches": [
""
],
"js": [
"inject.js"
],
"all_frames": true,
"permissions": [
"tabs"
],
"run_at": "document_start"
}
]
}
使用方法 如圖所示,創(chuàng)建一個(gè)文件夾,文件夾中創(chuàng)建一個(gè)鉤子函數(shù)文件.js 及 插件的配置文件 .json 即可
打開(kāi) 的擴(kuò)展程序, 加載已解壓的擴(kuò)展程序,選擇步驟1創(chuàng)建的文件夾即可
切換回原網(wǎng)頁(yè),刷新頁(yè)面,若鉤子函數(shù)關(guān)鍵詞匹配到了,則觸發(fā)debug
9. 破解無(wú)限防調(diào)試
如果你打開(kāi)的檢查工具,發(fā)現(xiàn)自動(dòng)斷到了如下的位置,那么這種手段為常用的反調(diào)試手段
對(duì)應(yīng)的破解手段如下:
9.1 方法置空
從原函數(shù)中可以看到這是一個(gè)無(wú)限遞歸的函數(shù),目的就是當(dāng)你開(kāi)啟了檢查工具時(shí),出現(xiàn)無(wú)數(shù)次debug,阻止你debug調(diào)試。那么我們重寫這個(gè)函數(shù)就可以了,在 一欄中使用匿名函數(shù)給本函數(shù)重新賦值,這樣就把函數(shù)變?yōu)榱艘粋€(gè)空函數(shù),達(dá)到了破解無(wú)限的目的
9.2 干掉定時(shí)器
適用于定時(shí)器類觸發(fā)的debug
for (var i = 1; i < 99999; i++)window.clearInterval(i);
9.3 中間人攔截替換無(wú)限debug函數(shù)
推薦使用攔截
10. 中使用xpath或css
xpath: $x("your_xpath_selector")
css: $$("css_selector")
11. 下 (過(guò)濾器)
篩選框可以實(shí)現(xiàn)很多定制化的篩選,比如字符串匹配,關(guān)鍵詞篩選等,其中關(guān)鍵詞篩選主要有如下幾種(輸入-顯示全部):
:僅顯示來(lái)自指定域的資源。您可以使用通配符()來(lái)包括多個(gè)域。例如,.com顯示以.com結(jié)尾的所有域名中的資源。 會(huì)在自動(dòng)完成下拉菜單中自動(dòng)填充它遇到的所有域。has--:顯示包含指定HTTP響應(yīng)頭信息的資源。 會(huì)在自動(dòng)完成下拉菜單中自動(dòng)填充它遇到的所有響應(yīng)頭。is:通過(guò)is:找出請(qǐng)求。-than(大于) :顯示大于指定大小的資源(以字節(jié)為單位)。設(shè)置值1000等效于設(shè)置值1k。(方法) :顯示通過(guò)指定的HTTP方法類型檢索的資源。使用它遇到的所有HTTP方法填充下拉列表。mime-type(mime類型:顯示指定MIME類型的資源。 使用它遇到的所有MIME類型填充下拉列表。mixed-(混合內(nèi)容:顯示所有混合內(nèi)容資源(mixed-:all)或僅顯示當(dāng)前顯示的內(nèi)容(mixed-:)。(協(xié)議):顯示通過(guò)不受保護(hù)的HTTP(:http)或受保護(hù)的HTTPS(:https)檢索的資源。set--(域):顯示具有Set-頭,并且其屬性與指定值匹配的資源。會(huì)在自動(dòng)完成下拉菜單中自動(dòng)填充它遇到的所有域。set--name(名):顯示具有Set-頭,并且名稱與指定值匹配的資源。會(huì)在自動(dòng)完成下拉菜單中自動(dòng)填充它遇到的所有名。set--value(值):顯示具有Set-頭,并且值與指定值匹配的資源。會(huì)在自動(dòng)完成下拉菜單中自動(dòng)填充它遇到的所有值。-code(狀態(tài)碼):僅顯示其HTTP狀態(tài)代碼與指定代碼匹配的資源。會(huì)在自動(dòng)完成下拉菜單中自動(dòng)填充它遇到的所有狀態(tài)碼。總結(jié)
以上為我做js逆向分析時(shí)用到的手段,如有不足之處或更多技巧,歡迎指教補(bǔ)充。愿本文的分享對(duì)您之后分析js有所幫助。謝謝~