likes
comments
collection
share

花亿点时间,写个Android抓包库

作者站长头像
站长
· 阅读数 37

0x1、引言

上周五版本刚提测,这周边改BUG边摸鱼,百无聊赖,想起前不久没业务需求时,随手写的Android抓包库。

花亿点时间,写个Android抓包库

就 公司的APP集成了 抓包功能,目的是:方便非Android开发的同事在 接口联调和测试阶段 能够看到APP的请求日志,进行一些简单的问题定位(如接口字段错误返回,导致APP UI显示异常),不用动不动就来找Android崽~

手机摇一摇,就能查看 APP发起的请求列表具体的请求信息

花亿点时间,写个Android抓包库

能用,但存在一些问题,先是 代码层面

  • 耦合:抓包代码直接硬编码在项目中,线上包不需要抓包功能,也会把这部分代码打包到APK里
  • 复用性差:其它APP想添加抓包功能,需要手动CV大量代码...
  • 安全性:是否启用抓包功能,通过 BuildConfig.DEBUG 来判断,二次打包修改AndroidManifest.xml文件添加 android:debuggable="true" 或者 root手机后修改ro.debuggable为1 设置手机为可调试模式,生产环境的接口请求一览无余。

当然,上面的安全性有点 夸大 了,编译时,编译器会进一步优化代码,可能 会删除未使用的变量或代码块。比如这样的代码:

if (BuildConfig.DEBUG) {
    xxx.setBaseUrl(Config.DEBUG_BASE_URL);
} else {
    xxx.setBaseUrl(Config.RELEASE_BASE_URL);
}

Release打包,BuildConfig.DEBUG永远为false,编译器会优化下代码,编译后的代码可能就剩这句:

xxx.setBaseUrl(Config.RELEASE_BASE_URL);

不信的读者可以设置 minifyEnabled true 后打包,反编译自己的APP试试康~

花亿点时间,写个Android抓包库

尽管编译后的Release包不包含 启用抓包的代码,但是把抓包代码打包到APK里,始终是不妥的。

毕竟,反编译apk,smail加个启用抓包的代码,并不是什么难事,最好的处理方式还是不要把抓包代码打包到Release APK中!

接着说说 实用性层面

  • 请求相关信息太少:只有URL、请求参数和响应参数这三个数据,状态码都没有,有时需要看下请求头或响应头参数。
  • 只能看不能复制:有时需要把请求参数发给后端。
  • 字段查找全靠肉眼扫:请求/响应Json很长的时候,看到眼花😵‍💫。
  • 不支持URL过滤: 执行一个操作,唰唰唰一堆请求,然后就是滑滑滑,肉👀筛URL。
  • 请求记录不会动态更新,要看新请求得关闭页面再打开。
  • 等等...

综上,还是有必要完善下这个库的,毕竟也是能 提高团队研发效率的一小环~

上面说的天花龙凤,其实没啥技术难点,库的本质就是

自定义一个okhttp拦截器获取请求相关信息然后进行一系列功能封装 而已。

所以:库不支持HttpUrlConnection、Flutter、其它协议包的抓取!!!

它的定位只是:方便非Android崽,查看公司APP的请求日志。 像笔者就不需要这个,电脑直接看不香么~

如果是 Android崽或者愿意折腾,想抓手机所有APP包 的朋友,可以参考下面两篇文章:

接着介绍下如何集成这个库,以及一些使用小技巧~

0x2、库的集成

1、添加依赖

// 根目录的build.gradle 添加 JitPack的Maven仓库
maven { url 'https://jitpack.io' }

// 添加依赖
debugImplementation 'com.github.coder-pig:CpNetworkCapture:0.0.11'

抓包库应该只在 调试阶段 起作用,所以这里使用debugImplementation,即库不参与release包的打包过程。当然,你硬要implementation也是可以的🤡

2、添加拦截器

我也想让你完全无侵入地使用这个库,但是抱歉,做不到,你仍需要 手动添加一个拦截器,而且是使用 反射的方式 代码示例如下:

// 反射获取抓包拦截器类实例初始化
var captureInterceptor: Interceptor? = null
try {
    val clazz = Class.forName("cn.coderpig.cp_network_capture.interceptor.CaptureInterceptor")
    val constructor = clazz.getDeclaredConstructor()
    captureInterceptor = constructor.newInstance() as Interceptor
} catch (e: Exception) {
    e.printStackTrace()
}

val builder = OkHttpClient.Builder()
// 抓包拦截器不为null,添加拦截器
captureInterceptor?.let { builder.addInterceptor(it) }
//...
builder.build()

想省去这一步的话,可以使用 ASM,不过这玩意一堆坑,得花不少时间折腾,我是懒的搞,感兴趣想搞可以参考下这个仓库:lygttpod/AndroidMonitor

3、跳转抓包页

利用 activity-alias 标签单独创建一个桌面图标,作为抓包页面入口,点击图标即可进入抓包页~

花亿点时间,写个Android抓包库

当然,有时可能需要主动跳转抓包页,比如我司就是摇一摇打开,依旧是反射,代码示例如下:

 try {
    Class<?> clazz = Class.forName("cn.coderpig.cp_network_capture.ui.activity.NetworkCaptureActivity");
    Intent starter = new Intent(mContext, clazz);
    starter.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    mContext.startActivity(starter);
} catch (Exception e) {
    e.printStackTrace();
}

0x3、库的使用

1、请求列表页

点击桌面的卡比兽图标即可进入请求列表页:

花亿点时间,写个Android抓包库

可以看到请求相关的一些基础信息,工具栏的两个按钮:

  • 垃圾桶:清空请求记录
  • 设置:进入设置页

花亿点时间,写个Android抓包库

设置页就是一些默认设置,接着点击 请求列表 四个大字,可以打开 URL过滤,比如过滤article

花亿点时间,写个Android抓包库

点击取消可以关闭过滤功能,点击列表项,会跳转到请求信息页~

2、请求信息页

左侧是请求相关信息,右侧是响应相关信息

花亿点时间,写个Android抓包库

3、点击复制 & 长按查找

请求/响应头、请求/响应体支持 点击复制到剪切板

花亿点时间,写个Android抓包库

不过TextView本身就自带 双击选取文本,接着点击 长按,可以对当前文本进行查找:

花亿点时间,写个Android抓包库

点击上下箭头可以查找前一个或后一个匹配项,默认 字符串全匹配(忽略大小写) ,工具栏的两个按钮:

  • Aa:不忽略大小写
  • .* :开启正则匹配

大概的用法就这些,后续再补个库的开发记录吧,欢迎Star体验,有问题或建议可以提issues,感谢~

转载自:https://juejin.cn/post/7276750877250699320
评论
请登录