接着極驗滑塊坐標識別(一)
在上一篇文章中我們采用了ajax斷點並沒有攔截到刷新驗證碼的代碼。
換一種思路,刷新驗證碼后會加載一個帶回調函數的js文件。
chrome的開發者工具中有強大的事件監聽斷點。
上面紅框圈起來的就是所有可以捕獲的監聽事件。
往下翻有一個Script。
勾選Script First Statement(第一次加載腳本斷下)。
再次刷新驗證碼。
中斷在了回調函數的腳本中,說明這個思路目前是可行的,按下F11進入回調函數。
發現進入了極驗的js文件當中,這個js文件被嚴重混淆,代碼變得十分難閱讀,跟蹤了一段時間后,發現距離核心代碼似乎有些遙遠,打算換一種思路,
有興趣的同學可以嘗試多跟蹤一下。。
在之前的分析中,我們可以發現,驗證碼是采用canvas元素進行顯示的,在事件監聽斷點中,剛好有一個canvas。
勾選這個Create canvas context(創建canvas對象時中斷)。
再次刷新驗證碼。
此刻斷下的位置應該就是解析驗證碼,繪制驗證碼的位置。
但是代碼嚴重混淆,十分難閱讀。
但是我們為了要搞清楚這段代碼的含義,就需要把混淆的代碼改寫成較為容易閱讀的代碼。
鼠標選中部分內容懸停在上面,就會顯示具體的值。
經過分析得知當前斷下的代碼是。
var t9s = canvas["getContext"]("2d");。
把混淆的代碼一步一步還原。
var t8k = c3M.N3M()[18][18][30]; while (t8k !== c3M.N3M()[6][25][16][14]) { switch (t8k) { case c3M.p3M()[1][20][5]: var t9s = canvas["getContext"]("2d"); t9s["drawImage"](L9s, 0, 0); var J9s = canvas["getContext"]("2d"); h9s["height"] = Z9s, h9s["width"] = 260; t8k = c3M.p3M()[28][25][5]; break; case c3M.p3M()[7][24][30]: var x5c = 5; L9s = L9s["j"], h9s = h9s["j"]; var Q9s = L9s["width"], Z9s = L9s["height"], c9s = document["createElement"]("canvas"); c9s["width"] = Q9s, c9s["height"] = Z9s; t8k = c3M.N3M()[13][23][5]; break; case c3M.p3M()[9][27][20]: B9s += 1; t8k = c3M.N3M()[4][18][30]; break; case c3M.p3M()[26][7][5]: var D9s = Z9s / 2, B9s = 0; t8k = c3M.N3M()[25][32][30]; break; case c3M.p3M()[0][34][25]: var w9s = L6[B9s] % 26 * 12 + 1, W9s = L6[B9s] > 25 ? D9s: 0, i9s = t9s["getImageData"](w9s, W9s, 10, D9s); J9s["putImageData"](i9s, B9s % 26 * 10, B9s > 25 ? D9s: 0); x5c = x5c > 40116 ? x5c - 3 : x5c + 3; t8k = c3M.N3M()[21][30][20]; break; case c3M.p3M()[21][31][30]: t8k = B9s < 52 && x5c * (x5c + 1) * x5c % 2 == 0 ? c3M.N3M()[24][5][25] : c3M.p3M()[31][5][25]; break; } }
變量名沒有修改,僅僅把字符串還原了,但是已經可以看懂函數大致含義。
可以確定,這里就是核心代碼了,getImageData獲取Image數據,putImageData寫入Image數據。
進行對坐標的修改,還原出原始的驗證碼圖片。
但是我們發現,這些代碼的順序似乎是亂的,經過我的跟蹤調試,猜測這里應該是一個for循環。
修正代碼位置如下。
var t8k = c3M.N3M()[18][18][30]; var x5c = 5; L9s = L9s["j"], h9s = h9s["j"]; var Q9s = L9s["width"], Z9s = L9s["height"], c9s = document["createElement"]("canvas"); c9s["width"] = Q9s, c9s["height"] = Z9s; //去掉了t8k = c3M.N3M()[13][23][5]; var t9s = canvas["getContext"]("2d"); t9s["drawImage"](L9s, 0, 0); var J9s = canvas["getContext"]("2d"); h9s["height"] = Z9s, h9s["width"] = 260; //去掉了t8k = c3M.p3M()[28][25][5]; for(var D9s = Z9s / 2, B9s = 0; B9s < 52 && x5c * (x5c + 1) * x5c % 2 == 0; B9s += 1) { var w9s = L6[B9s] % 26 * 12 + 1, W9s = L6[B9s] > 25 ? D9s: 0, i9s = t9s["getImageData"](w9s, W9s, 10, D9s); J9s["putImageData"](i9s, B9s % 26 * 10, B9s > 25 ? D9s: 0); x5c = x5c > 40116 ? x5c - 3 : x5c + 3; }
修正代碼以后,可以更加清晰的看出算法過程。
里面有一個L6變量,並沒有找到聲明的地方,但是通過調試輸出,這個變量是一個靜態的數組。
L6 = [39,38,48,49,41,40,46,47,35,34,50,51,33,32,28,29,27,26,36,37,31,30,44,45,43,42,12,13,23,22,14,15,21,20,8,9,25,24,6,7,3,2,0,1,11,10,4,5,19,18,16,17]。
這個數組就是驗證碼正確的位置。
例如L6[0]=39,應該就是驗證碼的第一塊內容對應的混淆后驗證碼的第39塊。
驗證碼還原的代碼就被我們分析完了,下面可以進行寫代碼測試。
代碼編寫部分請看極驗滑塊坐標識別(三)