android studio debug模式下和release模式下代码不一样_如何用lint扫出不安全代码

Lint是Google提供的静态代码分析工具,用于检查Android项目的质量问题。它与Android Studio集成,具备强大的功能和丰富的内置规则。本文介绍了自定义Lint的步骤,包括创建Java Library、编写自定义lint规则、打包aar库以及集成和调试,帮助开发者更好地理解和应用Lint。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

点击上方蓝字关注我们噢~

58e0907ddf6955b05909a86586581a63.gif 每个开发者都有一个梦想,希望写出来的代码没有Bug。虽然我们知道这是不可能的,退而求其次,那我们能否尽可能在编码阶段发现更多的潜在问题呢?这个是有可能的,这就是今天要介绍的主题lint。 01

Lint是什么

Lint是google提供的一款静态代码扫描工具,目的是帮助开发者发现代码的质量问题。

df61e0b18c5599b99480f8a1ad22ae53.png

相对于其他的工具,Lint有如下优势:

1)功能强大,支持java文件、class文件、资源文件、Gradle等文件的检测。

2)与android studio天然集成,可一键完成lint检测。

3)Lint专为android设计,规则丰富,原生已提供几百个实用规则。

4)扩展性强,支持自定义lint规则

......

02

Lint的原理

Lint功能如此强大,具体Lint是如何做到的?下图是Lint扫描的工作流。 0ad02615167167480037a0b087b1a1f5.png lint工具的代码扫描工作流 App源文件:包含组成Android项目的文件,如java、Kotlin、xml等 Lint.xml: lint工具的配置文件, 可根据业务场景调整问题的严重级别,或忽略某项检测项。 通过上图,可推断大致流程, lint Tool加载App Source文件及配置文件, 然后 根据内置规则及定制规则解析文件,最终生成lint out的报告。 根据推测,我们去分析Lint的源码,结果基本符合我们的猜想。整个lint工具包含 三个核心库文件:lint.jar,lint-api.jar,lint-checks.jar。

Lint.jar是整个lint的核心及入口,并在lint.jar中调用lint-api.jar及lint-checks.jar。

Lint-api.jar主要是对api进行一些封装,而lint-checks主要是内置规则的一些实现,下文将简单介绍整个lint的加载过程。

c6c8739e6b96cea4708e9530f5bccfbb.gif 主入口是,Lint.jar的main函数,具体如下: 4fbbd4886032702411a07741d710dfb7.png Main中run方法包含lint工具的处理流程。 Run函数主要流程如下: efa14209826a4cd076ffcffd8e061344.png 通过BuiltinIssueRegistry将内置规则和自定义规则进行加载,具体如下: a0679c70530ecbab939c7081966c8abf.png a9fc3f6cc6c33c6bd760e6d15e5216b2.png 当规则准备好以后,client开始run,进入实际的分析流程。 4d4c72559bdc10662fc5c68a7f6075b3.png b2d4e110dab1380d029400177e658578.png Client的run方法实际调用driver的analyze()方法,driver实际为lint-api.jar中LintDriver。analyze()方法调用checkProject进行项目的检查。 647e5d9fd52ce69460b3f0f3b77e1e2b.png

CheckProject方法又继续调用runFileDetectors进行分析。

91288a86b4a3c0cb5f859a053d2a8f72.png

以xml文件为例,在runFileDetectors会调用XmlVisitor.visitFile方法,最终调用相应scanner的具体方法。 561a1bdd50a0a9a35bb710695e6cb1d8.png 6c3fb807ae7f405f244e755aef25d549.png 至此,整个规则加载及检测流程基本清晰。03
Lint的重要概念
Lint提供一些API,我们可以根据API来编写自定义的规则,但其中涉及几个重要的概念,理解清楚有助于我们编写规则。具体的概念如下: Issue: 表示一条规则。 IssueRegistry: 用于注册Issue。自定义的Lint最终会生成jar包,jar包的Manifest须指向IssueRegistry类。 Detector: 检测单元。每个Issue对应一个Detector。 Scope: 声明Detector作用域,即扫描代码的范围,如java源文件、xml资源文件、Gradle文件等。 Scanner: 扫描单元。扫描并发现代码中的Issue。每个Detector可以实现一个或多个Scanner。自定义Lint主要工作就是实现Scanner。04

自定义lint

原理介绍差不多了,大家一定迫不及待想看看到底如何自定义lint吧。下面将介绍如何创建自定义lint。

