众所周知,Kotlin通过语法糖的形式实现了很多便捷和高效的方法,因此研究Kotlin代码通常是需要研究字节码或者反编译后的java文件。
比如这样的代码
fun String.toConsole() { |
Kotlin的编译器会在字节码中自动地增加这样一行代码Intrinsics.checkParameterIsNotNull
来做一些预检查的操作。
痛点
那么问题来了,如果我们想找出所有的关于Intrinsics
相关的自动加入内容,该怎么办,不能一个一个文件去反编译查看吧,因为这样
- 没有目标性,无法明确预知那个文件会生成这种代码
- 不具有自动化可重复性,需要依赖于人为行为
那么,我们查看class文件类进行内容匹配是否包含Intrinsics
呢,其实也不太好,因为一个class文件的内容是这样的
cat StringExtKt.class |
一段很错乱的内容,这样不利于我们更好的分析问题。因为相比较而言,我们有更加好的方法来处理。
基于上面的痛点,自己动手写了一个简单的ruby脚本,来解决问题。
实现思路
- 遍历指定路径下的class文件
- 将对应的class文件使用
javap
反编译 - 使用上面反编译的结果,查看是否包含待查询的关键字
- 如果上述结果匹配到,将反编译内容和文件路径输出到结果文件中
代码(Talk is cheap)
#!/usr/bin/ruby |
执行命令
ruby searchBytecode.rb ./ "Intrinsics" /tmp/result.txt |
- searchBytecode.rb 是上述的脚本文件名称
- ./ 第一个参数,为待查找的目录
- “Intrinsics” 第二个参数,为查询关键字
- /tmp/result.txt 第三个参数,为结果输出文件
执行日志
为了更好的表达应用正在执行,执行时会有日志输出。
其中
- 正常的日志会以白色颜色输出
- 不匹配的内容会以红颜色输出
- 匹配的内容会以绿颜色输出
结果文件
cat sample_intrinsics.txt |
问题排查
/System/Library/Frameworks/Ruby.framework/Versions/2.3/usr/lib/ruby/2.3.0/rubygems/core_ext/kernel_require.rb:55:in `require': cannot load such file -- colorize (LoadError) |
需手动安装ruby gems依赖
1 | ➜ gem install colorize |
再次执行即可。
执行优化
- 具体的执行时间可能会随着工程的复杂而不同。
- 建议筛选更加精细的目录,避免不必要的查询和操作
- 可以同时使用
tail -f
筛选匹配结果。
脚本github地址:https://github.com/androidyue/DroidScripts/blob/master/ruby/searchBytecode.rb
以上。
相关内容
- 研究学习Kotlin的一些方法