谈谈JSDebugger

务虚乱弹

JSDebugger开源地址:https://github.com/SatanWoo/JSDebugger

这是一篇谈谈设计JSDebugger的总体设想,不会过于深究具体实现细节,后续会单独探讨一些涉及实现方面的过程。

读过我之前博客的朋友可能会记得我3-4月份的时候写过一篇动手制作一个简易的iOS动态执行器,效果如下:

虽然这个效果还起来还不错(有许多人问这个东西咋实现的,挺炫酷的),但是其实只是个原型而已,从设想构思到编码实现没有超过一天的时间。当时在博文里面承诺发代码,想想实现的完善度还不够,就准备完善后再继续搞搞。不过后来由于我转到其他组不继续钻研iOS,这事也就不了了之。

那为什么现在又重新开搞呢?,三点原因吧:

  1. 有朋友在群里问我之前提过的Mach-o包瘦身方案怎么也没发文章?
  2. 看到同事查非Crash产生的Bug的过程还是比较累。

好,来说说前两个原因:

  • 第一点,有些文章为什么后续不发,主要原因还是很多产出和收获都是工作中和同事一起探讨研究出来的,发出来一是泄漏了公司的数据(职业操守还是很重要的),二是相当于霸占了一些别人的工作成果。比如说我之前写的内存等等,对外发的一般都是只和开源代码相关的同时删减了大部分略微关键的部分,所以导致有些读者读起来断断续续云里雾里。

完整版的很多文章或者一些没对外的技术研究,我都发在了公司的内网里,欢迎加入阿里巴巴。

  • 第二点,我之前有段时间负责手淘的稳定性,除了有堆栈的Crash问题外,更多是用户反馈的使用异常以及毫无头绪的奇怪现象。针对这种问题,我相信各家(甚至开源方案)一般都有自己的监控体系,比如日志啊、埋点等等。但是怎么说呢,从我的感受来看,都是使用起来偏繁琐,而且还依赖对应的开发把错误信息等现场保留写入到日志内。我想要的就是一个能像我在自己手机上调试应用一样调试用户手机的能力(前提是用户授权同意),因此我就想做了一个这样的工具。结合自己以前玩逆向的些许经历,Cycript就提供了类似的能力,因此就利用业余时间做了一个JSDebugger

说了这么多原因,其实还是我太懒了。

JSDebugger

言归正传,回到JSDebugger本身,基于之前的代码,这次主要做了完整性的代码重构重写以及功能完善上。

  • 类方法调用
  • 实例方法调用
  • Setter & Getter的调用
  • 可变参数的函数调用
  • C Pointer的使用
  • 基础类型的使用
  • 对象和类的使用
  • 结构体的使用(目前支持CGSize, CGRect, CGPoint,正在开发自定义注册接口)
  • 插件化的扩展功能。

同时,为了更好的测试所写的JavaScript代码,开发了玩具级别的Playground功能,每次实时修改文件后保存即可自动触发Reload

很多细节此文不表,但是有些功能上的实现还是比较用心的,比如支持了各种类型、个数的可变参数的函数调用,比如目前支持了chooseintrospect的能力,二者配合可以对任意对象实时查询其当前所有的属性值。

而且,我对JavaScriptCore的使用可能和常规大家所属性的iOS JavaScriptCore有所区别,利用更低层的设计思路,经过我实测:

更低层的设计桥接思路在iOS上同比基于Objective-C的使用方式可以节省50%的时间;同比在Android上使用开源的JavaScriptCore50分之一左右的时间。

当然Android上比较主流的JS引擎室v8咯

具体快原因可以阅读动手制作一个简易的iOS动态执行器中涉及的JavaScriptCore上层源码分析以及阅读我的JSDebugger源码。

目前JSDebugger还在不断完善中,后续会把我更多的想法移植到里面,总体规划有几个关键点:

  • 实现一个交互式的编辑器(或者命令行),能够让大家写Objective-C的代码自动转换成JSDebugger的JS语法。以我目前的技术水准,还做不到Cycript那种牛逼的Objective-CJavaScript的混合语法模式。

  • 实现远程图形化Debug能力。目前JSDebugger可以调试数据,但是如果能像Reveal一样把操作界面和数据结合起来就会更有效的定位问题。

欢迎有想法的朋友一起来参与完善这个项目,开源地址如下:

https://github.com/SatanWoo/JSDebugger

https://github.com/SatanWoo/JSDebugger

https://github.com/SatanWoo/JSDebugger

当然,要是发现了任何的Bug或者使用上的疑惑、抑或是可以改进的点,也可以私聊我或者开issue

最后

实现JSDebugger的过程,还是站在两个杰出的项目肩膀上:

  • Cycript
  • JSPatch

我的思路是来自于Cycript,诸如结构体等许多方面的实现细节是参考了JSPatch。在这里对这几个项目的作者和代码贡献者表示感谢!

此外,很多的技术方案是和HookZZ大神交流(主要是他教我)中学习而来,在这也特别感谢。也感谢头条的谢大佬的代码贡献以及寒神的Code Style整理。

当然,JSDebugger在实现上还是有很多自己思考的部分,感兴趣的读者可以自行前往JSDebugger的Github开源地址