0672496381aca6b332fc1d10ed774cdf.gif
创建Java Library
Android Studio中选择新建Module,选择Java Library 9a8849f2c02535f169669b3c582b6b31.png 具体的创建过程不详细叙述,这里特别说明几处 重要的注意项:

Gradle Plugin版本,请选择2.3.3,Gradle 版本选择3.3,否则一些包会找不到

8e096f922378c837bf56536f570c3bcf.png

项目目录下build.gradle修改,重点是依赖的版本号及maven目录

9902bf18c90e45401fdf21633d3db429.png 根目录下build.gradle文件 25b206df67b80617c3be8ed6921d7485.png 0672496381aca6b332fc1d10ed774cdf.gif
编写自定义lint
Registry注册Issue,如下我们注册一个名为VSecureRandomDetector的ISSUE 7f71a719c07a152ed3c18a6e43ff7847.png Scanner编写,通过getApplicableMethodNames定义关注的方法,这里我们只关心setSeed的方法。 然后在visitMethod中实现具体的逻辑,如当检查到setSeed方法时,我们需要判断方法的Class信息、参数信息等。如果不符合预期,则打印报告。详情如下: d3a4bbb1fa42ab1bac957e0c77f6cdf5.png 0672496381aca6b332fc1d10ed774cdf.gif
创建aar库

由于最终需要将jar集成到android工程中,所以我们需要将jar打包成aar文件,方便集成到android工程中。

创建android Library e7fc02fb1c5b7349fb9a6c97d9544b9a.png 修改aar的build.gradle文件,建立和jar之间关系,最终将jar打包到aar中。详情如下: f6210ce4d30b446134034b2c651f619c.png 最终执行build,生成libaar-debug.aar 0672496381aca6b332fc1d10ed774cdf.gif
自定义Lint集成

将libarr-debug.aar包放到项目目录的libs目录下,如果没有可以新建一个libs目录。然后在build.gradle中引入aar,具体可以参考下图:

d37d2d9e22f45d49a0a3a51a556134fd.png 接下来编写测试代码,看看自定义lint规则是否生效。测试代码如下: c84f2616251be80c378893e8447e9a79.png 测试代码中,当我们直接使用setSeed时,Android Studio显示红色波浪线,提示错误。 报错原因是不符合VSecureRandomForTest规则的要求,而VSecureRandomForTest正是我们上文自定义的lint规则,证明规则生效了。 当然,当我们build工程的时候,android studio也会自动执行lint检查。当检测到error时,会停止build的执行,并给出代码行及问题的原因,所以排查起来也是相对方便。具体如下图: 2b092e67f2c22521e7493ae1d48a98bc.png
0672496381aca6b332fc1d10ed774cdf.gif
Lint调试
编写规则过程,不可避免会出现错误,那我们能否去调试规则代码?当然可以。调试时,我们需要通过remote远程到项目上,执行调试。具体如下: 在规则项目中,建立remote,选择自己的代码模块,其他默认参数

bde43780bde1cd84642a282fa825a29d.png

在测试项目中,build项添加VM选项,VM选项可以从第一步的remote中拷贝,然后把suspend改为yes,具体如下图所示

6cff68638b6fa84a8a70e6e95c02f67b.png

在测试项目build.gradle中添加lint配置如下:

e0a7712c2b5611a2e5805ea0606d3f3a.png

以debug方式运行测试项目,然后将规则项目attach到测试项目中,就可以调试了,如下所示

9fb0dc88c891566eac8c2bd7e32e3570.png

总结

自定义lint集成的过程中,踩了很多坑,大部分是环境的问题,如gradle的版本、android studio的版本等。

整个环境打通后,后续的工作就是研究规则编写。这部分内容,一方面需要理解lint的重要概念、加载原理,内容上文已介绍;另一方面需要贴合自身的业务,这部分不详细阐述。

本文主要起抛砖引玉的作用,欢迎拍砖。

参考: 1.https://developer.android.com/studio/write/lint?hl=zh-cn 2.https://tech.meituan.com/2018/04/13/waimai-android-lint.html

ca531b0f917963de07d693541ebbdd37.gif

更多精彩阅读 f3fc08d05fe4011124d8f10cbf5136f3.gif如何用OLLVM来保护你的关键代码一文读懂 | 内置安全成熟度模型BSIMM像攻击者一样思考:论威胁分析中的建模模型

长按关注  更多安全技术干货等你发现 38d0233d98701eee8463d182bbfcbe06.png

d143f82f982bb74cfc98e3603514414a.gif

好文!在看吗?点一下鸭!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值