日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 前端技术 > javascript >内容正文

javascript

JS 逆向 --- 过无限debugge、hook、js混淆还原、控制流混淆

發(fā)布時(shí)間:2024/7/23 javascript 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JS 逆向 --- 过无限debugge、hook、js混淆还原、控制流混淆 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

?

訪問(wèn)這個(gè)網(wǎng)站的時(shí)候,cookie 里面會(huì)有一個(gè) sign 值,這個(gè)sign 值是通過(guò) JavaScript 代碼生成的,JS 代碼是用?ob 混淆的,

當(dāng)打開(kāi) "開(kāi)發(fā)者工具" 時(shí),會(huì)直接進(jìn)入 "無(wú)限 debugger" 模式,過(guò)無(wú)限debugger 模式這里有三種方法

  • 方法 1.? 直接 "從不在此處斷點(diǎn)"
  • 方法 2.? 查看調(diào)用堆棧,把進(jìn)入無(wú)限 debugger 的那個(gè)函數(shù)在console中重新定義,把函數(shù)置空
  • 方法 3.? 通過(guò)中間人攻擊,替換 JavaScript 代碼文件成本地文件,在本地文件中把 無(wú)限debugger 功能去掉( 注釋掉 )。
    ? ? 這種方法可以進(jìn)行本地?cái)帱c(diǎn)調(diào)試,和實(shí)時(shí)驗(yàn)證逆向的代碼邏輯

這里使用?方法 3,把網(wǎng)站返回的混淆后的JS代碼拿下來(lái),放到 demo.html 文件里面,并用 <script></script>? 包括,同時(shí),把 hook cookie 的代碼和框架代碼也放里面,并放在 混淆代碼之前

hook cookie 的代碼:

(function () {'use strict';var cookie_cache = document.cookie;Object.defineProperty(document, 'cookie', {get: function () {console.log(cookie_cache);return cookie_cache;},set: function (val) {debugger;var cookie = val.split(";")[0];var ncookie = cookie.split("=");var flag = false;var cache = cookie_cache.split(";");cache = cache.map(function (a) {if (a.split("=")[0] === ncookie[0]) {flag = true;return cookie;}return a;})cookie_cache = cache.join(";");if (!flag) {cookie_cache += cookie + ";";}},}); })();

hook 框架的代碼:

  • hook 和 AOPHooker JShttps://gitee.com/HGJing/hooker-js

?

demo.html 文件構(gòu)造好后,打開(kāi) fiddler ---> AutoResponder,添加規(guī)則,

chrome 打上 script 斷點(diǎn),然后訪問(wèn)目標(biāo)網(wǎng)站,即可斷下

可以看到訪問(wèn) JS 時(shí),已經(jīng)變成我們本地的 demo.html 文件了。然后去掉 script 斷點(diǎn),繼續(xù)運(yùn)行,會(huì)進(jìn)入 無(wú)限debugger 模式,可以在本地文件中找到無(wú)限 debugger 的函數(shù),直接注釋掉,或者刪除即可,也可以在console直接置空,更簡(jiǎn)單的是直接 "never pause here",這里使用?"never pause here" 然后繼續(xù)運(yùn)行,等待一會(huì)會(huì)直接進(jìn)入 hook cookie 的 set 函數(shù)中,查看調(diào)用堆棧,即可找到關(guān)鍵位置

關(guān)鍵 JS 代碼:_0x521302[$_0x5780('\x30\x78\x37\x38', '\x4f\x71\x6c\x44') + '\x65\x4c'](_0x30c194, _0x521302['\x48\x43\x54' + '\x65\x4c'](_0x451a25, _0x521302['\x55\x64\x79' + '\x56\x42'](_0x1af341)))

  • $_0x5780('\x30\x78\x37\x38', '\x4f\x71\x6c\x44') + '\x65\x4c' 放到 console 里面執(zhí)行得到?"HCTeL"
  • '\x48\x43\x54' + '\x65\x4c'?放到 console 里面執(zhí)行得到?"HCTeL"
  • '\x55\x64\x79' + '\x56\x42'?放到 console 里面執(zhí)行得到?"UdyVB"

所以關(guān)鍵代碼可以還原為:_0x521302["HCTeL"](_0x30c194, _0x521302["HCTeL"](_0x451a25, _0x521302["UdyVB"](_0x1af341)))

繼續(xù)還原?_0x1af341,在 console 中執(zhí)行,可以發(fā)現(xiàn) 是一個(gè)函數(shù),執(zhí)行 toString() 方法,打印方法內(nèi)容。

function _0x1af341(_0x250d81){return new Date()[$_0x5780('\x30\x78\x37\x65','\x64\x24\x75\x57')+$_0x5780('\x30\x78\x63\x30','\x69\x7a\x39\x37')+'\x66']();}

上面函數(shù)繼續(xù)進(jìn)行還原:$_0x5780('\x30\x78\x37\x65','\x64\x24\x75\x57')+$_0x5780('\x30\x78\x63\x30','\x69\x7a\x39\x37')+'\x66' 執(zhí)行后得到?"valueOf",

所以上面方法可以還原為:function _0x1af341(_0x250d81){return new Date().valueOf();}

現(xiàn)在還原?_0x521302["UdyVB"] 方法:執(zhí)行?_0x521302["UdyVB"].toString()

可以看到這個(gè)函數(shù)傳遞了一個(gè)參數(shù),這個(gè)參數(shù)執(zhí)行了一個(gè)函數(shù),函數(shù)體是返回函數(shù)執(zhí)行后的結(jié)果。

