前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >利用 Kotlin inline 解决日志泄漏风险

利用 Kotlin inline 解决日志泄漏风险

作者头像
codelang
发布2022-11-30 14:47:39
3050
发布2022-11-30 14:47:39
举报
文章被收录于专栏:codelangcodelang

写这个话题主要是因为看到一篇文章《淘宝系App图片为什么在北京电信网络加载这么慢?[1]》,文章作者通过 xposed hook 了淘宝的 ALog 日志,最终分析到问题原因。这不觉让我有点警惕,Log 日志是我们平时开发中经常使用的调试工具,但却成为了三方了解应用流程的助推器。

因何泄漏?

我来列一个我们平时开发最常用的 LogUtils:

代码语言:javascript
复制
object LogUtils {
    fun i(tag: String, msg: String) {
        if (App.isDebug) {
            Log.i(tag, msg)
        }
    }
}

通过 isDebug 来保护在 Release 环境中 Log.i 日志不会被打印,在 MainActivity 中我们可以这么调用:

代码语言:javascript
复制
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        
        // 打印日志
        LogUtils.i("TAG", "MainActivity onCreate") 
    }
}

我们来反编译看下 Release 包:

由于 Release 包的 isDebug 为 false,经过代码优化,LogUtils.i 在判断 log 内容不为空时直接 return 不处理,可是 LogUtils.i 方法依然存在,这导致 MainActivity 中调用 LogUtils.i 的日志,可以被三方通过 hook LogUtils.i 方法,读取该方法中的参数并打印出来,例子中的 ALog 就是这么被 hook 泄漏的。

我们需要的是,在 isDebug 为 false 的时候,调用 LogUtils.i 的地方和 LogUtils.i 这个方法都从 Release 包中消失,这样才能从根本上消除日志。

如何解决?

我们可以用 kotlin inline 来解决这个问题,尝试写个工具类:

代码语言:javascript
复制
inline fun <reified T : Any> T.logE(msg: String) {
    if (App.isDebug) {
        val tag = this::class.java.simpleName
        Log.e(tag, msg)
    }
}

在 MainActivity 中调用:

代码语言:javascript
复制
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        
        this.logE("MainActivity onCreate")
    }
}

反编译看下 Release 包:

为什么 kotlin inline 可以呢?我来写个转换过程可能方便理解些:

代码语言:javascript
复制
//1、 原始调用
override fun onCreate(savedInstanceState: Bundle?) {
    this.logE("MainActivity onCreate")
}

//2、kotlin inline 转换
override fun onCreate(savedInstanceState: Bundle?) {
     if (App.isDebug) {
        val tag = MainActivity::class.java.simpleName
        Log.e(tag, msg)
    }
}

//3、经过编译器优化
override fun onCreate(savedInstanceState: Bundle?) {
 
}

由于 App.isDebug 为 false,永远走不到这个分支,编译器经过代码优化,将该代码直接移除,最终,MainActivity 中 Log 相关的信息全部消失。

参考资料

[1]

淘宝系App图片为什么在北京电信网络加载这么慢?: https://coderyuan.com/2020/05/26/taobao-app-images-request-debug/

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2022-07-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 扣浪 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 因何泄漏?
  • 如何解决?
  • 参考资料
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档