日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

PopUnder 研究:Javascript逆向與反逆向

瀏覽:34日期:2023-11-12 08:55:42
緣起

最近在研究 PopUnder 的實現方案,通過 Google 搜索 js popunder 出來的第一頁中有個網站 popunderjs.com ,當時看了下,這是個提供 popunder 解決方案的一家公司,而且再翻了幾頁,發現市面上能解決這個問題的,只有2家公司,可見這個市場基本是屬于壟斷型的。

popunderjs 原來在 github 上是有開源代碼的,但后來估計作者發現這個需求巨大的商業價值,索性不開源了,直接收費。所以現在要研究它的實現方案,只能上官網扒它源碼了。

這是它的示例頁: http://code.ptcong.com/demos/bjp/demo.html 分別加載了幾個重要文件:

http://code.ptcong.com/demos/bjp/script.js?0.3687041198903791http://code.ptcong.com/demos/bjp/license.demo.js?0.31109710863616447 文件結構

script.js 是功能主體,實現了 popunder 的所有功能以及定義了多個 API 方法

license.demo.js 是授權文件,有這個文件你才能順利調用 script.js 里的方法

防止被逆向

這么具有商業價值的代碼,就這么公開地給你們用,肯定要考慮好被逆向的問題。我們來看看它是怎么反逆向的。

首先,打開控制臺,發現2個問題:

控制臺所有內容都被反復清空,只輸出了這么一句話: Console was cleared script.js?0.5309098417125133:1 無法斷點調試,因為一旦啟用斷點調試功能,就會被定向到一個匿名函數 (function() {debugger})

也就是說,常用的斷點調試方法已經無法使用了,我們只能看看源代碼,看能不能理解它的邏輯了。但是,它源代碼是這樣的:

var a = typeof window === S[0] && typeof window[S[1]] !== S[2] ? window : global; try {a[S[3]](S[4]);return function() {}; } catch (a) {try { (function() {} [S[11]](S[12])()); return function() {} ;} catch (a) { if (/TypeError/[S[15]](a + S[16])) {return function() {}; }} }

可見源代碼是根本不可能閱讀的,所以還是得想辦法破掉它的反逆向措施。

利用工具巧妙破解反逆向

首先在斷點調試模式一步步查看它都執行了哪些操作,突然就發現了這么一段代碼:

(function() { (function a() {try { (function b(i) {if ((’’ + (i / i)).length !== 1 || i % 20 === 0) { (function() {} ).constructor(’debugger’)();} else { debugger ;}b(++i); } )(0);} catch (e) { setTimeout(a, 5000);} } )()})();

這段代碼主要有2部分,一是通過 try {} 塊內的 b() 函數來判斷是否打開了控制臺,如果是的話就進行自我調用,反復進入 debugger 這個斷點,從而達到干擾我們調試的目的。如果沒有打開控制臺,那調用 debugger 就會拋出異常,這時就在 catch {} 塊內設置定時器,5秒后再調用一下 b() 函數。

這么說來其實一切的一切都始于 setTimeout 這個函數(因為 b() 函數全是閉包調用,無法從外界破掉),所以只要在 setTimeout 被調用的時候,不讓它執行就可以破解掉這個死循環了。

所以我們只需要簡單地覆蓋掉 setTimeout 就可以了……比如:

window._setTimeout = window.setTimeout;window.setTimeout = function () {};

但是!這個操作無法在控制臺里面做!因為當你打開控制臺的時候,你就必然會被吸入到 b() 函數的死循環中。這時再來覆蓋 setTimeout 已經沒有意義了。

這時我們的工具 TamperMonkey 就上場了,把代碼寫到 TM 的腳本里,就算不打開控制臺也能執行了。

TM 腳本寫好之后,刷新頁面,等它完全加載完,再打開控制臺,這時 debugger 已經不會再出現了!

接下來就輪到控制臺刷新代碼了

