0%

20210306 问题小记

最近对某些第三方Android库做简单的逆向分析。遇到两个问题,记录之。

Variables debug info not available

Android Studio 中断点调试某些第三方 Android 库提示 Variables debug info not available,无法查看局部变量信息。

找到以下资料 来源

Java classes which are part of the JDK are compiled without debug info for the size and performance reasons.

简单来说是提到出于大小和性能因素考虑,JDK 中的类是不带 debug 信息的。

类似地,很多第三方 Android 库使用 proguard 等工具混淆和优化后去掉了 debug 信息,所以调试时无法查看局部变量信息(成员变量信息可查看)

无法生成 ScanResult 实例

通常来说,我们会使用 Android 系统 API 获取 android.net.wifi.ScanResult 的实例。示例:

1
List<ScanResult> list = wifiManager.getScanResults();

但出于某些原因,我想自己创建 android.net.wifi.ScanResult 的实例。一开始,我以为这很简单。

第一个思路,直接调用构造方法创建不就可以了吗?

1
2
3
ScanResult sr = new ScanResult();

ScanResult sr2 = new ScanResult(sr);

但实际上在 Android SDK 30 之前,没有这两个构造方法。所以低版本 Android 设备上有兼容问题,会报 java.lang.NoSuchMethodError 错误:

1
2
3
2021-03-06 11:15:48.458 22161-22161/? E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.amaploc.demo, PID: 22161
java.lang.NoSuchMethodError: No direct method <init>()V in class Landroid/net/wifi/ScanResult; or its super classes (declaration of 'android.net.wifi.ScanResult' appears in /system/framework/framework.jar!classes2.dex)

第二个思路,反射调用 ScanResult 的构造方法 (非公开方法,@hidden)。但同样存在兼容性问题:

  1. 不同版本的 SDK 上非公开的构造方法参数不同
  2. 某些厂商可能修改了 ScanResult 构造方法

这里提供一个简单的解决办法。考虑到 ScanResult 实现了 Parcelable 接口,所以可以借助 Parcel 来序列化/反序列化生成新的实例。

1
2
3
4
5
6
7
8
9
public ScanResult scanResultInstance() {
ScanResult parent = sCopyInstance;

Parcel p = Parcel.obtain();
parent.writeToParcel(p, 0);
p.setDataPosition(0);

return ScanResult.CREATOR.createFromParcel(p);
}

参考