【瑞数VMP】浅谈某普期刊JS逆向的环境检测点
前言
某普前段时间更新了新版本的瑞数。
不过去年的垃圾代码跑不通,但是又有需求的情况下就插桩打印分析了下。
简单聊下几个检测点以及补环境应对办法。
ps: 相比去年,今年需要写的东西就不多了。
正文
原型链
原型链hook还是能打印大部分环境信息的,然后和本地打印出来的信息比对下,补的跟浏览器跑出来的一样就行了。(5代补的齐的话,基本上到6代要解决的就是几个检测点。5代补环境可以看我去年写的文章)然后这里不再赘述原型链hook了…
检测点
第一个检测点
window或其原型链上的原型对象都获取不到这个属性描述符,但是test in window是true的。
一开始我是代理了window来做的,但是代理window真的超级容易被检测到(行不通的笨蛋)。
第一个检测点解决思路
我们可以通过代理WindowProperties这个原型对象来实现这个功能。
并且当全局对象获取不到属性时,我在原型上也能捕获到,还不容易被检测,一举两得。
第二个检测点
typeof document.all == ‘undefined’
这个不好在js中实现,得在node源码里操作。
一开始我是用泰迪大佬的代码,在node模块中实现new 一个type为undefined的对象。
但是这样的话,我们无法对其进行代理。为什么要代理?
浏览器里原型是HTMLAllCollection、HTMLCollection的对象,都是动态数组。即dom树改变,数组就会动态更新(无需重新获取一次该对象)。
但是呢我比较菜,所以我用代理的话能比较轻松的实现这个功能。
第二个检测点解决方案
放上v8源码实现(非node模块实现),可以直接将一个对象的type类型置为undefined
BUILTIN(UtilsSetUndetectable){
HandleScope scope(isolate);
Factory* factory = isolate->factory();
int args_len = args.length() - 1;
if (args_len < 1) {
// 报错
}
Handle<JSObject> obj = Handle<JSObject>::cast(args.at(1));
Handle<Map> map(obj->map(), isolate);
Handle<Map> new_map = Map::Copy(isolate, map, "CopyAsPrototypeForJSGlobalProxy");
new_map->set_is_undetectable(true);
// 如果对对象本身的map set_is_undetectable会导致同类型的对象type全部为undefined.
obj->set_map(*new_map);
return *factory->ToBoolean(true);
}
// 更多关于node v8 API 的源码, 我放在星球里了. 星球里还有不不大佬的补环境框架.
// 星球不定期更新好东西, 是我、泰迪、陈不不一起合作的.
// 链接: https://t.zsxq.com/06bIUvBEM
插桩
如果还是过不去,并且原型链hook打印执行流程没有发现异常的情况下。就可以在vmp代码位置插桩打印执行流日志(日志有点多的),和本地的执行流日志比对,看看是不是有什么不一样的地方。至于在哪里打印,外面有几篇文章告诉读者插桩点了,这里就不放出来了…
鸣谢
在这里感谢陈不不大佬,在JS逆向之路上提供了不少帮助~
有兴趣的小伙伴们可以看看他在B站上发的视频,对JS逆向提升有一定的帮助~
b站:陈不不and挽风的逆向
我、陈不不、泰迪合作的星球:https://t.zsxq.com/06bIUvBEM
如有侵权,请第一时间联系作者删除文章~