通過 Console was cleared 右側的鏈接點進去定位到具體的代碼,點擊 {} 美化一下被壓縮過的代碼,發現其實就是用 setInterval 反復調用 console.clear() 清空控制臺并輸出了 <div>Console was cleared</div> 信息,但是注意了,不能直接覆蓋 setInterval 因為這個函數在其他地方也有重要的用途。

所以我們可以通過覆蓋 console.clear() 函數和過濾 log 信息來阻止它的清屏行為。

同樣寫入到 TamperMonkey 的腳本中,代碼:

window.console.clear = function() {};window.console._log = window.console.log;window.console.log = function (e) { if (e[’nodeName’] && e[’nodeName’] == ’DIV’) {return ; } return window.console.error.apply(window.console._log, arguments);};

之所以用 error 來輸出信息,是為了查看它的調用棧,對理解程序邏輯有幫助。

基本上,做完這些的工作之后,這段代碼就可以跟普通程序一樣正常調試了。但還有個問題,它主要代碼是經常混淆加密的,所以調試起來很有難度。下面簡單講講過程。

混淆加密方法一:隱藏方法調用,降低可讀性

從 license.demo.js 可以看到開頭有一段代碼是這樣的:

var zBCa = function T(f) { for (var U = 0, V = 0, W, X, Y = (X = decodeURI('+TR4W%17%7F@%17.....省略若干'), W = ’’, ’D68Q4cYfvoqAveD2D8Kb0jTsQCf2uvgs’); U < X.length; U++, V++) {if (V === Y.length) { V = 0;}W += String['fromCharCode'](X['charCodeAt'](U) ^ Y['charCodeAt'](V)); } var S = W.split('&&');

通過跟蹤執行,可以發現 S 變量的內容其實是本程序所有要用到的類名、函數名的集合,類似于 var S = [’console’, ’clear’, ’console’, ’log’] 。如果要調用 console.clear() 和 console.log() 函數的話,就這樣

var a = window;a[S[0]][S[1]]();a[S[2]][S[3]](); 混淆加密方法二:將函數定義加入到證書驗證流程

license.demo.js 中有多處這樣的代碼:

a[’RegExp’](’/R[S]{4}p.cwn[D]{5}twr/’,’g’)[’test’](T + ’’)

這里的 a 代表 window,T 代表某個函數, T + ’’ 的作用是把 T 函數的定義轉成字符串,所以這段代碼的意思其實是,驗證 T 函數的定義中是否包含某些字符。

每次成功的驗證,都會返回一個特定的值,這些個特定的值就是解密核心證書的參數。

可能是因為我重新整理了代碼格式,所以在重新運行的時候,這個證書一直運行不成功,所以后來就放棄了通過證書來突破的方案。

逆向思路:輸出所有函數調用和參數

通過斷點調試,我們可以發現,想一步一步深入地搞清楚這整個程序的邏輯,是十分困難,因為它大部分函數之間都是相互調用的關系,只是參數的不同,結果就不同。

所以我后來想了個辦法,就是只查看它的系統函數的調用,通過對調用順序的研究,也可以大致知道它執行了哪些操作。

要想輸出所有系統函數的調用,需要解決以下問題:

覆蓋所有內置變量及類的函數,我們既要覆蓋 window.console.clear() 這樣的依附在實例上的函數,也要覆蓋依附在類定義上的函數,如 window.HTMLAnchorElement.__proto__.click() 需要正確區分內置函數和自定義函數

經過搜索后,找到了區分內置函數的代碼:

// Used to resolve the internal `[[Class]]` of values var toString = Object.prototype.toString; // Used to resolve the decompiled source of functions var fnToString = Function.prototype.toString; // Used to detect host constructors (Safari > 4; really typed array specific) var reHostCtor = /^[object .+?Constructor]$/; // Compile a regexp using a common native method as a template. // We chose `Object#toString` because there’s a good chance it is not being mucked with. var reNative = RegExp(’^’ + // Coerce `Object#toString` to a string String(toString) // Escape any special regexp characters .replace(/[.*+?^${}()|[]/]/g, ’$&’) // Replace mentions of `toString` with `.*?` to keep the template generic. // Replace thing like `for ...` to support environments like Rhino which add extra info // such as method arity. .replace(/toString|(function).*?(?=()| for .+?(?=])/g, ’$1.*?’) + ’$’ ); function isNative(value) { var type = typeof value; return type == ’function’ // Use `Function#toString` to bypass the value’s own `toString` method // and avoid being faked out. ? reNative.test(fnToString.call(value)) // Fallback to a host object check because some environments will represent // things like typed arrays as DOM methods which may not conform to the // normal native pattern. : (value && type == ’object’ && reHostCtor.test(toString.call(value))) || false; }

然后結合網上的資料,寫出了遞歸覆蓋內置函數的代碼:

function wrapit(e) { if (e.__proto__) {wrapit(e.__proto__); } for (var a in e) {try { e[a];} catch (e) { // pass continue;}var prop = e[a];if (!prop || prop._w) continue;prop = e[a];if (typeof prop == ’function’ && isNative(prop)) { e[a] = (function (name, func) {return function () { var args = [].splice.call(arguments,0); // convert arguments to array if (false && name == ’getElementsByTagName’ && args[0] == ’iframe’) { } else {console.error((new Date).toISOString(), [this], name, args); } if (name == ’querySelectorAll’) {//alert(’querySelectorAll’); } return func.apply(this, args);}; })(a, prop); e[a]._w = true;}; }}

使用的時候只需要:

wrapit(window);wrapit(document);

然后模擬一下正常的操作,觸發 PopUnder 就可以看到它的調用過程了。

參考資料:

A Beginners’ Guide to Obfuscation Detect if function is native to browser Detect if a Function is Native Code with JavaScript

來自:http://www.jianshu.com/p/9148d215c119

標簽: JavaScript
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
国产一区二区三区久久久久久久久| 日韩国产在线一| 久久一区二区中文字幕| 亚洲精品亚洲人成在线观看| 日韩精彩视频在线观看| 鲁大师精品99久久久| 久久只有精品| 玖玖玖国产精品| 丝袜美腿诱惑一区二区三区| 亚洲高清激情| 国产精品亚洲片在线播放| 免费观看日韩电影| 一区二区亚洲视频| 国产精品美女| 日韩精品视频网| 国产精品久久久久久av公交车| 亚洲综合中文| 国产在线视频欧美一区| 国产亚洲永久域名| 久久超级碰碰| 亚洲国产影院| 国产一区二区精品| 97久久精品| 婷婷六月综合| 亚洲三级在线| 老司机精品视频网| 欧美女激情福利| 国产日韩高清一区二区三区在线| 日韩av自拍| 午夜久久av| 女生影院久久| 男人的天堂亚洲一区| 久久97视频| 国产在线欧美| 国产精品毛片视频| 亚洲一区网站| 久久一区欧美| 国产视频一区二| 一区二区三区四区在线观看国产日韩| 国产免费av一区二区三区| 亚洲www免费| 国产麻豆精品| 亚洲一区二区三区高清不卡| 日韩精品久久理论片| 在线手机中文字幕| 一区二区91| 色综合五月天| 中文字幕视频精品一区二区三区| 久久国产生活片100| 国产成人久久| 国产免费播放一区二区| 国产精品普通话对白| 精品一区二区三区在线观看视频| 天堂va在线高清一区| 欧美成人a交片免费看| 午夜一级在线看亚洲| 亚洲三级欧美| 国产精品久久久久久模特| 日韩午夜电影| 国产在线日韩精品| 欧美日韩精品一区二区三区视频| 在线观看视频免费一区二区三区| 精品欧美一区二区三区在线观看| 久久国产精品色av免费看| 中文字幕日韩亚洲| av不卡在线| 亚洲欧美日韩国产一区| 狠狠久久婷婷| 日韩中文字幕91| 激情五月综合| 99久久婷婷这里只有精品| 日韩成人综合| 成人精品视频| 国产精品欧美在线观看| 国产精品一区2区3区| 欧美日韩中出| 中文字幕免费一区二区| 精品国产aⅴ| 欧美黄色网页| 国产亚洲精品精品国产亚洲综合 | 欧美三区不卡| 成人午夜在线| 日本中文字幕不卡| 国产成人77亚洲精品www| 91精品国产自产观看在线| 99在线|亚洲一区二区| 日韩欧美网址| 亚洲黄色免费av| 国产一区二区三区视频在线| 日本精品国产| 日本在线视频一区二区| 午夜在线精品偷拍| 国产超碰精品| 高清日韩中文字幕| 国产日产一区| 国产亚洲欧美日韩精品一区二区三区| 久久最新视频| aa国产精品| 国产精品亚洲片在线播放| 日韩中文字幕av电影| av一区在线| 久久xxx视频| 国产精品亚洲综合色区韩国| 伊人国产精品| 日本aⅴ亚洲精品中文乱码| 日韩在线观看中文字幕| 色婷婷成人网| 精品一区视频| 黄色在线网站噜噜噜| 蜜桃成人av| 亚洲色图网站| 久久影院资源站| 日韩欧美三级| 国产在线不卡| 婷婷综合一区| 精品不卡一区| 久久精品在线| 丝袜a∨在线一区二区三区不卡| 日韩专区欧美专区| 国产精品久久久久久av公交车| 激情黄产视频在线免费观看| 免费观看久久av| 深夜日韩欧美| 麻豆高清免费国产一区| 激情欧美一区| 国产精品手机在线播放| 成人污污视频| 亚洲免费中文| 亚洲乱码一区| **爰片久久毛片| 精品资源在线| 国产精品免费看| 精品国产99| 亚洲视频二区| 国产成人精品一区二区三区视频 | 色乱码一区二区三区网站| 中文字幕在线高清| 在线日韩中文| 国产剧情一区二区在线观看| 在线日韩中文| 老色鬼精品视频在线观看播放| 蜜桃tv一区二区三区| 日本成人在线不卡视频| 久久精品动漫| 国产精品红桃| 久久亚洲影院| 国产伦久视频在线观看| 亚洲午夜国产成人| 日韩av免费大片| 在线观看一区| 欧美午夜精彩| 久久99免费视频| 日韩午夜高潮| 久久婷婷av| 日韩影院二区| 国产精品xx| 不卡福利视频| 中文字幕人成乱码在线观看 | 日韩国产综合| 精品视频免费| 国产精品白浆| 国产精品欧美日韩一区| 亚洲ww精品| 亚洲2区在线| 亚洲精品少妇| 婷婷精品久久久久久久久久不卡| 99成人在线视频| 成人av二区| 免费不卡在线视频| 国产精品婷婷| 视频一区视频二区中文| 中文亚洲免费| 一区视频在线| 视频一区国产视频| 视频在线在亚洲| 亚洲一级大片| 久久精品国产精品亚洲毛片| 五月天综合网站| 国产精久久一区二区| 国产精品日本一区二区三区在线| 精品国产a一区二区三区v免费| 欧美影院三区| 精品国产一区二区三区噜噜噜| 91一区二区三区四区| 欧美一级一区| 午夜在线一区| 婷婷综合激情| 久久高清国产| 亚洲一区欧美激情| 偷拍亚洲精品| 精品国产欧美日韩| 国模精品一区| 国产成人黄色| 日韩中文欧美| 国产一区二区久久久久| 免费亚洲一区| 日韩精品一级| 国产三级一区| 麻豆91精品视频| 国产欧美在线|