所以?_0x521302["HCTeL"](_0x30c194, _0x521302["HCTeL"](_0x451a25, _0x521302["UdyVB"](_0x1af341)))

可以還原為??_0x521302["HCTeL"](_0x30c194, _0x521302["HCTeL"](_0x451a25, _0x1af341()))

再進(jìn)一步還原:_0x521302["HCTeL"](_0x30c194, _0x521302["HCTeL"](_0x451a25, new Date().valueOf()))? ,驗(yàn)證還原結(jié)果:

按照上面方法在進(jìn)一步還原:_0x30c194(_0x451a25(new Date().valueOf()))

現(xiàn)在只需要分析?_0x30c194、_0x451a25 ,先看下 _0x451a25 函數(shù)的 toString() :function _0x451a25(_0x787271){return _0x521302[$_0x5780('\x30\x78\x31\x33\x65','\x52\x5a\x77\x72')+'\x66\x4d'](_0x521302[$_0x5780('\x30\x78\x34\x35','\x4b\x73\x48\x58')+'\x66\x4d'](_0x521302[$_0x5780('\x30\x78\x31\x33\x65','\x52\x5a\x77\x72')+'\x66\x4d'](_0x521302[$_0x5780('\x30\x78\x61\x31','\x29\x72\x71\x78')+'\x72\x6d'],_0x787271)+'\x7e',_0x521302[$_0x5780('\x30\x78\x31\x32','\x71\x75\x31\x47')+'\x41\x75'](_0x5b6292,_0x787271)),_0x521302[$_0x5780('\x30\x78\x66\x33','\x30\x33\x4e\x46')+'\x45\x71']);}

按上面步驟還原:

function _0x451a25(_0x787271) {return "sign=" + _0x787271 + "~" + _0x5b6292(_0x787271) + "; path=/"; }

所以整體邏輯可以變?yōu)?/p> function _0x451a25(_0x787271) {return "sign=" + _0x787271 + "~" + _0x5b6292(_0x787271) + "; path=/"; }var timestamp = new Date().valueOf() _0x30c194(_0x451a25(timestamp))//等價(jià)于 _0x30c194("sign=" + timestamp + "~" + _0x5b6292(timestamp) + "; path=/")

****************** 關(guān)鍵邏輯部分?******************

這里只需要 分析?_0x5b6292(timestamp) 即可。

看下?_0x5b6292 的 toString():function _0x5b6292(_0x141932){return _0x521302[$_0x5780('\x30\x78\x62\x34','\x41\x6f\x23\x33')+'\x41\x75'](_0x2e58ec,_0x141932);}?

還原后等價(jià)于:_0x2e58ec(timestamp)

再繼續(xù)分析??_0x2e58ec 。看下?_0x2e58ec 的 toString():"function _0x2e58ec(_0x2dd05e,_0x2bf8cf,_0x597aa3){return _0x2bf8cf?_0x597aa3?_0x521302[$_0x5780('\x30\x78\x62\x39','\x4b\x73\x48\x58')+'\x6c\x75'](_0x5b6292,_0x2bf8cf,_0x2dd05e):_0x521302[$_0x5780('\x30\x78\x31\x31\x30','\x43\x34\x4e\x62')+'\x44\x44'](_0x1af341,_0x2bf8cf,_0x2dd05e):_0x597aa3?_0x521302[$_0x5780('\x30\x78\x63\x32','\x69\x65\x46\x51')+'\x4d\x6d'](_0x1091df,_0x2dd05e):_0x521302['\x75\x6d\x74'+'\x4e\x65'](_0x289aa2,_0x2dd05e);}"

還原后等價(jià)于:_0x289aa2(timestamp)

繼續(xù)分析?_0x289aa2 。看下?_0x289aa2 的 toString():function _0x289aa2(_0x22d83d){return _0x521302[$_0x5780('\x30\x78\x33\x37','\x5d\x57\x5a\x62')+'\x4d\x6d'](_0x554ed6,_0x1091df(_0x22d83d));}

還原后等價(jià)于:_0x554ed6(_0x1091df(timestamp))

總體邏輯等價(jià)于:_0x554ed6(_0x3f26c9(_0x161382(timestamp)))

_0x161382.toString():function _0x161382(_0x3dad10){return unescape(_0x521302[$_0x5780('\x30\x78\x34\x62','\x52\x5a\x77\x72')+'\x4d\x6d'](encodeURIComponent,_0x3dad10));}

還原后等價(jià)于:function _0x161382(timestamp){return unescape(encodeURIComponent(timestamp));}

整體邏輯等價(jià)于:_0x554ed6(_0x3f26c9(unescape(encodeURIComponent(timestamp))))

var timestamp = new Date().valueOf() var encode_timestamp = unescape(encodeURIComponent(timestamp)) _0x554ed6(_0x3f26c9(encode_timestamp))

_0x3f26c9.toString():function _0x3f26c9(_0x4b9199){return _0x2b5e04(_0x1cb205(_0x17d11d(_0x4b9199),_0x521302[$_0x5780('\x30\x78\x64\x39','\x5e\x74\x58\x6a')+'\x43\x73'](0x8,_0x4b9199[$_0x5780('\x30\x78\x65\x30','\x55\x74\x46\x4b')+$_0x5780('\x30\x78\x35\x30','\x39\x2a\x79\x29')])));}

還原后等價(jià)于:

?

后面就是 摳??_0x554ed6? 和?_0x3f26c9 的代碼,然后執(zhí)行 js 即可得到。。。。。。

?

?

?

?

?

總結(jié)

以上是生活随笔為你收集整理的JS 逆向 --- 过无限debugge、hook、js混淆还原、控制流混淆的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。