0x00 前言
本文是对上期反调试与反反调试文章的补充。
0x01 location
我在上期文章中提到过我无法通过hook解决掉location.href,后来也有师傅在留言区提到了另一个location的方法,那就是replace,href在上期文章中已经介绍过了,所以接下来就给大家介绍一下replace方法:
这个方法可以以给定的URL来替换掉当前的资源,例如 window.location.replace("http://www.baidu.com")
执行后就会跳转到百度,还有一个效果类似的方法就是location.assign方法:
使用方法也是一样的,但是这两个方法的效果是有区别的。
•location.replace()
调用 replace() 方法后,当前页面不会保存到会话历史中(session History),这样,用户点击回退按钮时,将不会再跳转到该页面。
•location.assign()
调用 assign() 方法后,当前页面会保存到会话历史中(session History)。
简单演示一下,以下是执行 window.location.assign("http://www.bing.com")
的效果:
可见是可以回退到上一页面的,而执行 window.location.replace("http://www.bing.com")
就达不到以上的效果:
而这两个方法同样也重写不了(Chrome):
虽然看的是重写了,但是执行 window.location.replace("http://www.bing.com")
依然还是原本的效果,还有之前提到过的href也无法hook掉,至少我目前做不到,这些会在之后的hook深入文章中提到。
不过接下来我在这里分享一个hook脚本,是CC11001100师傅写的(这里感谢一下CC11001100师傅开源提供的思路):
github地址:https://github.com/JSREI/page-redirect-code-location-hook
具体代码:
onbeforeunload:
当浏览器窗口关闭或者刷新时,就会触发 beforeunload 事件。
我就拿上期文章中提到的那个跳转案例看下效果,F12访问网站:
可见此时已经设置了location.href并触发了beforeunload事件,跟下堆栈:
直接跟到了设置window.location.href的位置,所以接下来可以替换掉这段定时器从而防止网站跳转。
我自己的解决方案也是只能给出替换,我上文给出的一个替换方法是抓包替换,不过我这两天抽时间写了一个脚本,就拿上期的那个跳转案例演示一下效果:
大家应该能从中看出来其效果,也就是说我通过mitmproxy抓包,将存在location.href和其他两个方法的js文件下载到本地,其中还会copy一份临时的js文件(copy的js文件名格式为:xxx.temp.js
),为什么要copy一份,这是因为我们F12查看的js文件都是格式化后的,例如我这里创建一个测试文档,引入一下压缩后的jquery文件:
F12查看:
可见在F12中显示的js文件都是格式化后的,但实际上加载的js是压缩后的,这是一个很重要的知识点,我在之前的自动化加解密文章中也提到过类似的知识点,也就是说我们一定要保证其 文件或数据要和原本加载的一模一样
,所以我特地下了两份js下来,备份的js是我们拿来定位反调试代码的,而另一份则是我们用来替换的。
刚刚我已经演示了定位到那段熟悉的反调试代码,现在就去要替换的js中删掉这段代码:
删掉即可:
记住要替换的js一定 不要格式化
,上文已经提到过为什么,这里不再过多赘述。
接下来我讲一下如何不打开网站进行替换,不知道大家有没有发现chrome替换的一个特点,我这里随便拿一个网站演示一下:
如果我要替换掉这个jquery,那么替换的文件夹名就会是这样的:
我猜大家应该能理解到我的意图了,这也是为什么我在脚本中还增加了print出js地址的功能:
所以我们替换后的js文件应该放到这个目录下:
xxx.xxx.com/_nuxt/BfRsNvdj.js
打开存放替换后的js的文件夹:
新建一个文件夹,文件夹就是这个网站的域名:
继续创建一个_nuxt文件夹,将替换后的js放进去即可:
现在就完成了替换,开着F12访问一下网站:
现在进入网站就自动加载了我们替换后的js。
工具我已经开源在github上,地址:https://github.com/0xsdeo/Locate_location
。
注:该工具适用于没有设类似waf的网站,上文提到的那个案例似乎是每天都会更新一下js文件名,读者可以自行对比一下本期存在反调试的那个js文件名和上期的文件名,显然是不一样的,所以遇到这种情况我还是建议通过抓包替换,这样保险一些。
0x02 Bypass Debugger
其实上期文章中我写的bypass debugger脚本还不是那么好,虽然能够实现想要的效果,但是有些地方还是有点多余了,所以我还是进行了优化
,具体看下文。
我还是先拿第一个版本的脚本进行优化,直接上代码:
改写前的:
大家应该立马就能看出来哪里改了,就是最后的那段赋原型,我没再去用Object.create方法,直接去赋值了,这种是可以的,至于为什么我上期没这么写,是我个人原因,因为当时在学Object的一些方法,所以就顺着用了这个方法,导致脚本显得有些臃肿了。
临时变量Bypass_debugger.prototype
指向的就是Function的原型,所以这里直接赋给重写后的Function原型即可:
所以优化第二版的代码也是顺手的事:
改写前的:
可见代码清晰了不少,我个人觉得是没有哪里需要解释的,上期文章中都讲到过,如果读者有不懂的地方可以在本文下方留言或私信我。所以目前优化成这样就不需要再改写第三版的了,我当时写第三版的脚本时就是为了想让重写constructor的那段代码放到最后,现在就不需要了,因为已经是放到最后了。
最后就是重写Function为构造函数那段hook脚本:
优化后依然是某些案例用不了,原因还是未知。还是那句话,如果有知道为什么的大佬,可以留言或者私信我,本人洗耳恭听。
代码已同步更新在github上,地址:https://github.com/0xsdeo/Hook_JS
原文始发于微信公众号(Spade sec):JS逆向系列11-反调试与反反调试(续)
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论