转载自: https://juejin.cn/post/7386485874300977178
加速乐作为一种常见的反爬虫技术,在网络上已有大量详尽深入的教程可供参考。然而,对于那些初次接触的人来说,直接面对它可能仍会感到困惑。
本文仅用于学习交流,学习探讨逆向知识,欢迎私信共享学习心得。如有侵权,联系博主删除。请勿商用,否则后果自负。
加速乐采用了一系列的高级反爬虫技术,包括OB混淆、动态加密算法和多层Cookie获取,以确保整体校验的严密性。关键校验字段位于Cookie中的__jsl_clearance_s
。其验证过程通常涉及三次关键的请求:
-
首次请求:当用户首次尝试访问目标网站时,服务器会返回一个特殊的521状态码,其响应数据通过AAEncode技术进行混淆处理,以初步筛选访问者。
-
二次请求:紧接着的第二次请求中,如果服务器继续检测到可疑行为,它会再次返回521状态码,但这次响应数据将采用更为复杂的OB混淆,进一步验证访问者的身份。
-
三次请求:只有在前两次请求成功通过验证后,第三次请求才能成功访问网站,此时服务器将返回正常的状态码200,并提供用户所需的内容。
通过这一连串精心设计的步骤,加速乐确保了只有合法的访问者能够顺利获取网站数据,从而有效抵御恶意爬虫的侵扰,我们要做的就是模拟这些操作,获取想要的数据。
目标URL: aHR0cHM6Ly93d3cuY252ZC5vcmcuY24vZmxhdy90eXBlbGlzdD90eXBlSWQ9Mjc=
按照常规做法,我们首先进行网络抓包分析。
发送
:未携带 Cookie
响应
:状态码521
,Cookie 中的__jsluid_s
值和js
代码
发送
:Cookie 携带__jsluid_s
和__jsl_clearance_s
值
响应
:状态码521
,新的js
代码
发送
:Cookie 携带原始__jsluid_s
值,新的__jsl_clearance_s
值
响应
:状态码200
,正文内容
观察结果揭示了对同一页面共发起了三次HTTP
请求:前两次请求均遭遇了521
状态码的响应,而最后一次请求成功收到了200
状态码。这种模式正是加速乐反爬虫机制的显著特征。
浏览器上我们没能看到具体的响应,我们借助抓包工具试试,这里使用的Fiddler
。
同样,看到了三次请求的过程,并且向我们展示了具体的响应。
通过Fiddler
或使用python
模拟请求,得到下面这样一段JS代码:
1
|
document.cookie=('_')+('_')+('j')+('s')+('l')+('_')+('c')+('l')+('e')+('a')+('r')+('a')+('n')+('c')+('e')+('_')+('s')+('=')+(+!+[]+'')+(3+4+'')+(-~false+'')+(2+7+'')+(4+'')+(1+6+'')+(2+'')+((2<<1)+'')+((2)*[2]+'')+(([2]+0>>2)+'')+('.')+(-~1+'')+((2^1)+'')+((1+[2])/[2]+'')+('|')+('-')+((+true)+'')+('|')+('L')+('w')+('j')+(1+2+'')+('u')+('T')+('F')+('n')+(-~{}+'')+('j')+('j')+(~~''+'')+('E')+('t')+(~~false+'')+('g')+('I')+(-~1+'')+('J')+('g')+('i')+('K')+('m')+((1+[2])/[2]+'')+('N')+('f')+((1<<2)+'')+('%')+((1+[2]>>2)+'')+('D')+(';')+(' ')+('M')+('a')+('x')+('-')+('a')+('g')+('e')+('=')+(-~[2]+'')+(-~[5]+'')+((+false)+'')+(~~{}+'')+(';')+(' ')+('P')+('a')+('t')+('h')+('=')+('/')+(';')+(' ')+('S')+('a')+('m')+('e')+('S')+('i')+('t')+('e')+('=')+('N')+('o')+('n')+('e')+(';')+(' ')+('S')+('e')+('c')+('u')+('r')+('e');location.href=location.pathname+location.search
|
复制到浏览器执行下来看看:
得到了__jsl_clearance_s=1719472445.236|-1|Lwj3uTFn1jj0Et0gI2JgiKm6Nf4%3D; Max-age=3600; Path=/; SameSite=None; Secure
而__jsl_clearance_s
正是第二次请求需要带上的Cookie之一
真的老登。为了使代码难以阅读和分析,还进行了AAEncode
加密混淆。
使用第一个请求后得到的 Cookies 继续发起第二段请求得到新的 JS 代码:
代码被压缩了,不是很好看,使用在线 JS 美化(https://spidertools.cn/#/formatJS
)后:
以下js代码需要用base64解码还原
1
|
dmFyIF8weDRmOWQgPSBbJ0huSnUnLCAndzRKb3c1QWsnLCAnQ0NyRHE4S1gnLCAnS01PVlpNT1gnLCAnTUNERGp6Zz0nLCAndzU1M3c1UERwdz09JywgJ0NzT1hiY09YJywgJ3dvWENoTU9Bd3EwPScsICdKc09QWGNPKycsICd3cGxGdzZKWScsICdiWDhwd3BVPScsICd3NmZEamt6Q213PT0nLCAnd29CMHdyckRrZz09JywgJ3c2SENtTU9pWkE9PScsICdHUmJDa2x3PScsICdkdzAzS3c9PScsICd3NDdEcWNPN1RnPT0nLCAnRDhPUmZ3ST0nLCAnR3NPQ1NzT3QnLCAnVGpVZVB3PT0nLCAnd3BYQ25IUkonLCAndzR4Unc3YkRyUT09JywgJ1NjS2R3cUREdVE9PScsICdNMWhEd3JRPScsICd3b0xDdXNPaHdvcz0nLCAnZUZaQnc3MD0nLCAndzdYRG9jS3NkQT09JywgJ0NEZkRqa009JywgJ3c2Y3pXY0s4JywgJ1gxZ3F3cmM9JywgJ3dyL0RvRHZEaWc9PScsICdmbEhEdUFnPScsICdIQmJEak1LTCcsICdRRkxDcGNPaScsICdJOE9CY2NPTScsICd3NkFtdzRuQ2xRPT0nLCAnUEVIQ29EZz0nLCAndzVSWXdvckRyZz09JywgJ3c0Wi93cUhEblE9PScsICdPaWZEZ0RjPScsICdIV3hsd3BrPScsICdhWDdEblFVPScsICd3NzNEdGNPbndvUT0nLCAnWW1IQ25jT0QnLCAnV1h3NXdwMD0nLCAnUDFiQ29zS2wnLCAnd3B6Q2o4T3J3clE9JywgJ3c0UUd3Nm5Ec1E9PScsICdhOEtzd3J2RGt3PT0nLCAnQUN6RG1IMD0nLCAnd29uRGw4T3R3ck09JywgJ0pXVmJ3cTA9JywgJ1ozWWR3cFE9JywgJ0NHakNnc0t4JywgJ3c1TWFQTU8zJywgJ3c1c2dMTU9UJywgJ0lsUEN0WDQ9JywgJ3c2ckRsOE9VVUE9PScsICd3NFREa3NPRFd3PT0nLCAnd3FMRHVDTERsQT09JywgJ3c2TERrc09PVmc9PScsICdWeGN3d3AwPScsICd3NXJDdjhLY0t3PT0nLCAnY2NLU0NzSzcnLCAnYW01WHc1Yz0nLCAndzc4Snc2bkRwUT09JywgJ0tVUENxc0tRJywgJ3c1M0NqY0tIQUE9PScsICd3N0hDbmNLNE5BPT0nLCAnd3JuQ3Q4T1p3b1E9JywgJ3dwTWZ3cFhDalE9PScsICd3NUFJQnNPVCcsICd3NWZEczFqQ2p3PT0nLCAndzVSRHc3TXonLCAnd3J3a3dxYkNxZz09JywgJ3c0VjZ3clhEaHc9PScsICdHQ3JEdkE9PScsICd3cWZEa01PV3c0VT0nLCAnR3gzRGtzS28nLCAndzZjNmJjS0UnLCAnRXdERHV3az0nLCAnZWh2Q2gyMD0nLCAndzZ0VXc1VENrdz09JywgJ3c0dEh3Ni9EaGc9PScsICdHTUtadzdIRHNnPT0nLCAndzVNQ0FNTzMnLCAndzdoU3c2bkRnQT09JywgJ3c3VERsY09Md3FJPScsICd3NjAyYThLNicsICd3N3A5dzd3dScsICd3cmt1dzZ3NCcsICd3NnRKdzVQQ213PT0nLCAnZmxqRHBCcz0nLCAndzZERHE4S1lTZz09JywgJ0xHSEN2OEtkJywgJ2VuYkN0WFE9JywgJzZLMmk1ckdtNmFpYTZLNmMnLCAndzRnQ0FzTzcnLCAnUHNPcllnST0nLCAnY0RJck5BPT0nLCAndzdQQ2doRVUnLCAnd3JzVHc1WENsUT09JywgJ3dwUUt3NFlxJywgJ0RRRERpUkk9JywgJ3c2N0R0TU9td3JVPScsICdEbWpDaU1LaycsICdYY0tCd3BuRG93PT0nLCAnd3FrMEhNTzAnLCAndzRZN3c2WERzdz09JywgJ3dyakR0Q0REaEE9PScsICd3b0REb1F2RGdnPT0nLCAnd28wNndyakN2QT09JywgJ3c1SmV3b0hEaVE9PScsICdOa0xDcGNLNicsICd3ckxDdUhwaScsICdZSG82d3BvPScsICd3N3ZDb3NLK3c3Yz0nLCAndzROTXc1c3cnLCAnd3BZMXdvWENpUT09JywgJ3dxc013b1RDb0E9PScsICd3NWRNd3B6RHRRPT0nLCAndzRKMXc0dkNxdz09JywgJ3c0SENvTU9WVkE9PScsICd3N3pDbzhLd3c1MD0nLCAnd3AvQ21VUmMnLCAndzdkS3c3SVcnLCAndzdJYndxST0nLCAnd3JEQ2pNT1l3cXM9JywgJ2FsM0NpY09sJywgJ3c1TENvc09jUWc9PScsICdKOE9JWk1PUicsICd3NEhEc3NLamZRPT0nLCAndzVaSndvckRpQT09JywgJ3c0d0JhY0tkJywgJ0pCekRuQkE9JywgJ3dvaGF3NnpEZ2c9PScsICd3NlZBdzdvVCcsICd3NXpDcE1LZHc2Yz0nLCAnYUJVV1BnPT0nLCAndzV6RHNNT2ZWUT09JywgJ3c3ZHR3b2ZEalE9PScsICd3cnZEcGhyRG9BPT0nLCAnd3FZbndxcEMnLCAnT3p6RG55dz0nLCAndzdMQ25zSzd3cjQ9JywgJ3c3MHB3NzdEaUE9PScsICd3cTk4dzV4UScsICdBaDNDbDF3PScsICd3clo0dzczRGdRPT0nLCAnSXNPalg4T3UnLCAnZW5GTXc3bz0nLCAndzUzRHBjS1BZZz09JywgJ3c3Sjl3cTNEbFE9PScsICdFOE9NZjhPQycsICdhUjRod3BZPScsICdOVExEaVRBPScsICdCTU92YkNBPScsICdaMjBwd29FPScsICd3cFp4dzVCWScsICdZRmpEb1NBPScsICd3NDNEb3NPcGZ3PT0nLCAndzd4Snc0YzYnLCAnd3JqQ24xSjQnLCAnd3JQQ3MyMVInLCAndzVkZnc2ZkNtZz09JywgJ2JjS3d3b1hEanc9PScsICdCM0Zvd3BZPScsICdXV2RhdzVJPScsICd3cTE0dzRSZScsICdLRm5DdWNLZScsICd3Nk00ZmNLbScsICdkSDlwdzVBPScsICd3b0xEak1PaXc1Zz0nLCAnSjBiQ3VnPT0nLCAnRTE3Q3FNSzgnLCAndzRGV3c0ZkRodz09JywgJ0Z4RERoajA9JywgJ3c0dkRyOE9nd3FVPScsICd3NEpOd3JqRG9BPT0nLCAnd3FnUUFNT2onLCAndzZsM3dxbkRsdz09JywgJ3dvd2ZSY09pJywgJ0pUUENoRzQ9JywgJ3c1UERvc09yd3JvPScsICd3cUl3QnNPOCcsICdDU2JEckVnPScsICdlblFoJywgJ084S3dMc09YJywgJ3c0cFR3NC9Da3c9PScsICd3b3pEdThPWXc3OD0nLCAnQVNUQ2dHND0nLCAndzZzTE84T3onLCAndzd2Q3JTd3knLCAnRlZyQ3FNSzknLCAndzVSNHc0VEN0dz09JywgJ0lzT1BhY093JywgJ3c1SERoOE8wV0E9PScsICd3b1Vid3AvRGp3PT0nLCAnd3BJY3c1d1onLCAnQmNPeWJjT08nLCAnRThLVnc0RERtQT09JywgJ2NCUXB3cjA9JywgJ3dxekNoOE9sd3FVPScsICdWMkpNdzdJPScsICd3NUJqdzY0MycsICd3NmNpdzczQ2p3PT0nLCAnTE1PRmNzT0gnLCAnWE1LMndwZkRqdz09JywgJ2ZFakRuajA9JywgJ0FNT1pROE9JJywgJ013SERnY0tCJywgJ3c2Tnp3cG5EbkE9PScsICdMekhEZ2NLVycsICdJOE9hU3pFPScsICd3cUFEdzVEQ3BBPT0nLCAnd29mRG5zT2p3NzA9JywgJ3dxRENuRmhXJywgJ3c1ckRyTU9OWEE9PScsICd3NEZRdzVnOCcsICd3NHRUdzZMRG9nPT0nLCAndzZKRXc0ckRqZz09JywgJ3c0aGN3bzNEdFE9PScsICdRbWJDcE1PKycsICdReFlRd3FJPScsICdjRWRGdzcwPScsICdBSEhDZ01LcCcsICdKOE9QYXNPSScsICdQUWZEaXNLZycsICdVc0t3d3B6RHJnPT0nLCAnS0dqQ29rST0nLCAnY01LM3dwYkNrUT09JywgJ3dvcytNY09DJywgJ1FXRlB3NjA9JywgJ3c3ZkRqVjdDblE9PScsICd3NzdEazhLZVNRPT0nLCAnQzhPUVNNT2gnLCAndzZQQ3RUa04nLCAndzZNV1g4S1AnLCAnRXNPTVpNT00nLCAnQ0JyRHV6MD0nLCAndzd2Q2s4Szl3Nzg9JywgJ0s4T2Vkc09sJywgJ3c0akRzc09Rd3B3PScsICd3cXJDZ01PZXdvVT0nLCAnd29WUnc0VmcnLCAndzZnSnc0L0Rvdz09JywgJ05nWERvY0txJywgJ3dxakN1c09Ed3JvPSddOwooZnVuY3Rpb24oXzB4MTkxMjFjLCBfMHg0ZjlkZmQpIHsKCXZhciBfMHgyNDJlN2UgPSBmdW5jdGlvbihfMHgxMjM0ZjIpIHsKCQl3aGlsZSAoLS1fMHgxMjM0ZjIpIHsKCQkJXzB4MTkxMjFjWydwdXNoJ10oXzB4MTkxMjFjWydzaGlmdCddKCkpCgkJfQoJfTsKCV8weDI0MmU3ZSgrK18weDRmOWRmZCkKfShfMHg0ZjlkLCAweGNkKSk7CnZhciBfMHgyNDJlID0gZnVuY3Rpb24oXzB4MTkxMjFjLCBfMHg0ZjlkZmQpIHsKCV8weDE5MTIxYyA9IF8weDE5MTIxYyAtIDB4MDsKCXZhciBfMHgyNDJlN2UgPSBfMHg0ZjlkW18weDE5MTIxY107CglpZiAoXzB4MjQyZVsncFdoYWpmJ10gPT09IHVuZGVmaW5lZCkgewoJCShmdW5jdGlvbigpIHsKCQkJdmFyIF8weDM3NGUzNyA9IGZ1bmN0aW9uKCkgewoJCQkJdmFyIF8weGMyNGJiMTsKCQkJCXRyeSB7CgkJCQkJXzB4YzI0YmIxID0gRnVuY3Rpb24oJ3JldHVyblx4MjAoZnVuY3Rpb24oKVx4MjAnICsgJ3t9LmNvbnN0cnVjdG9yKFx4MjJyZXR1cm5ceDIwdGhpc1x4MjIpKFx4MjApJyArICcpOycpKCkKCQkJCX0gY2F0Y2ggKF8weDM1YmUxMykgewoJCQkJCV8weGMyNGJiMSA9IHdpbmRvdwoJCQkJfQoJCQkJcmV0dXJuIF8weGMyNGJiMQoJCQl9OwoJCQl2YXIgXzB4MmJmNTc2ID0gXzB4Mzc0ZTM3KCk7CgkJCXZhciBfMHgxMTEzMTcgPSAnQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODkrLz0nOwoJCQlfMHgyYmY1NzZbJ2F0b2InXSB8fCAoXzB4MmJmNTc2WydhdG9iJ10gPSBmdW5jdGlvbihfMHg1ZGRlMTMpIHsKCQkJCXZhciBfMHg1YzczOTkgPSBTdHJpbmcoXzB4NWRkZTEzKVsncmVwbGFjZSddKC89KyQvLCAnJyk7CgkJCQl2YXIgXzB4MzVmODM0ID0gJyc7CgkJCQlmb3IgKHZhciBfMHhlNjcyNDggPSAweDAsIF8weDE5OTZlMCwgXzB4MTY4MzQ5LCBfMHhhNDk0MjUgPSAweDA7IF8weDE2ODM0OSA9IF8weDVjNzM5OVsnY2hhckF0J10oXzB4YTQ5NDI1KyspOyB+XzB4MTY4MzQ5ICYmIChfMHgxOTk2ZTAgPSBfMHhlNjcyNDggJSAweDQgPyBfMHgxOTk2ZTAgKiAweDQwICsgXzB4MTY4MzQ5IDogXzB4MTY4MzQ5LCBfMHhlNjcyNDgrKyAlIDB4NCkgPyBfMHgzNWY4MzQgKz0gU3RyaW5nWydmcm9tQ2hhckNvZGUnXSgweGZmICYgXzB4MTk5NmUwID4+ICgtMHgyICogXzB4ZTY3MjQ4ICYgMHg2KSkgOiAweDApIHsKCQkJCQlfMHgxNjgzNDkgPSBfMHgxMTEzMTdbJ2luZGV4T2YnXShfMHgxNjgzNDkpCgkJCQl9CgkJCQlyZXR1cm4gXzB4MzVmODM0CgkJCX0pCgkJfSgpKTsKCQl2YXIgXzB4MTQzMzFkID0gZnVuY3Rpb24oXzB4MjZhNTA5LCBfMHg1ZjMzNDYpIHsKCQkJdmFyIF8weDE1ODc5MyA9IFtdLAoJCQkJXzB4MjA0OWU5ID0gMHgwLAoJCQkJXzB4MzRhMTNmLCBfMHhhYTc5ZWIgPSAnJywKCQkJCV8weDQ3YmIzNiA9ICcnOwoJCQlfMHgyNmE1MDkgPSBhdG9iKF8weDI2YTUwOSk7CgkJCWZvciAodmFyIF8weDNlMjA4ZCA9IDB4MCwgXzB4NTM4YzFjID0gXzB4MjZhNTA5WydsZW5ndGgnXTsgXzB4M2UyMDhkIDwgXzB4NTM4YzFjOyBfMHgzZTIwOGQrKykgewoJCQkJXzB4NDdiYjM2ICs9ICclJyArICgnMDAnICsgXzB4MjZhNTA5WydjaGFyQ29kZUF0J10oXzB4M2UyMDhkKVsndG9TdHJpbmcnXSgweDEwKSlbJ3NsaWNlJ10oLTB4MikKCQkJfQoJCQlfMHgyNmE1MDkgPSBkZWNvZGVVUklDb21wb25lbnQoXzB4NDdiYjM2KTsKCQkJdmFyIF8weDEyMDY1MzsKCQkJZm9yIChfMHgxMjA2NTMgPSAweDA7IF8weDEyMDY1MyA8IDB4MTAwOyBfMHgxMjA2NTMrKykgewoJCQkJXzB4MTU4NzkzW18weDEyMDY1M10gPSBfMHgxMjA2NTMKCQkJfQoJCQlmb3IgKF8weDEyMDY1MyA9IDB4MDsgXzB4MTIwNjUzIDwgMHgxMDA7IF8weDEyMDY1MysrKSB7CgkJCQlfMHgyMDQ5ZTkgPSAoXzB4MjA0OWU5ICsgXzB4MTU4NzkzW18weDEyMDY1M10gKyBfMHg1ZjMzNDZbJ2NoYXJDb2RlQXQnXShfMHgxMjA2NTMgJSBfMHg1ZjMzNDZbJ2xlbmd0aCddKSkgJSAweDEwMDsKCQkJCV8weDM0YTEzZiA9IF8weDE1ODc5M1tfMHgxMjA2NTNdOwoJCQkJXzB4MTU4NzkzW18weDEyMDY1M10gPSBfMHgxNTg3OTNbXzB4MjA0OWU5XTsKCQkJCV8weDE1ODc5M1tfMHgyMDQ5ZTldID0gXzB4MzRhMTNmCgkJCX0KCQkJXzB4MTIwNjUzID0gMHgwOwoJCQlfMHgyMDQ5ZTkgPSAweDA7CgkJCWZvciAodmFyIF8weDFlOTU0ZiA9IDB4MDsgXzB4MWU5NTRmIDwgXzB4MjZhNTA5WydsZW5ndGgnXTsgXzB4MWU5NTRmKyspIHsKCQkJCV8weDEyMDY1MyA9IChfMHgxMjA2NTMgKyAweDEpICUgMHgxMDA7CgkJCQlfMHgyMDQ5ZTkgPSAoXzB4MjA0OWU5ICsgXzB4MTU4NzkzW18weDEyMDY1M10pICUgMHgxMDA7CgkJCQlfMHgzNGExM2YgPSBfMHgxNTg3OTNbXzB4MTIwNjUzXTsKCQkJCV8weDE1ODc5M1tfMHgxMjA2NTNdID0gXzB4MTU4NzkzW18weDIwNDllOV07CgkJCQlfMHgxNTg3OTNbXzB4MjA0OWU5XSA9IF8weDM0YTEzZjsKCQkJCV8weGFhNzllYiArPSBTdHJpbmdbJ2Zyb21DaGFyQ29kZSddKF8weDI2YTUwOVsnY2hhckNvZGVBdCddKF8weDFlOTU0ZikgXiBfMHgxNTg3OTNbKF8weDE1ODc5M1tfMHgxMjA2NTNdICsgXzB4MTU4NzkzW18weDIwNDllOV0pICUgMHgxMDBdKQoJCQl9CgkJCXJldHVybiBfMHhhYTc5ZWIKCQl9OwoJCV8weDI0MmVbJ2x6WW1TcCddID0gXzB4MTQzMzFkOwoJCV8weDI0MmVbJ05PS1hVTiddID0ge307CgkJXzB4MjQyZVsncFdoYWpmJ10gPSAhIVtdCgl9Cgl2YXIgXzB4MTIzNGYyID0gXzB4MjQyZVsnTk9LWFVOJ11bXzB4MTkxMjFjXTsKCWlmIChfMHgxMjM0ZjIgPT09IHVuZGVmaW5lZCkgewoJCWlmIChfMHgyNDJlWydhQWROcWsnXSA9PT0gdW5kZWZpbmVkKSB7CgkJCV8weDI0MmVbJ2FBZE5xayddID0gISFbXQoJCX0KCQlfMHgyNDJlN2UgPSBfMHgyNDJlWydselltU3AnXShfMHgyNDJlN2UsIF8weDRmOWRmZCk7CgkJXzB4MjQyZVsnTk9LWFVOJ11bXzB4MTkxMjFjXSA9IF8weDI0MmU3ZQoJfSBlbHNlIHsKCQlfMHgyNDJlN2UgPSBfMHgxMjM0ZjIKCX0KCXJldHVybiBfMHgyNDJlN2UKfTsKCmZ1bmN0aW9uIGhhc2goXzB4OTA2MGVjKSB7Cgl2YXIgXzB4NTZkOTNlID0ge307CglfMHg1NmQ5M2VbXzB4MjQyZSgnMHg4OCcsICdbZHdFJykgKyAnQiddID0gZnVuY3Rpb24oXzB4NTZkMzFjLCBfMHg0Njg0YzIpIHsKCQlyZXR1cm4gXzB4NTZkMzFjIF4gXzB4NDY4NGMyCgl9OwoJXzB4NTZkOTNlW18weDI0MmUoJzB4OTgnLCAnS0xzYicpICsgJ0snXSA9IGZ1bmN0aW9uKF8weDVkMWNiNCwgXzB4NGZlYzk3KSB7CgkJcmV0dXJuIF8weDVkMWNiNCArIF8weDRmZWM5NwoJfTsKCV8weDU2ZDkzZVtfMHgyNDJlKCcweGM5JywgJ1JkVW4nKSArICdRJ10gPSBmdW5jdGlvbihfMHgyODMwZjUsIF8weDMxMTVlZSkgewoJCXJldHVybiBfMHgyODMwZjUgJiBfMHgzMTE1ZWUKCX07CglfMHg1NmQ5M2VbXzB4MjQyZSgnMHgxYScsICd3SlhyJykgKyAnQyddID0gXzB4MjQyZSgnMHgzNycsICc3TWVLJykgKyBfMHgyNDJlKCcweDZhJywgJ1dpTiEnKSArIF8weDI0MmUoJzB4NTknLCAnNDQhYycpICsgXzB4MjQyZSgnMHgzNScsICcya3p1Jyk7CglfMHg1NmQ5M2VbXzB4MjQyZSgnMHgyNycsICdSZFVuJykgKyAnRSddID0gZnVuY3Rpb24oXzB4MWM5ODk3LCBfMHg0NWQxNjQpIHsKCQlyZXR1cm4gXzB4MWM5ODk3ID49IF8weDQ1ZDE2NAoJfTsKCV8weDU2ZDkzZVtfMHgyNDJlKCcweGI3JywgJ2p6KDgnKSArICdUJ10gPSBmdW5jdGlvbihfMHg0MjFmMDYsIF8weGQ1NWRkMikgewoJCXJldHVybiBfMHg0MjFmMDYgJiBfMHhkNTVkZDIKCX07CglfMHg1NmQ5M2VbXzB4MjQyZSgnMHg2ZScsICdES3h4JykgKyAndSddID0gZnVuY3Rpb24oXzB4NWYxNGUzLCBfMHhhYTFjZTApIHsKCQlyZXR1cm4gXzB4NWYxNGUzID4+IF8weGFhMWNlMAoJfTsKCV8weDU2ZDkzZVtfMHgyNDJlKCcweDVmJywgJzJrenUnKSArICdXJ10gPSBmdW5jdGlvbihfMHgxZWU0NGEsIF8weDM1NzgzZikgewoJCXJldHVybiBfMHgxZWU0NGEgKiBfMHgzNTc4M2YKCX07CglfMHg1NmQ5M2VbXzB4MjQyZSgnMHgzNCcsICdSZFVuJykgKyAnYSddID0gZnVuY3Rpb24oXzB4NDZiN2YxLCBfMHg0YTIwZTUpIHsKCQlyZXR1cm4gXzB4NDZiN2YxIDwgXzB4NGEyMGU1Cgl9OwoJXzB4NTZkOTNlW18weDI0MmUoJzB4NzMnLCAnW3FWZycpICsgJ2gnXSA9IGZ1bmN0aW9uKF8weDE0ZGNkMiwgXzB4NGQ5ZDRkKSB7CgkJcmV0dXJuIF8weDE0ZGNkMiAhPT0gXzB4NGQ5ZDRkCgl9OwoJXzB4NTZkOTNlW18weDI0MmUoJzB4N2EnLCAnWW4jbycpICsgJ2QnXSA9IF8weDI0MmUoJzB4NjUnLCAnMzl3UicpICsgJ28nOwoJXzB4NTZkOTNlW18weDI0MmUoJzB4Y2EnLCAncnpAYicpICsgJ2cnXSA9IF8weDI0MmUoJzB4MmEnLCAnQWRkRCcpICsgJ0snOwoJXzB4NTZkOTNlW18weDI0MmUoJzB4Y2YnLCAnIU4lMCcpICsgJ2onXSA9IGZ1bmN0aW9uKF8weDQ4NjA1ZCwgXzB4MTg5OGQzKSB7CgkJcmV0dXJuIF8weDQ4NjA1ZCAtIF8weDE4OThkMwoJfTsKCV8weDU2ZDkzZVtfMHgyNDJlKCcweGE0JywgJyFOJTAnKSArICdGJ10gPSBmdW5jdGlvbihfMHg0ZjA5ZTYsIF8weDM3NWZiNikgewoJCXJldHVybiBfMHg0ZjA5ZTYgLSBfMHgzNzVmYjYKCX07CglfMHg1NmQ5M2VbXzB4MjQyZSgnMHhjNicsICdlVzhCJykgKyAnbyddID0gZnVuY3Rpb24oXzB4MzRlYjkzLCBfMHgzNzVmMDQpIHsKCQlyZXR1cm4gXzB4MzRlYjkzICogXzB4Mzc1ZjA0Cgl9OwoJXzB4NTZkOTNlW18weDI0MmUoJzB4MzYnLCAnW3FWZycpICsgJ2MnXSA9IGZ1bmN0aW9uKF8weGMyNTVlNCwgXzB4MjE4OTgxKSB7CgkJcmV0dXJuIF8weGMyNTVlNCAqIF8weDIxODk4MQoJfTsKCV8weDU2ZDkzZVtfMHgyNDJlKCcweGU4JywgJ0heKEgnKSArICdxJ10gPSBmdW5jdGlvbihfMHg5ZDI2ZTAsIF8weDJkNjY3NCkgewoJCXJldHVybiBfMHg5ZDI2ZTAgfCBfMHgyZDY2NzQKCX07CglfMHg1NmQ5M2VbXzB4MjQyZSgnMHhkJywgJ2hUJiMnKSArICdFJ10gPSBmdW5jdGlvbihfMHg0Y2JkMDEsIF8weDljMGJjZSkgewoJCXJldHVybiBfMHg0Y2JkMDEgPDwgXzB4OWMwYmNlCgl9OwoJXzB4NTZkOTNlW18weDI0MmUoJzB4NzUnLCAnKVhZTicpICsgJ3gnXSA9IGZ1bmN0aW9uKF8weDNjYTg2MCwgXzB4NWVlNzY4KSB7CgkJcmV0dXJuIF8weDNjYTg2MCB8IF8weDVlZTc2OAoJfTsKCV8weDU2ZDkzZVtfMHgyNDJlKCcweDUzJywgJzFQaVQnKSArICdHJ10gPSBmdW5jdGlvbihfMHg0YjA1MDcsIF8weDNmOWFkYikgewoJCXJldHVybiBfMHg0YjA1MDcgJiBfMHgzZjlhZGIKCX07CglfMHg1NmQ5M2VbXzB4MjQyZSgnMHgxNicsICdQcClSJykgKyAnayddID0gZnVuY3Rpb24oXzB4M2M4YjFlLCBfMHg0ZmJlYWYpIHsKCQlyZXR1cm4gXzB4M2M4YjFlICYgXzB4NGZiZWFmCgl9OwoJXzB4NTZkOTNlW18weDI0MmUoJzB4NzInLCAnajYkZScpICsgJ2wnXSA9IGZ1bmN0aW9uKF8weDNlYzFjNywgXzB4MzNkYzU0KSB7CgkJcmV0dXJuIF8weDNlYzFjNyBeIF8weDMzZGM1NAoJfTsKCV8weDU2ZDkzZVtfMHgyNDJlKCcweGFiJywgJ3FYdzcnKSArICdqJ10gPSBmdW5jdGlvbihfMHgxMDg5ZjgsIF8weDVjODdkNykgewoJCXJldHVybiBfMHgxMDg5ZjggPCBfMHg1Yzg3ZDcKCX07CglfMHg1NmQ5M2VbXzB4MjQyZSgnMHhjZCcsICddakRyJykgKyAnQyddID0gXzB4MjQyZSgnMHg0ZicsICdyekBiJykgKyBfMHgyNDJlKCcweGJiJywgJ0FkZEQnKSArIF8weDI0MmUoJzB4ZTAnLCAnajYkZScpICsgJzUnOwoJXzB4NTZkOTNlW18weDI0MmUoJzB4YjMnLCAnaFQmIycpICsgJ2QnXSA9IGZ1bmN0aW9uKF8weDVkN2I5MCwgXzB4NWE0MjVjKSB7CgkJcmV0dXJuIF8weDVkN2I5MCArIF8weDVhNDI1YwoJfTsKCV8weDU2ZDkzZVtfMHgyNDJlKCcweDk1JywgJ1ZTV3AnKSArICdQJ10gPSBmdW5jdGlvbihfMHg0ZWNiYjEsIF8weDUzNDEwYSkgewoJCXJldHVybiBfMHg0ZWNiYjEgLSBfMHg1MzQxMGEKCX07CglfMHg1NmQ5M2VbXzB4MjQyZSgnMHg3MScsICcpWFlOJykgKyAnTiddID0gZnVuY3Rpb24oXzB4NTJhYWZhLCBfMHgyOWRkYWEsIF8weDI3NTIyYSkgewoJCXJldHVybiBfMHg1MmFhZmEoXzB4MjlkZGFhLCBfMHgyNzUyMmEpCgl9OwoJXzB4NTZkOTNlW18weDI0MmUoJzB4ZGEnLCAnUFMqdCcpICsgJ2snXSA9IGZ1bmN0aW9uKF8weDc4MDlkMCwgXzB4NTQ3MGU3LCBfMHgzMzEyZjAsIF8weDRhMGZmMiwgXzB4MzRlMWI5KSB7CgkJcmV0dXJuIF8weDc4MDlkMChfMHg1NDcwZTcsIF8weDMzMTJmMCwgXzB4NGEwZmYyLCBfMHgzNGUxYjkpCgl9OwoJXzB4NTZkOTNlW18weDI0MmUoJzB4MCcsICc3TWVLJykgKyAnbCddID0gZnVuY3Rpb24oXzB4NThmODNiLCBfMHg1MDAwNTAsIF8weDFhM2RmNSkgewoJCXJldHVybiBfMHg1OGY4M2IoXzB4NTAwMDUwLCBfMHgxYTNkZjUpCgl9OwoJXzB4NTZkOTNlW18weDI0MmUoJzB4YmMnLCAnM1F3QScpICsgJ0MnXSA9IGZ1bmN0aW9uKF8weDIzNzU0NywgXzB4NDgwOGQ0KSB7CgkJcmV0dXJuIF8weDIzNzU0NyhfMHg0ODA4ZDQpCgl9OwoJXzB4NTZkOTNlW18weDI0MmUoJzB4MzEnLCAnYUhQMicpICsgJ0snXSA9IGZ1bmN0aW9uKF8weDMxYzIwYiwgXzB4M2YwMzhiKSB7CgkJcmV0dXJuIF8weDMxYzIwYiArIF8weDNmMDM4YgoJfTsKCV8weDU2ZDkzZVtfMHgyNDJlKCcweGE4JywgJ2hUJiMnKSArICdtJ10gPSBmdW5jdGlvbihfMHgzNGI1MGUsIF8weDFmOWMwNykgewoJCXJldHVybiBfMHgzNGI1MGUgKyBfMHgxZjljMDcKCX07CglfMHg1NmQ5M2VbXzB4MjQyZSgnMHhkYicsICdlVzhCJykgKyAnYSddID0gZnVuY3Rpb24oXzB4ZTQwMDhjLCBfMHg1MmFiMGYpIHsKCQlyZXR1cm4gXzB4ZTQwMDhjICsgXzB4NTJhYjBmCgl9OwoJXzB4NTZkOTNlW18weDI0MmUoJzB4OScsICdNREdNJykgKyAnTyddID0gZnVuY3Rpb24oXzB4MWFjMjVlLCBfMHg1OGZkOTkpIHsKCQlyZXR1cm4gXzB4MWFjMjVlKF8weDU4ZmQ5OSkKCX07CglfMHg1NmQ5M2VbXzB4MjQyZSgnMHgyNScsICc0NCFjJykgKyAndCddID0gZnVuY3Rpb24oXzB4MThkNmQ2LCBfMHhlZjQxZTQpIHsKCQlyZXR1cm4gXzB4MThkNmQ2KF8weGVmNDFlNCkKCX07Cgl2YXIgXzB4NWFhMzg4ID0gXzB4NTZkOTNlOwoKCWZ1bmN0aW9uIF8weDRmMjEwNShfMHg1NDhlMTEsIF8weGQ2ZjdlZSkgewoJCXJldHVybiBfMHg1YWEzODhbXzB4MjQyZSgnMHhkOScsICdpISljJykgKyAnQiddKF8weDVhYTM4OFtfMHgyNDJlKCcweDYxJywgJ2o2JGUnKSArICdLJ10oXzB4NTQ4ZTExICYgMHg3ZmZmZmZmZiwgXzB4NWFhMzg4W18weDI0MmUoJzB4YzQnLCAncl43aCcpICsgJ1EnXShfMHhkNmY3ZWUsIDB4N2ZmZmZmZmYpKSwgXzB4NTQ4ZTExICYgMHg4MDAwMDAwMCkgXiBfMHhkNmY3ZWUgJiAweDgwMDAwMDAwCgl9CgoJZnVuY3Rpb24gXzB4NDdiZjM5KF8weDFmMmRjYSkgewoJCXZhciBfMHgzYmU3YzYgPSBfMHg1YWEzODhbXzB4MjQyZSgnMHg3OCcsICdIXihIJykgKyAnQyddOwoJCXZhciBfMHg0MDNjZDIgPSAnJzsKCQlmb3IgKHZhciBfMHg0OWQ5YmIgPSAweDc7IF8weDVhYTM4OFtfMHgyNDJlKCcweDlkJywgJ11qRHInKSArICdFJ10oXzB4NDlkOWJiLCAweDApOyBfMHg0OWQ5YmItLSkgewoJCQlfMHg0MDNjZDIgKz0gXzB4M2JlN2M2W18weDI0MmUoJzB4M2YnLCAnXWpEcicpICsgJ0F0J10oXzB4NWFhMzg4W18weDI0MmUoJzB4OGQnLCAnNDExXicpICsgJ1QnXShfMHgxZjJkY2EgPj4gXzB4NDlkOWJiICogMHg0LCAweGYpKQoJCX0KCQlyZXR1cm4gXzB4NDAzY2QyCgl9CgoJZnVuY3Rpb24gXzB4Mzc0NjkxKF8weDM0MzFmNCkgewoJCXZhciBfMHgyMjc3ZmIgPSBfMHg1YWEzODhbXzB4MjQyZSgnMHgyNCcsICdXaU4hJykgKyAnSyddKF8weDVhYTM4OFtfMHgyNDJlKCcweDg5JywgJ2khKWMnKSArICd1J10oXzB4MzQzMWY0W18weDI0MmUoJzB4ZjUnLCAnQWRkRCcpICsgJ3RoJ10gKyAweDgsIDB4NiksIDB4MSksCgkJCV8weDRjMGUyZiA9IG5ldyBBcnJheShfMHg1YWEzODhbXzB4MjQyZSgnMHg0OScsICdLTHNiJykgKyAnVyddKF8weDIyNzdmYiwgMHgxMCkpOwoJCWZvciAodmFyIF8weDMwYWY5NyA9IDB4MDsgXzB4NWFhMzg4W18weDI0MmUoJzB4NDInLCAnMVBpVCcpICsgJ2EnXShfMHgzMGFmOTcsIF8weDVhYTM4OFtfMHgyNDJlKCcweGNjJywgJ2hUJiMnKSArICdXJ10oXzB4MjI3N2ZiLCAweDEwKSk7IF8weDMwYWY5NysrKSB7CgkJCWlmIChfMHg1YWEzODhbXzB4MjQyZSgnMHg2YycsICczUXdBJykgKyAnaCddKF8weDVhYTM4OFtfMHgyNDJlKCcweDYnLCAnanooOCcpICsgJ2QnXSwgXzB4NWFhMzg4W18weDI0MmUoJzB4MScsICdyXjdoJykgKyAnZyddKSkgewoJCQkJXzB4NGMwZTJmW18weDMwYWY5N10gPSAweDAKCQkJfSBlbHNlIHsKCQkJCXJldHVybgoJCQl9CgkJfQoJCWZvciAoXzB4MzBhZjk3ID0gMHgwOyBfMHgzMGFmOTcgPCBfMHgzNDMxZjRbXzB4MjQyZSgnMHhmNScsICdBZGREJykgKyAndGgnXTsgXzB4MzBhZjk3KyspIHsKCQkJXzB4NGMwZTJmW18weDMwYWY5NyA+PiAweDJdIHw9IF8weDM0MzFmNFtfMHgyNDJlKCcweDMzJywgJ1dpTiEnKSArIF8weDI0MmUoJzB4MicsICdWU1dwJykgKyAnQXQnXShfMHgzMGFmOTcpIDw8IF8weDVhYTM4OFtfMHgyNDJlKCcweDhlJywgJzQzczInKSArICdqJ10oMHgxOCwgKF8weDMwYWY5NyAmIDB4MykgKiAweDgpCgkJfQoJCV8weDRjMGUyZltfMHg1YWEzODhbXzB4MjQyZSgnMHgxOCcsICcpclZHJykgKyAndSddKF8weDMwYWY5NywgMHgyKV0gfD0gMHg4MCA8PCBfMHg1YWEzODhbXzB4MjQyZSgnMHhlZScsICdhSFAyJykgKyAnRiddKDB4MTgsIF8weDVhYTM4OFtfMHgyNDJlKCcweGE3JywgJ11qRHInKSArICdXJ10oXzB4MzBhZjk3ICYgMHgzLCAweDgpKTsKCQlfMHg0YzBlMmZbXzB4NWFhMzg4W18weDI0MmUoJzB4ODMnLCAnWW4jbycpICsgJ28nXShfMHgyMjc3ZmIsIDB4MTApIC0gMHgxXSA9IF8weDVhYTM4OFtfMHgyNDJlKCcweDkxJywgJ25SQmonKSArICdjJ10oXzB4MzQzMWY0W18weDI0MmUoJzB4OTYnLCAnd0pYcicpICsgJ3RoJ10sIDB4OCk7CgkJcmV0dXJuIF8weDRjMGUyZgoJfQoKCWZ1bmN0aW9uIF8weDRiM2Y5MShfMHg1YjkwMjYsIF8weDNhZDM3YSkgewoJCXJldHVybiBfMHg1YWEzODhbXzB4MjQyZSgnMHg4ZicsICc1NUZwJykgKyAncSddKF8weDVhYTM4OFtfMHgyNDJlKCcweGVmJywgJzM5d1InKSArICdFJ10oXzB4NWI5MDI2LCBfMHgzYWQzN2EpLCBfMHg1YjkwMjYgPj4+IDB4MjAgLSBfMHgzYWQzN2EpCgl9CgoJZnVuY3Rpb24gXzB4MWE1MWZlKF8weDE0NjAwNSwgXzB4MjA4ZWFiLCBfMHgzN2ViY2UsIF8weDIzMDBlYikgewoJCWlmIChfMHgxNDYwMDUgPCAweDE0KSByZXR1cm4gXzB4NWFhMzg4W18weDI0MmUoJzB4ZDYnLCAnUEExbicpICsgJ3gnXShfMHg1YWEzODhbXzB4MjQyZSgnMHg3ZicsICdEN0llJykgKyAnVCddKF8weDIwOGVhYiwgXzB4MzdlYmNlKSwgXzB4NWFhMzg4W18weDI0MmUoJzB4ZWQnLCAnIU4lMCcpICsgJ1QnXSh+XzB4MjA4ZWFiLCBfMHgyMzAwZWIpKTsKCQlpZiAoXzB4NWFhMzg4W18weDI0MmUoJzB4ZjMnLCAnRDdJZScpICsgJ2EnXShfMHgxNDYwMDUsIDB4MjgpKSByZXR1cm4gXzB4NWFhMzg4W18weDI0MmUoJzB4MjEnLCAncl43aCcpICsgJ0InXShfMHgyMDhlYWIgXiBfMHgzN2ViY2UsIF8weDIzMDBlYik7CgkJaWYgKF8weDVhYTM4OFtfMHgyNDJlKCcweGFjJywgJ3lMNXAnKSArICdhJ10oXzB4MTQ2MDA1LCAweDNjKSkgcmV0dXJuIF8weDVhYTM4OFtfMHgyNDJlKCcweDI5JywgJ1BwKVInKSArICd4J10oXzB4MjA4ZWFiICYgXzB4MzdlYmNlIHwgXzB4NWFhMzg4W18weDI0MmUoJzB4NGEnLCAncnpAYicpICsgJ0cnXShfMHgyMDhlYWIsIF8weDIzMDBlYiksIF8weDVhYTM4OFtfMHgyNDJlKCcweDE3JywgJ1ZTV3AnKSArICdrJ10oXzB4MzdlYmNlLCBfMHgyMzAwZWIpKTsKCQlyZXR1cm4gXzB4NWFhMzg4W18weDI0MmUoJzB4OTknLCAnS0xzYicpICsgJ0InXShfMHg1YWEzODhbXzB4MjQyZSgnMHhkNCcsICdpISljJykgKyAnbCddKF8weDIwOGVhYiwgXzB4MzdlYmNlKSwgXzB4MjMwMGViKQoJfQoKCWZ1bmN0aW9uIF8weDU2NTdhNihfMHgyYjA3NmEpIHsKCQlyZXR1cm4gXzB4MmIwNzZhIDwgMHgxNCA/IDB4NWE4Mjc5OTkgOiBfMHgyYjA3NmEgPCAweDI4ID8gMHg2ZWQ5ZWJhMSA6IF8weDVhYTM4OFtfMHgyNDJlKCcweDNiJywgJzM5d1InKSArICdqJ10oXzB4MmIwNzZhLCAweDNjKSA/IC0weDcwZTQ0MzI0IDogLTB4MzU5ZDNlMmEKCX0KCXZhciBfMHg0MzNkNzcgPSBfMHgzNzQ2OTEoXzB4OTA2MGVjKTsKCXZhciBfMHgxNTIwZjMgPSBuZXcgQXJyYXkoMHg1MCk7Cgl2YXIgXzB4MjM2NTU2ID0gMHg2NzQ1MjMwMTsKCXZhciBfMHgxMjZiY2EgPSAtMHgxMDMyNTQ3NzsKCXZhciBfMHgzY2EwOGMgPSAtMHg2NzQ1MjMwMjsKCXZhciBfMHgxYWQ3NDUgPSAweDEwMzI1NDc2OwoJdmFyIF8weDNkNGFiMSA9IC0weDNjMmQxZTEwOwoJZm9yICh2YXIgXzB4NTJlNGYwID0gMHgwOyBfMHg1MmU0ZjAgPCBfMHg0MzNkNzdbXzB4MjQyZSgnMHhmNScsICdBZGREJykgKyAndGgnXTsgXzB4NTJlNGYwICs9IDB4MTApIHsKCQl2YXIgXzB4NWQ2NDgyID0gXzB4MjM2NTU2OwoJCXZhciBfMHgxYmRiYTMgPSBfMHgxMjZiY2E7CgkJdmFyIF8weDI1NjY1NSA9IF8weDNjYTA4YzsKCQl2YXIgXzB4YWY5NDY1ID0gXzB4MWFkNzQ1OwoJCXZhciBfMHgzNWFiZjUgPSBfMHgzZDRhYjE7CgkJZm9yICh2YXIgXzB4NTc2NjVmID0gMHgwOyBfMHg1YWEzODhbXzB4MjQyZSgnMHhhNScsICd5TDVwJykgKyAnaiddKF8weDU3NjY1ZiwgMHg1MCk7IF8weDU3NjY1ZisrKSB7CgkJCXZhciBfMHgyODY2NzIgPSBfMHg1YWEzODhbXzB4MjQyZSgnMHhjZCcsICddakRyJykgKyAnQyddW18weDI0MmUoJzB4OWMnLCAnaSEpYycpICsgJ3QnXSgnfCcpOwoJCQl2YXIgXzB4NWE3ZGNjID0gMHgwOwoJCQl3aGlsZSAoISFbXSkgewoJCQkJc3dpdGNoIChfMHgyODY2NzJbXzB4NWE3ZGNjKytdKSB7CgkJCQkJY2FzZSAnMCc6CgkJCQkJCV8weDFhZDc0NSA9IF8weDNjYTA4YzsKCQkJCQkJY29udGludWU7CgkJCQkJY2FzZSAnMSc6CgkJCQkJCV8weDNjYTA4YyA9IF8weDRiM2Y5MShfMHgxMjZiY2EsIDB4MWUpOwoJCQkJCQljb250aW51ZTsKCQkJCQljYXNlICcyJzoKCQkJCQkJXzB4M2Q0YWIxID0gXzB4MWFkNzQ1OwoJCQkJCQljb250aW51ZTsKCQkJCQljYXNlICczJzoKCQkJCQkJXzB4MTI2YmNhID0gXzB4MjM2NTU2OwoJCQkJCQljb250aW51ZTsKCQkJCQljYXNlICc0JzoKCQkJCQkJaWYgKF8weDVhYTM4OFtfMHgyNDJlKCcweDk0JywgJ2khKWMnKSArICdqJ10oXzB4NTc2NjVmLCAweDEwKSkgewoJCQkJCQkJXzB4MTUyMGYzW18weDU3NjY1Zl0gPSBfMHg0MzNkNzdbXzB4NWFhMzg4W18weDI0MmUoJzB4ZjQnLCAnMFE1dScpICsgJ2QnXShfMHg1MmU0ZjAsIF8weDU3NjY1ZildCgkJCQkJCX0gZWxzZSB7CgkJCQkJCQlfMHgxNTIwZjNbXzB4NTc2NjVmXSA9IF8weDRiM2Y5MShfMHg1YWEzODhbXzB4MjQyZSgnMHhiOCcsICdLTHNiJykgKyAnbCddKF8weDVhYTM4OFtfMHgyNDJlKCcweGViJywgJzU1RnAnKSArICdsJ10oXzB4MTUyMGYzW18weDVhYTM4OFtfMHgyNDJlKCcweDQzJywgJ0FkZEQnKSArICdQJ10oXzB4NTc2NjVmLCAweDMpXSwgXzB4MTUyMGYzW18weDU3NjY1ZiAtIDB4OF0pLCBfMHgxNTIwZjNbXzB4NTc2NjVmIC0gMHhlXSkgXiBfMHgxNTIwZjNbXzB4NTc2NjVmIC0gMHgxMF0sIDB4MSkKCQkJCQkJfQoJCQkJCQljb250aW51ZTsKCQkJCQljYXNlICc1JzoKCQkJCQkJXzB4MjM2NTU2ID0gdDsKCQkJCQkJY29udGludWU7CgkJCQkJY2FzZSAnNic6CgkJCQkJCXQgPSBfMHg1YWEzODhbXzB4MjQyZSgnMHhjNycsICc0MTFeJykgKyAnTiddKF8weDRmMjEwNSwgXzB4NGYyMTA1KF8weDRiM2Y5MShfMHgyMzY1NTYsIDB4NSksIF8weDVhYTM4OFtfMHgyNDJlKCcweGRkJywgJ2p6KDgnKSArICdrJ10oXzB4MWE1MWZlLCBfMHg1NzY2NWYsIF8weDEyNmJjYSwgXzB4M2NhMDhjLCBfMHgxYWQ3NDUpKSwgXzB4NWFhMzg4W18weDI0MmUoJzB4MCcsICc3TWVLJykgKyAnbCddKF8weDRmMjEwNSwgXzB4NGYyMTA1KF8weDNkNGFiMSwgXzB4MTUyMGYzW18weDU3NjY1Zl0pLCBfMHg1YWEzODhbXzB4MjQyZSgnMHg2YicsICdQQTFuJykgKyAnQyddKF8weDU2NTdhNiwgXzB4NTc2NjVmKSkpOwoJCQkJCQljb250aW51ZQoJCQkJfQoJCQkJYnJlYWsKCQkJfQoJCX0KCQlfMHgyMzY1NTYgPSBfMHg0ZjIxMDUoXzB4MjM2NTU2LCBfMHg1ZDY0ODIpOwoJCV8weDEyNmJjYSA9IF8weDVhYTM4OFtfMHgyNDJlKCcweDY4JywgJzBRNXUnKSArICdsJ10oXzB4NGYyMTA1LCBfMHgxMjZiY2EsIF8weDFiZGJhMyk7CgkJXzB4M2NhMDhjID0gXzB4NWFhMzg4W18weDI0MmUoJzB4NTcnLCAnMmt6dScpICsgJ2wnXShfMHg0ZjIxMDUsIF8weDNjYTA4YywgXzB4MjU2NjU1KTsKCQlfMHgxYWQ3NDUgPSBfMHg0ZjIxMDUoXzB4MWFkNzQ1LCBfMHhhZjk0NjUpOwoJCV8weDNkNGFiMSA9IF8weDRmMjEwNShfMHgzZDRhYjEsIF8weDM1YWJmNSkKCX0KCXJldHVybiBfMHg1YWEzODhbXzB4MjQyZSgnMHhhNicsICdUeWN6JykgKyAnZCddKF8weDVhYTM4OFtfMHgyNDJlKCcweGRlJywgJ3dKWHInKSArICdLJ10oXzB4NWFhMzg4W18weDI0MmUoJzB4M2MnLCAnNDExXicpICsgJ20nXShfMHg1YWEzODhbXzB4MjQyZSgnMHg2NCcsICczOXdSJykgKyAnYSddKF8weDQ3YmYzOShfMHgyMzY1NTYpLCBfMHg0N2JmMzkoXzB4MTI2YmNhKSksIF8weDVhYTM4OFtfMHgyNDJlKCcweDUyJywgJ2VXOEInKSArICdPJ10oXzB4NDdiZjM5LCBfMHgzY2EwOGMpKSwgXzB4NWFhMzg4W18weDI0MmUoJzB4MTMnLCAnUEExbicpICsgJ08nXShfMHg0N2JmMzksIF8weDFhZDc0NSkpLCBfMHg1YWEzODhbXzB4MjQyZSgnMHgyNScsICc0NCFjJykgKyAndCddKF8weDQ3YmYzOSwgXzB4M2Q0YWIxKSkKfQoKZnVuY3Rpb24gZ28oXzB4MTg0MDU0KSB7Cgl2YXIgXzB4MzFmMDc5ID0ge307CglfMHgzMWYwNzlbXzB4MjQyZSgnMHgxZCcsICdbZHdFJykgKyAnUCddID0gZnVuY3Rpb24oXzB4NDUyYWM3LCBfMHgyYzMxZGYpIHsKCQlyZXR1cm4gXzB4NDUyYWM3ICYgXzB4MmMzMWRmCgl9OwoJXzB4MzFmMDc5W18weDI0MmUoJzB4YWUnLCAnW2R3RScpICsgJ0UnXSA9IF8weDI0MmUoJzB4ZWMnLCAnaSEpYycpICsgXzB4MjQyZSgnMHhlNScsICcya3p1Jyk7CglfMHgzMWYwNzlbXzB4MjQyZSgnMHg2ZicsICdES3h4JykgKyAnWCddID0gXzB4MjQyZSgnMHhiZScsICdHeSFFJykgKyAndCc7CglfMHgzMWYwNzlbXzB4MjQyZSgnMHgyZCcsICdQcClSJykgKyAnWCddID0gZnVuY3Rpb24oXzB4MWU3NzE1LCBfMHg0MmY5NGQpIHsKCQlyZXR1cm4gXzB4MWU3NzE1ICE9IF8weDQyZjk0ZAoJfTsKCV8weDMxZjA3OVtfMHgyNDJlKCcweDM5JywgJ0d5IUUnKSArICdwJ10gPSBmdW5jdGlvbihfMHg1MjM3YzQsIF8weDM0NDkwZCkgewoJCXJldHVybiBfMHg1MjM3YzQgPCBfMHgzNDQ5MGQKCX07CglfMHgzMWYwNzlbXzB4MjQyZSgnMHhlMicsICc0NCFjJykgKyAnYyddID0gZnVuY3Rpb24oXzB4NGRlNTY5LCBfMHg1ZTE2NzYpIHsKCQlyZXR1cm4gXzB4NGRlNTY5ICsgXzB4NWUxNjc2Cgl9OwoJXzB4MzFmMDc5W18weDI0MmUoJzB4OCcsICc0MTFeJykgKyAnQiddID0gZnVuY3Rpb24oXzB4NWM5ZGRmLCBfMHgzYmU5MjcpIHsKCQlyZXR1cm4gXzB4NWM5ZGRmID09IF8weDNiZTkyNwoJfTsKCV8weDMxZjA3OVtfMHgyNDJlKCcweGEwJywgJ2hUJiMnKSArICdhJ10gPSBmdW5jdGlvbihfMHgyNjQ0YzEsIF8weDJjOTI4OCkgewoJCXJldHVybiBfMHgyNjQ0YzEoXzB4MmM5Mjg4KQoJfTsKCV8weDMxZjA3OVtfMHgyNDJlKCcweDQ1JywgJ1tkd0UnKSArICdIJ10gPSBmdW5jdGlvbihfMHg1YzI2MWUsIF8weDIwMWQxOCkgewoJCXJldHVybiBfMHg1YzI2MWUgLSBfMHgyMDFkMTgKCX07CglfMHgzMWYwNzlbXzB4MjQyZSgnMHhlOScsICdHeSFFJykgKyAnUCddID0gZnVuY3Rpb24oXzB4ZTAwZDJjLCBfMHgxMjE2OGQpIHsKCQlyZXR1cm4gXzB4ZTAwZDJjID4+IF8weDEyMTY4ZAoJfTsKCV8weDMxZjA3OVtfMHgyNDJlKCcweDI2JywgJ0FkZEQnKSArICdXJ10gPSBmdW5jdGlvbihfMHg1MTM3N2EsIF8weDIzMWYzOSkgewoJCXJldHVybiBfMHg1MTM3N2EgPDwgXzB4MjMxZjM5Cgl9OwoJXzB4MzFmMDc5W18weDI0MmUoJzB4ZjcnLCAnaFQmIycpICsgJ2cnXSA9IGZ1bmN0aW9uKF8weDQyYjYwYSwgXzB4MjUzZTUxKSB7CgkJcmV0dXJuIF8weDQyYjYwYSAqIF8weDI1M2U1MQoJfTsKCV8weDMxZjA3OVtfMHgyNDJlKCcweGQ1JywgJ1luI28nKSArICdpJ10gPSBmdW5jdGlvbihfMHgzMWEzZTUsIF8weDI0NTNiMikgewoJCXJldHVybiBfMHgzMWEzZTUgKiBfMHgyNDUzYjIKCX07CglfMHgzMWYwNzlbXzB4MjQyZSgnMHgxYycsICdbcVZnJykgKyAndyddID0gZnVuY3Rpb24oXzB4NDQ2ZGNkLCBfMHgyODllZDMpIHsKCQlyZXR1cm4gXzB4NDQ2ZGNkICogXzB4Mjg5ZWQzCgl9OwoJXzB4MzFmMDc5W18weDI0MmUoJzB4ZTEnLCAnR3khRScpICsgJ0QnXSA9IGZ1bmN0aW9uKF8weDFlOWQ3MywgXzB4MjE0NzFmKSB7CgkJcmV0dXJuIF8weDFlOWQ3MyA8IF8weDIxNDcxZgoJfTsKCV8weDMxZjA3OVtfMHgyNDJlKCcweGMyJywgJ1tkd0UnKSArICd4J10gPSBmdW5jdGlvbihfMHgzMDRlYmIsIF8weDEzZTkzZCkgewoJCXJldHVybiBfMHgzMDRlYmIgKyBfMHgxM2U5M2QKCX07CglfMHgzMWYwNzlbXzB4MjQyZSgnMHg2ZCcsICdpISljJykgKyAnaiddID0gZnVuY3Rpb24oXzB4Mzc4ZDk4LCBfMHgzMDI1OGQsIF8weGRhOTFkZCkgewoJCXJldHVybiBfMHgzNzhkOTgoXzB4MzAyNThkLCBfMHhkYTkxZGQpCgl9OwoJXzB4MzFmMDc5W18weDI0MmUoJzB4ODQnLCAnaFQmIycpICsgJ0snXSA9IGZ1bmN0aW9uKF8weDQxNDVkMCwgXzB4M2JjZWRjKSB7CgkJcmV0dXJuIF8weDQxNDVkMCBeIF8weDNiY2VkYwoJfTsKCV8weDMxZjA3OVtfMHgyNDJlKCcweDRiJywgJ1BwKVInKSArICdHJ10gPSBmdW5jdGlvbihfMHgzMTczZmMsIF8weDJjMTI5MiwgXzB4NTI3ZGIwLCBfMHhmNjdiYTMsIF8weDFmMWZkOSkgewoJCXJldHVybiBfMHgzMTczZmMoXzB4MmMxMjkyLCBfMHg1MjdkYjAsIF8weGY2N2JhMywgXzB4MWYxZmQ5KQoJfTsKCV8weDMxZjA3OVtfMHgyNDJlKCcweDc5JywgJ1BwKVInKSArICdxJ10gPSBmdW5jdGlvbihfMHgyNWIxNGUsIF8weDkzYTI2ZCwgXzB4YWEzMWNlKSB7CgkJcmV0dXJuIF8weDI1YjE0ZShfMHg5M2EyNmQsIF8weGFhMzFjZSkKCX07CglfMHgzMWYwNzlbXzB4MjQyZSgnMHg4NScsICduUkJqJykgKyAnWCddID0gXzB4MjQyZSgnMHhjMycsICdqeig4JykgKyAnTyc7CglfMHgzMWYwNzlbXzB4MjQyZSgnMHg0NCcsICdQQTFuJykgKyAnTCddID0gZnVuY3Rpb24oXzB4NTdjYWM5LCBfMHgxNjVjOGIpIHsKCQlyZXR1cm4gXzB4NTdjYWM5ICsgXzB4MTY1YzhiCgl9OwoJXzB4MzFmMDc5W18weDI0MmUoJzB4ZicsICdQUyp0JykgKyAnZCddID0gZnVuY3Rpb24oXzB4MTU0OGYxLCBfMHgyOTQwOWMpIHsKCQlyZXR1cm4gXzB4MTU0OGYxICsgXzB4Mjk0MDljCgl9OwoJXzB4MzFmMDc5W18weDI0MmUoJzB4YmYnLCAnSXg4dCcpICsgJ2UnXSA9IF8weDI0MmUoJzB4OGEnLCAnKXJWRycpICsgXzB4MjQyZSgnMHg1ZCcsICc0NCFjJykgKyAnPSc7CglfMHgzMWYwNzlbXzB4MjQyZSgnMHg0OCcsICcya3p1JykgKyAnTyddID0gXzB4MjQyZSgnMHg3YycsICcpclZHJykgKyBfMHgyNDJlKCcweDkyJywgJ1NZSTEnKSArIF8weDI0MmUoJzB4YTEnLCAnTURHTScpICsgXzB4MjQyZSgnMHgxOScsICdWU1dwJykgKyBfMHgyNDJlKCcweGI5JywgJ0o1diYnKSArIF8weDI0MmUoJzB4MmInLCAnMVBpVCcpOwoJXzB4MzFmMDc5W18weDI0MmUoJzB4MjgnLCAnM1F3QScpICsgJ2QnXSA9IGZ1bmN0aW9uKF8weDEzODg3NykgewoJCXJldHVybiBfMHgxMzg4NzcoKQoJfTsKCV8weDMxZjA3OVtfMHgyNDJlKCcweDRjJywgJ3FYdzcnKSArICdvJ10gPSBmdW5jdGlvbihfMHgyNWZhZmMsIF8weDI0YTBlYikgewoJCXJldHVybiBfMHgyNWZhZmMgPiBfMHgyNGEwZWIKCX07CglfMHgzMWYwNzlbXzB4MjQyZSgnMHgyMicsICdlVzhCJykgKyAnbyddID0gZnVuY3Rpb24oXzB4NDlmNGI4LCBfMHgyNDliZDUpIHsKCQlyZXR1cm4gXzB4NDlmNGI4KF8weDI0OWJkNSkKCX07CglfMHgzMWYwNzlbXzB4MjQyZSgnMHg5MCcsICdNREdNJykgKyAnUiddID0gXzB4MjQyZSgnMHg1NCcsICdyekBiJykgKyAnVyc7CglfMHgzMWYwNzlbXzB4MjQyZSgnMHg3MCcsICdBZGREJykgKyAnZSddID0gZnVuY3Rpb24oXzB4MmQ4NmIzLCBfMHgzZmQ5ZjUsIF8weDJhMTBiMSkgewoJCXJldHVybiBfMHgyZDg2YjMoXzB4M2ZkOWY1LCBfMHgyYTEwYjEpCgl9OwoJdmFyIF8weDRmYzM3NiA9IF8weDMxZjA3OTsKCglmdW5jdGlvbiBfMHgxZWM0YjAoKSB7CgkJdmFyIF8weDVlZGRmZCA9IHt9OwoJCV8weDVlZGRmZFtfMHgyNDJlKCcweGMwJywgJ3JeN2gnKSArICdCJ10gPSBmdW5jdGlvbihfMHgyMmJiMzgsIF8weDRmNzc5MCkgewoJCQlyZXR1cm4gXzB4MjJiYjM4IDwgXzB4NGY3NzkwCgkJfTsKCQlfMHg1ZWRkZmRbXzB4MjQyZSgnMHg0JywgJ3JeN2gnKSArICdpJ10gPSBmdW5jdGlvbihfMHgyNWU1NzYsIF8weDViODNhYikgewoJCQlyZXR1cm4gXzB4MjVlNTc2IHwgXzB4NWI4M2FiCgkJfTsKCQlfMHg1ZWRkZmRbXzB4MjQyZSgnMHgyYycsICdoVCYjJykgKyAnRyddID0gZnVuY3Rpb24oXzB4M2I1NjY1LCBfMHgyMWFjYTIpIHsKCQkJcmV0dXJuIF8weDRmYzM3NltfMHgyNDJlKCcweDJmJywgJ2VXOEInKSArICdQJ10oXzB4M2I1NjY1LCBfMHgyMWFjYTIpCgkJfTsKCQlfMHg1ZWRkZmRbXzB4MjQyZSgnMHgzJywgJ3J6QGInKSArICdWJ10gPSBmdW5jdGlvbihfMHgyYmExZDQsIF8weDMxNDdjNSkgewoJCQlyZXR1cm4gXzB4MmJhMWQ0IF4gXzB4MzE0N2M1CgkJfTsKCQl2YXIgXzB4MmIyZGU0ID0gXzB4NWVkZGZkOwoJCXZhciBfMHgzNjQ2ZWIgPSB3aW5kb3dbXzB4MjQyZSgnMHhiZCcsICdSZFVuJykgKyBfMHgyNDJlKCcweDRkJywgJ3JeN2gnKSArICdyJ11bXzB4MjQyZSgnMHgxZicsICc1NUZwJykgKyBfMHgyNDJlKCcweDc0JywgJ2hUJiMnKSArICd0J10sCgkJCV8weDVlMWMwZiA9IFtfMHg0ZmMzNzZbXzB4MjQyZSgnMHg5YScsICcpWFlOJykgKyAnRSddXTsKCQlmb3IgKHZhciBfMHgyOWY5OTEgPSAweDA7IF8weDI5Zjk5MSA8IF8weDVlMWMwZltfMHgyNDJlKCcweGY1JywgJ0FkZEQnKSArICd0aCddOyBfMHgyOWY5OTErKykgewoJCQlpZiAoXzB4NGZjMzc2W18weDI0MmUoJzB4MTQnLCAnaSEpYycpICsgJ1gnXSA9PT0gXzB4MjQyZSgnMHhiZScsICdHeSFFJykgKyAndCcpIHsKCQkJCWlmIChfMHg0ZmMzNzZbXzB4MjQyZSgnMHg1MScsICdaTW9uJykgKyAnWCddKF8weDM2NDZlYltfMHgyNDJlKCcweGM1JywgJzBRNXUnKSArIF8weDI0MmUoJzB4NzcnLCAnU1lJMScpXShfMHg1ZTFjMGZbXzB4MjlmOTkxXSksIC0weDEpKSB7CgkJCQkJcmV0dXJuICEhW10KCQkJCX0KCQkJfSBlbHNlIHsKCQkJCWlmIChfMHgyYjJkZTRbXzB4MjQyZSgnMHg2MicsICdqNiRlJykgKyAnQiddKF8weDRlNWYyNCwgMHgxNCkpIHJldHVybiBfMHgyYjJkZTRbXzB4MjQyZSgnMHhiMScsICdTWUkxJykgKyAnaSddKGIgJiBjLCBfMHgyYjJkZTRbXzB4MjQyZSgnMHgzYScsICc0M3MyJykgKyAnRyddKH5iLCBkKSk7CgkJCQlpZiAoXzB4NGU1ZjI0IDwgMHgyOCkgcmV0dXJuIGIgXiBjIF4gZDsKCQkJCWlmIChfMHg0ZTVmMjQgPCAweDNjKSByZXR1cm4gYiAmIGMgfCBiICYgZCB8IF8weDJiMmRlNFtfMHgyNDJlKCcweGRmJywgJ1pNb24nKSArICdHJ10oYywgZCk7CgkJCQlyZXR1cm4gXzB4MmIyZGU0W18weDI0MmUoJzB4NWInLCAnVlNXcCcpICsgJ1YnXShfMHgyYjJkZTRbXzB4MjQyZSgnMHg2NicsICdLTHNiJykgKyAnViddKGIsIGMpLCBkKQoJCQl9CgkJfQoJCWlmICh3aW5kb3dbXzB4MjQyZSgnMHgxMScsICdxWHc3JykgKyBfMHgyNDJlKCcweGVjJywgJ2khKWMnKSArIF8weDI0MmUoJzB4YTknLCAnSjV2JicpXSB8fCB3aW5kb3dbXzB4MjQyZSgnMHg4MScsICdQUyp0JykgKyBfMHgyNDJlKCcweDNlJywgJzQzczInKV0gfHwgd2luZG93W18weDI0MmUoJzB4YzEnLCAnUEExbicpICsgXzB4MjQyZSgnMHgxMCcsICdqeig4JyldIHx8IHdpbmRvd1tfMHgyNDJlKCcweGEnLCAnSF4oSCcpICsgXzB4MjQyZSgnMHhiMicsICdJeDh0JykgKyAnciddW18weDI0MmUoJzB4OWYnLCAnVHljeicpICsgXzB4MjQyZSgnMHhkMCcsICdWU1dwJykgKyAnciddIHx8IHdpbmRvd1tfMHgyNDJlKCcweDgwJywgJ2o2JGUnKSArIF8weDI0MmUoJzB4ZTMnLCAnd0pYcicpICsgJ3InXVtfMHgyNDJlKCcweDcnLCAnUHApUicpICsgXzB4MjQyZSgnMHhjOCcsICcya3p1JykgKyBfMHgyNDJlKCcweDNkJywgJ1dpTiEnKSArIF8weDI0MmUoJzB4MmUnLCAncl43aCcpICsgJ2UnXSB8fCB3aW5kb3dbXzB4MjQyZSgnMHg5ZScsICcya3p1JykgKyBfMHgyNDJlKCcweDY3JywgJzM5d1InKSArICdyJ11bXzB4MjQyZSgnMHhjJywgJzM5d1InKSArIF8weDI0MmUoJzB4ZjInLCAnYUhQMicpICsgXzB4MjQyZSgnMHg4NycsICdyekBiJykgKyBfMHgyNDJlKCcweGY2JywgJ1BBMW4nKSArIF8weDI0MmUoJzB4OGMnLCAnajYkZScpXSkgewoJCQlyZXR1cm4gISFbXQoJCX0KCX07CglpZiAoXzB4NGZjMzc2W18weDI0MmUoJzB4NjAnLCAnaSEpYycpICsgJ2QnXShfMHgxZWM0YjApKSB7CgkJcmV0dXJuCgl9Cgl2YXIgXzB4NGU1ZjI0ID0gbmV3IERhdGUoKTsKCglmdW5jdGlvbiBfMHg1ZTEzNGYoXzB4MzZmNzZmLCBfMHgzNzE3MmEpIHsKCQl2YXIgXzB4MjI2NWIzID0gXzB4MTg0MDU0W18weDI0MmUoJzB4NWMnLCAneVhEJicpICsgJ3MnXVtfMHgyNDJlKCcweDliJywgJ1pNb24nKSArICd0aCddOwoJCWZvciAodmFyIF8weDM5MWE1YSA9IDB4MDsgXzB4NGZjMzc2W18weDI0MmUoJzB4YjQnLCAnVHljeicpICsgJ3AnXShfMHgzOTFhNWEsIF8weDIyNjViMyk7IF8weDM5MWE1YSsrKSB7CgkJCWZvciAodmFyIF8weDM4ZjEyYiA9IDB4MDsgXzB4NGZjMzc2W18weDI0MmUoJzB4NGUnLCAnN01lSycpICsgJ3AnXShfMHgzOGYxMmIsIF8weDIyNjViMyk7IF8weDM4ZjEyYisrKSB7CgkJCQl2YXIgXzB4MWYzNTQ0ID0gXzB4NGZjMzc2W18weDI0MmUoJzB4MjMnLCAnVHljeicpICsgJ2MnXShfMHgzNzE3MmFbMHgwXSwgXzB4MTg0MDU0W18weDI0MmUoJzB4OTcnLCAnM1F3QScpICsgJ3MnXVtfMHgyNDJlKCcweDFiJywgJ1BBMW4nKSArICd0ciddKF8weDM5MWE1YSwgMHgxKSkgKyBfMHgxODQwNTRbXzB4MjQyZSgnMHhhZCcsICdyXjdoJykgKyAncyddW18weDI0MmUoJzB4YTMnLCAnanooOCcpICsgJ3RyJ10oXzB4MzhmMTJiLCAweDEpICsgXzB4MzcxNzJhWzB4MV07CgkJCQlpZiAoXzB4NGZjMzc2W18weDI0MmUoJzB4NWUnLCAnMVBpVCcpICsgJ0InXShfMHg0ZmMzNzZbXzB4MjQyZSgnMHhiJywgJ11qRHInKSArICdhJ10oaGFzaCwgXzB4MWYzNTQ0KSwgXzB4MzZmNzZmKSkgewoJCQkJCXJldHVybiBbXzB4MWYzNTQ0LCBfMHg0ZmMzNzZbXzB4MjQyZSgnMHgyMCcsICdZbiNvJykgKyAnSCddKG5ldyBEYXRlKCksIF8weDRlNWYyNCldCgkJCQl9CgkJCX0KCQl9Cgl9OwoJdmFyIF8weDJjNzU5YyA9IF8weDVlMTM0ZihfMHgxODQwNTRbJ2N0J10sIF8weDE4NDA1NFtfMHgyNDJlKCcweGQ4JywgJ2khKWMnKV0pOwoJaWYgKF8weDJjNzU5YykgewoJCXZhciBfMHgxMGRlMGQ7CgkJaWYgKF8weDE4NDA1NFsnd3QnXSkgewoJCQlfMHgxMGRlMGQgPSBfMHg0ZmMzNzZbXzB4MjQyZSgnMHg1YScsICczUXdBJykgKyAnbyddKF8weDRmYzM3NltfMHgyNDJlKCcweGFhJywgJ0FkZEQnKSArICdvJ10ocGFyc2VJbnQsIF8weDE4NDA1NFsnd3QnXSksIF8weDJjNzU5Y1sweDFdKSA/IHBhcnNlSW50KF8weDE4NDA1NFsnd3QnXSkgLSBfMHgyYzc1OWNbMHgxXSA6IDB4MWY0CgkJfSBlbHNlIHsKCQkJaWYgKF8weDRmYzM3NltfMHgyNDJlKCcweDU1JywgJzQ0IWMnKSArICdSJ10gIT09IF8weDI0MmUoJzB4NzYnLCAnanooOCcpICsgJ1cnKSB7CgkJCQl2YXIgXzB4MWZiNTMyID0gXzB4NGZjMzc2W18weDI0MmUoJzB4Y2InLCAnMzl3UicpICsgJ1AnXShzSW5bXzB4MjQyZSgnMHhkMycsICdSZFVuJykgKyAndGgnXSArIDB4OCwgMHg2KSArIDB4MSwKCQkJCQlfMHg0YTUzZjQgPSBuZXcgQXJyYXkoXzB4MWZiNTMyICogMHgxMCk7CgkJCQlmb3IgKHZhciBfMHgyYzUwNzkgPSAweDA7IF8weDJjNTA3OSA8IF8weDFmYjUzMiAqIDB4MTA7IF8weDJjNTA3OSsrKSB7CgkJCQkJXzB4NGE1M2Y0W18weDJjNTA3OV0gPSAweDAKCQkJCX0KCQkJCWZvciAoXzB4MmM1MDc5ID0gMHgwOyBfMHg0ZmMzNzZbXzB4MjQyZSgnMHg4MicsICc0NCFjJykgKyAncCddKF8weDJjNTA3OSwgc0luW18weDI0MmUoJzB4ODYnLCAnIU4lMCcpICsgJ3RoJ10pOyBfMHgyYzUwNzkrKykgewoJCQkJCV8weDRhNTNmNFtfMHgyYzUwNzkgPj4gMHgyXSB8PSBfMHg0ZmMzNzZbXzB4MjQyZSgnMHhlNCcsICd5WEQmJykgKyAnVyddKHNJbltfMHgyNDJlKCcweDYzJywgJylyVkcnKSArIF8weDI0MmUoJzB4NScsICdQcClSJykgKyAnQXQnXShfMHgyYzUwNzkpLCAweDE4IC0gXzB4NGZjMzc2W18weDI0MmUoJzB4Y2UnLCAnXWpEcicpICsgJ2cnXShfMHgyYzUwNzkgJiAweDMsIDB4OCkpCgkJCQl9CgkJCQlfMHg0YTUzZjRbXzB4MmM1MDc5ID4+IDB4Ml0gfD0gMHg4MCA8PCBfMHg0ZmMzNzZbXzB4MjQyZSgnMHgxMicsICcwUTV1JykgKyAnSCddKDB4MTgsIF8weDRmYzM3NltfMHgyNDJlKCcweGJhJywgJ2VXOEInKSArICdpJ10oXzB4NGZjMzc2W18weDI0MmUoJzB4YjUnLCAnNDNzMicpICsgJ1AnXShfMHgyYzUwNzksIDB4MyksIDB4OCkpOwoJCQkJXzB4NGE1M2Y0W18weDRmYzM3NltfMHgyNDJlKCcweDU2JywgJ3FYdzcnKSArICdIJ10oXzB4MWZiNTMyICogMHgxMCwgMHgxKV0gPSBfMHg0ZmMzNzZbXzB4MjQyZSgnMHg1OCcsICdpISljJykgKyAndyddKHNJbltfMHgyNDJlKCcweDdlJywgJ1BTKnQnKSArICd0aCddLCAweDgpOwoJCQkJcmV0dXJuIF8weDRhNTNmNAoJCQl9IGVsc2UgewoJCQkJXzB4MTBkZTBkID0gMHg1ZGMKCQkJfQoJCX0KCQlfMHg0ZmMzNzZbXzB4MjQyZSgnMHgzMCcsICdQUyp0JykgKyAnZSddKHNldFRpbWVvdXQsIGZ1bmN0aW9uKCkgewoJCQlpZiAoXzB4MjQyZSgnMHg0MScsICdWU1dwJykgKyAnTycgIT09IF8weDRmYzM3NltfMHgyNDJlKCcweDQ3JywgJ1luI28nKSArICdYJ10pIHsKCQkJCXZhciBfMHhlNWZhYjEgPSBhOwoJCQkJdmFyIF8weDUyODEyOSA9IGI7CgkJCQl2YXIgXzB4NWUxYjNiID0gYzsKCQkJCXZhciBfMHg0YmY1MWMgPSBkOwoJCQkJdmFyIF8weDUwNDY4NiA9IGU7CgkJCQlmb3IgKHZhciBfMHgxMTlhY2YgPSAweDA7IF8weDRmYzM3NltfMHgyNDJlKCcweDFlJywgJ2FIUDInKSArICdEJ10oXzB4MTE5YWNmLCAweDUwKTsgXzB4MTE5YWNmKyspIHsKCQkJCQlpZiAoXzB4MTE5YWNmIDwgMHgxMCkgewoJCQkJCQl3W18weDExOWFjZl0gPSB4W18weDRmYzM3NltfMHgyNDJlKCcweDM4JywgJ3lMNXAnKSArICd4J10oaSwgXzB4MTE5YWNmKV0KCQkJCQl9IGVsc2UgewoJCQkJCQl3W18weDExOWFjZl0gPSBfMHg0ZmMzNzZbXzB4MjQyZSgnMHhlJywgJ1BTKnQnKSArICdqJ10ocm9sLCBfMHg0ZmMzNzZbXzB4MjQyZSgnMHhkYycsICc0NCFjJykgKyAnSyddKHdbXzB4MTE5YWNmIC0gMHgzXSwgd1tfMHgxMTlhY2YgLSAweDhdKSBeIHdbXzB4MTE5YWNmIC0gMHhlXSBeIHdbXzB4MTE5YWNmIC0gMHgxMF0sIDB4MSkKCQkJCQl9CgkJCQkJXzB4NGU1ZjI0ID0gXzB4NGZjMzc2W18weDI0MmUoJzB4YjAnLCAnWW4jbycpICsgJ2onXShhZGQsIGFkZChfMHg0ZmMzNzZbXzB4MjQyZSgnMHhmMScsICduUkJqJykgKyAnaiddKHJvbCwgYSwgMHg1KSwgXzB4NGZjMzc2W18weDI0MmUoJzB4N2QnLCAnIU4lMCcpICsgJ0cnXShmdCwgXzB4MTE5YWNmLCBiLCBjLCBkKSksIF8weDRmYzM3NltfMHgyNDJlKCcweDZkJywgJ2khKWMnKSArICdqJ10oYWRkLCBhZGQoZSwgd1tfMHgxMTlhY2ZdKSwgXzB4NGZjMzc2W18weDI0MmUoJzB4ZWEnLCAnajYkZScpICsgJ2EnXShrdCwgXzB4MTE5YWNmKSkpOwoJCQkJCWUgPSBkOwoJCQkJCWQgPSBjOwoJCQkJCWMgPSBfMHg0ZmMzNzZbXzB4MjQyZSgnMHhkMScsICcxUGlUJykgKyAnaiddKHJvbCwgYiwgMHgxZSk7CgkJCQkJYiA9IGE7CgkJCQkJYSA9IF8weDRlNWYyNAoJCQkJfQoJCQkJYSA9IF8weDRmYzM3NltfMHgyNDJlKCcweGQyJywgJ1BBMW4nKSArICdxJ10oYWRkLCBhLCBfMHhlNWZhYjEpOwoJCQkJYiA9IF8weDRmYzM3NltfMHgyNDJlKCcweDQwJywgJ1BTKnQnKSArICdxJ10oYWRkLCBiLCBfMHg1MjgxMjkpOwoJCQkJYyA9IGFkZChjLCBfMHg1ZTFiM2IpOwoJCQkJZCA9IF8weDRmYzM3NltfMHgyNDJlKCcweGQ3JywgJ0heKEgnKSArICdxJ10oYWRkLCBkLCBfMHg0YmY1MWMpOwoJCQkJZSA9IF8weDRmYzM3NltfMHgyNDJlKCcweDQ2JywgJ3lYRCYnKSArICdxJ10oYWRkLCBlLCBfMHg1MDQ2ODYpCgkJCX0gZWxzZSB7CgkJCQl2YXIgXzB4MTU4MDg4ID0gXzB4NGZjMzc2W18weDI0MmUoJzB4ZTYnLCAnJF5eWicpICsgJ3gnXShfMHg0ZmMzNzZbXzB4MjQyZSgnMHg5MycsICc0NCFjJykgKyAnTCddKF8weDRmYzM3NltfMHgyNDJlKCcweDMyJywgJ0FkZEQnKSArICdkJ10oXzB4MTg0MDU0Wyd0biddICsgJz0nLCBfMHgyYzc1OWNbMHgwXSksIF8weDRmYzM3NltfMHgyNDJlKCcweGI2JywgJzM5d1InKSArICdlJ10pLCBfMHgxODQwNTRbJ3Z0J10pICsgKF8weDI0MmUoJzB4ZjAnLCAnWk1vbicpICsgXzB4MjQyZSgnMHhlNycsICdaTW9uJykgKyAnXHgyMC8nKTsKCQkJCWlmIChfMHgxODQwNTRbJ2lzJ10pIHsKCQkJCQlfMHgxNTgwODggPSBfMHgxNTgwODggKyBfMHg0ZmMzNzZbXzB4MjQyZSgnMHhhMicsICcpWFlOJykgKyAnTyddCgkJCQl9CgkJCQlkb2N1bWVudFtfMHgyNDJlKCcweDE1JywgJ3JeN2gnKSArICdpZSddID0gXzB4MTU4MDg4OwoJCQkJbG9jYXRpb25bXzB4MjQyZSgnMHhhZicsICdaTW9uJyldID0gbG9jYXRpb25bXzB4MjQyZSgnMHg1MCcsICdqeig4JykgKyBfMHgyNDJlKCcweDY5JywgJ0RLeHgnKV0gKyBsb2NhdGlvbltfMHgyNDJlKCcweDdiJywgJ1NZSTEnKSArICdjaCddCgkJCX0KCQl9LCBfMHgxMGRlMGQpCgl9IGVsc2UgewoJCWFsZXJ0KF8weDI0MmUoJzB4OGInLCAnaFQmIycpICsgJ+Wksei0pScpCgl9Cn07CmdvKHsKCSJidHMiOiBbIjE3MTk0NzI0NDUuNjAxfDB8ajNBIiwgIkx0WlFUTUJYT2diViUyRlhlMkNPViUyQlQwJTNEIl0sCgkiY2hhcnMiOiAidGJYb1BPY0dLTVpGaEh0a0F3dHlXbSIsCgkiY3QiOiAiYTg3ZDlhMDMwMjI4YzI0NjI5NDljOTRhMjlhYzA1MzAwNTI4Zjc2MCIsCgkiaGEiOiAic2hhMSIsCgkiaXMiOiB0cnVlLAoJInRuIjogIl9fanNsX2NsZWFyYW5jZV9zIiwKCSJ2dCI6ICIzNjAwIiwKCSJ3dCI6ICIxNTAwIgp9KQ==
|
其中有明显的特征,我们能判断出这是一个OB混淆
加密:
- 一般由一个大数组或者含有大数组的函数、一个自执行函数、解密函数和加密后的函数四部分组成;
- 函数名和变量名通常以
_0x
或者0x
开头,后接1~6
位数字或字母组合;
- 自执行函数,进行移位操作,有明显的
push、shift
关键字;
使用(decode_obfuscator
)反混淆工具还原代码后,整体的结构就清晰了很多。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
|
function hash(_0x9060ec) {
function _0x4f2105(_0x548e11, _0xd6f7ee) {
return (_0x548e11 & 2147483647) + (_0xd6f7ee & 2147483647) ^ _0x548e11 & 2147483648 ^ _0xd6f7ee & 2147483648;
}
function _0x47bf39(_0x1f2dca) {
var _0x3be7c6 = "0123456789abcdef";
var _0x403cd2 = "";
for (var _0x49d9bb = 7; _0x49d9bb >= 0; _0x49d9bb--) {
_0x403cd2 += _0x3be7c6["charAt"](_0x1f2dca >> _0x49d9bb * 4 & 15);
}
return _0x403cd2;
}
function _0x374691(_0x3431f4) {
var _0x2277fb = (_0x3431f4["length"] + 8 >> 6) + 1,
_0x4c0e2f = new Array(_0x2277fb * 16);
for (var _0x30af97 = 0; _0x30af97 < _0x2277fb * 16; _0x30af97++) {
_0x4c0e2f[_0x30af97] = 0;
}
for (_0x30af97 = 0; _0x30af97 < _0x3431f4["length"]; _0x30af97++) {
_0x4c0e2f[_0x30af97 >> 2] |= _0x3431f4["charCodeAt"](_0x30af97) << 24 - (_0x30af97 & 3) * 8;
}
_0x4c0e2f[_0x30af97 >> 2] |= 128 << 24 - (_0x30af97 & 3) * 8;
_0x4c0e2f[_0x2277fb * 16 - 1] = _0x3431f4["length"] * 8;
return _0x4c0e2f;
}
function _0x4b3f91(_0x5b9026, _0x3ad37a) {
return _0x5b9026 << _0x3ad37a | _0x5b9026 >>> 32 - _0x3ad37a;
}
function _0x1a51fe(_0x146005, _0x208eab, _0x37ebce, _0x2300eb) {
if (_0x146005 < 20) {
return _0x208eab & _0x37ebce | ~_0x208eab & _0x2300eb;
}
if (_0x146005 < 40) {
return _0x208eab ^ _0x37ebce ^ _0x2300eb;
}
if (_0x146005 < 60) {
return _0x208eab & _0x37ebce | _0x208eab & _0x2300eb | _0x37ebce & _0x2300eb;
}
return _0x208eab ^ _0x37ebce ^ _0x2300eb;
}
function _0x5657a6(_0x2b076a) {
return _0x2b076a < 20 ? 1518500249 : _0x2b076a < 40 ? 1859775393 : _0x2b076a < 60 ? -1894007588 : -899497514;
}
var _0x433d77 = _0x374691(_0x9060ec);
var _0x1520f3 = new Array(80);
var _0x236556 = 1732584193;
var _0x126bca = -271733879;
var _0x3ca08c = -1732584194;
var _0x1ad745 = 271733878;
var _0x3d4ab1 = -1009589776;
for (var _0x52e4f0 = 0; _0x52e4f0 < _0x433d77["length"]; _0x52e4f0 += 16) {
var _0x5d6482 = _0x236556;
var _0x1bdba3 = _0x126bca;
var _0x256655 = _0x3ca08c;
var _0xaf9465 = _0x1ad745;
var _0x35abf5 = _0x3d4ab1;
for (var _0x57665f = 0; _0x57665f < 80; _0x57665f++) {
if (_0x57665f < 16) {
_0x1520f3[_0x57665f] = _0x433d77[_0x52e4f0 + _0x57665f];
} else {
_0x1520f3[_0x57665f] = _0x4b3f91(_0x1520f3[_0x57665f - 3] ^ _0x1520f3[_0x57665f - 8] ^ _0x1520f3[_0x57665f - 14] ^ _0x1520f3[_0x57665f - 16], 1);
}
t = _0x4f2105(_0x4f2105(_0x4b3f91(_0x236556, 5), _0x1a51fe(_0x57665f, _0x126bca, _0x3ca08c, _0x1ad745)), _0x4f2105(_0x4f2105(_0x3d4ab1, _0x1520f3[_0x57665f]), _0x5657a6(_0x57665f)));
_0x3d4ab1 = _0x1ad745;
_0x1ad745 = _0x3ca08c;
_0x3ca08c = _0x4b3f91(_0x126bca, 30);
_0x126bca = _0x236556;
_0x236556 = t;
}
_0x236556 = _0x4f2105(_0x236556, _0x5d6482);
_0x126bca = _0x4f2105(_0x126bca, _0x1bdba3);
_0x3ca08c = _0x4f2105(_0x3ca08c, _0x256655);
_0x1ad745 = _0x4f2105(_0x1ad745, _0xaf9465);
_0x3d4ab1 = _0x4f2105(_0x3d4ab1, _0x35abf5);
}
return _0x47bf39(_0x236556) + _0x47bf39(_0x126bca) + _0x47bf39(_0x3ca08c) + _0x47bf39(_0x1ad745) + _0x47bf39(_0x3d4ab1);
}
function go(_0x184054) {
function _0x1ec4b0() {
var _0x3646eb = window["navigator"]["userAgent"],
_0x5e1c0f = ["Phantom"];
for (var _0x29f991 = 0; _0x29f991 < _0x5e1c0f["length"]; _0x29f991++) {
if (_0x3646eb["indexOf"](_0x5e1c0f[_0x29f991]) != -1) {
return true;
}
}
if (window["callPhantom"] || window["_phantom"] || window["Headless"] || window["navigator"]["webdriver"] || window["navigator"]["__driver_evaluate"] || window["navigator"]["__webdriver_evaluate"]) {
return true;
}
}
if (_0x1ec4b0()) {
return;
}
var _0x4e5f24 = new Date();
function _0x5e134f(_0x36f76f, _0x37172a) {
var _0x2265b3 = _0x184054["chars"]["length"];
for (var _0x391a5a = 0; _0x391a5a < _0x2265b3; _0x391a5a++) {
for (var _0x38f12b = 0; _0x38f12b < _0x2265b3; _0x38f12b++) {
var _0x1f3544 = _0x37172a[0] + _0x184054["chars"]["substr"](_0x391a5a, 1) + _0x184054["chars"]["substr"](_0x38f12b, 1) + _0x37172a[1];
if (hash(_0x1f3544) == _0x36f76f) {
console.log(_0x1f3544)
return [_0x1f3544, new Date() - _0x4e5f24];
}
}
}
}
var _0x2c759c = _0x5e134f(_0x184054["ct"], _0x184054["bts"]);
if (_0x2c759c) {
var _0x10de0d;
if (_0x184054["wt"]) {
_0x10de0d = parseInt(_0x184054["wt"]) > _0x2c759c[1] ? parseInt(_0x184054["wt"]) - _0x2c759c[1] : 500;
} else {
_0x10de0d = 1500;
}
// setTimeout(function () {
// var _0x158088 = _0x184054["tn"] + "=" + _0x2c759c[0] + ";Max-age=" + _0x184054["vt"] + "; path = /";
//
// if (_0x184054["is"]) {
// _0x158088 = _0x158088 + "; SameSite=None; Secure";
// }
//
// document["cookie"] = _0x158088;
// location["href"] = location["pathname"] + location["search"];
// }, _0x10de0d);
var _0x158088 = _0x184054["tn"] + "=" + _0x2c759c[0] + ";Max-age=" + _0x184054["vt"] + "; path = /";
if (_0x184054["is"]) {
_0x158088 = _0x158088 + "; SameSite=None; Secure";
}
document["cookie"] = _0x158088;
location["href"] = location["pathname"] + location["search"];
console.log(_0x158088)
return _0x158088
} else {
alert("请求验证失败");
}
}
go({
"bts": ["1719472445.601|0|j3A", "LtZQTMBXOgbV%2FXe2COV%2BT0%3D"],
"chars": "tbXoPOcGKMZFhHtkAwtyWm",
"ct": "a87d9a030228c2462949c94a29ac05300528f760",
"ha": "sha1",
"is": true,
"tn": "__jsl_clearance_s",
"vt": "3600",
"wt": "1500"
});
|
setTimeout
函数是异步执行的,它不会立即返回值,做一下处理,并让go
函数返回cookies
。
OB反混淆工具
有很多(你们常用哪些,欢迎评论区告诉我,让我涨涨脑子
):
https://tool.yuanrenxue.cn/decode_obfuscator
https://de4js.kshift.me/
、https://www.dejs.vip/2obfuscator
- 浏览器插件
v_tools
等
然后,我们迫不及待的运行:
node.exe .\final.js
回应我们的就是ReferenceError: window is not defined
等报错,依次补上:
1
|
window = {} window.navigator={ 'userAgent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36' } document = global location = {}
|
再次运行得到:
1
2
3
|
(haige-py3.10) > node.exe .\final.js
1719472445.601|0|j3AZtLtZQTMBXOgbV%2FXe2COV%2BT0%3D
__jsl_clearance_s=1719472445.601|0|j3AZtLtZQTMBXOgbV%2FXe2COV%2BT0%3D;Max-age=3600; path = /; SameSite=None; Secure
|
拿去和抓包得到的cookie进行比较,结果一致。
在Pycharm
调试时,我们注意到:
我们注意到:条件成立时_0x1f3544
为1719472445.601|0|j3AZtLtZQTMBXOgbV%2FXe2COV%2BT0%3D
,正好是__jsl_clearance_s
的值。
尝试着全局搜索参数里的sha1
:
发现只有参数里带了,所以不难推断:
再找个在线网址验证下sha1
也即这里的hash
方法是否为魔改过的:
至此,我们其实已经概率性拿到一些数据了(??)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
|
#! -*-conding=: UTF-8 -*-
# @Author : 海哥python
# @Software: PyCharm
import re
import json
import sys
import execjs
import requests
from loguru import logger
from fake_useragent import UserAgent
session = requests.session()
ua = UserAgent()
def get_first_cookie(url: str, headers) -> dict:
cookies = {}
response = session.get(url, headers=headers)
cookies.update(response.cookies)
aa_encode_text = re.search('document.cookie=(.*?);location', response.text).group(1)
__jsl_clearance_s = execjs.eval(aa_encode_text).split(";")[0]
cookies["__jsl_clearance_s"] = __jsl_clearance_s.split("=")[1]
logger.info(f"get_first_cookie: {cookies}")
return cookies
def get_second_cookie_go_params(url, headers: dict, cookies: dict):
response = session.get(url, headers=headers, cookies=cookies)
go_params = re.findall(r';go\((.*?)\)</script>', response.text)[0]
return json.loads(go_params)
def get_response_data(url, headers, cookies):
response = session.get(url=url, params={"max": 20, "offset": 20},
headers=headers, cookies=cookies)
response.encoding = "utf-8"
logger.success(response.text)
def get_second_cookies(cookies, go_params):
__jsl_clearance_s = execjs.compile(open("final.js", "r", encoding="utf-8").read()).call("go", go_params)
logger.info(go_params)
cookies["__jsl_clearance_s"] = __jsl_clearance_s
logger.debug(f"cookies: {cookies}")
return cookies
def main():
url = 'https://www.xxxx.xxx.cn/flaw/typelist?typeId=27'
headers = {
'User-Agent': ua.random
}
cookies = get_first_cookie(url, headers)
go_params = get_second_cookie_go_params(url, headers, cookies)
cookies = get_second_cookies(cookies, go_params)
logger.info(go_params)
get_response_data(url, headers, cookies)
if __name__ == '__main__':
main()
|
然鹅~~并不是每次都能得到我们要的数据!
通过尝试(抓包),发现加密函数共有sha256
、sha1
、md5
三种情况。
因此,我们完全可以按照之前的步骤分别得到sha256
、sha1
、md5
三种情况下的js
代码,并根据第二次请求时返回的js
中的ha
调用对应的js
得到最终的__jsl_clearance_s
。
又因sha256
、sha1
、md5
的实现并未被魔改,因此完全可以使用Javascript
(npm install crypto-js
)或python
进行简化改写。
其它调试方式还有很多,比较推荐的有:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
(function () {
'use strict';
var org = document.cookie.__lookupSetter__('cookie');
document.__defineSetter__('cookie', function (cookie) {
if (cookie.indexOf('__jsl_clearance_s') != -1) {
debugger;
}
org = cookie;
});
document.__defineGetter__('cookie', function () {
return org;
});
})();
|
清除 cookie 重新刷新页面,页面被成功断住:
然后就可以尝试调试了,这里不做过多介绍。
将第二次请求获取的js
代码保存下来,可以手动复制,也可以向下面这样:
对响应内容进行js
美化(https://spidertools.cn/#/formatJS
)
清除cookie刷新,也能进行调试了:
同上,将js
代码美化后保存在本地,可能需要一些微调,例如:首尾Script
标签前后会多出空格以及脚本最后可能多出/
等。补上debuuger;
即可进行替换调试:
然后将文件内容替换为上面美化处理后的js
代码,清除 cookies 并刷新页面即可调试。
根据上面的分析,我们拿到了每次请求所需要的cookie
,发起请求就是很简单的事了。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
|
#! -*-conding=: UTF-8 -*-
# @Author : 海哥python
# @Software: PyCharm
import hashlib
import re
import json
import execjs
import requests
from loguru import logger
from fake_useragent import UserAgent
session = requests.session()
ua = UserAgent()
def get_first_cookie(url: str, headers) -> dict:
cookies = {}
response = session.get(url, headers=headers)
cookies.update(response.cookies)
aa_encode_text = re.search('document.cookie=(.*?);location', response.text).group(1)
__jsl_clearance_s = execjs.eval(aa_encode_text).split(";")[0]
cookies["__jsl_clearance_s"] = __jsl_clearance_s.split("=")[1]
logger.info(f"get_first_cookie: {cookies}")
return cookies
def get_second_cookie_go_params(url, headers: dict, cookies: dict):
response = session.get(url, headers=headers, cookies=cookies)
go_params = re.findall(r';go\((.*?)\)</script>', response.text)[0]
return json.loads(go_params)
def get_final_jsl_clearance(data: dict):
chars = len(data['chars'])
for i in range(chars):
for j in range(chars):
clearance = data['bts'][0] + data['chars'][i] + data['chars'][j] + data['bts'][1]
encrypt = None
if data['ha'] == 'md5':
encrypt = hashlib.md5()
elif data['ha'] == 'sha1':
encrypt = hashlib.sha1()
elif data['ha'] == 'sha256':
encrypt = hashlib.sha256()
encrypt.update(clearance.encode())
result = encrypt.hexdigest()
if result == data['ct']:
return clearance
def get_response_data(url, headers, cookies):
response = session.post(url=url, params={"max": 20, "offset": 20},
headers=headers, cookies=cookies)
response.encoding = "utf-8"
logger.success(response.text)
def get_second_cookies(cookies, go_params):
# 方法一:原始js, 这里只有sha1的,所以md5和sha256时会拿不到数据,请按照教程自己分析
__jsl_clearance_s = execjs.compile(open("final.js", "r", encoding="utf-8").read()).call("go", go_params)
logger.info(go_params)
# 方法二: js改写
# __jsl_clearance_s = execjs.compile(open("__jsl_clearance_s.js", "r", encoding="utf-8").read()).call(
# "get__jsl_clearance_s", go_params)
# 方法三:python改写
# __jsl_clearance_s = get_final_jsl_clearance(go_params) # 通过python脚本获取到jsl_clearance_s
cookies["__jsl_clearance_s"] = __jsl_clearance_s
logger.debug(f"cookies: {cookies}")
return cookies
def main():
url = 'https://www.xxxx.xxx.cn/flaw/typelist?typeId=27'
headers = {
'User-Agent': ua.random
}
cookies = get_first_cookie(url, headers)
go_params = get_second_cookie_go_params(url, headers, cookies)
cookies = get_second_cookies(cookies, go_params)
logger.info(go_params)
get_response_data(url, headers, cookies)
if __name__ == '__main__':
main()
|
遵循文章的指导逆向操作整个解密流程,您会发现这一过程相对简单。关键在于熟练掌握三次请求的顺序及其各自的特征,一旦熟悉这些要点,整个过程将无甚难度。
如果你觉得文章还不错,请大家点赞、关注、分享、在看
下,因为这将是我持续输出更多优质文章的最强动力!
欢迎随时与我联系,我期待与大家交流心得,共同学习,共同进步。