1、 解体日志
日志 1
要害日志
Failed to register native method com.bykv.vk.component.ttvideo.player.TTPlayer._close(J)V in base.apk
ttvideo :其中 tt 标识头条,可知是头条广告 SDK Failed to register native method:看样子是 so 相干
具体日志
Failed to register native method com.bykv.vk.component.ttvideo.player.TTPlayer._close(J)V in base.apk----- class 'Lcom/bykv/vk/component/ttvideo/player/TTPlayer;' cl=0x12d6c3a0 ----- objectSize=941 (736 from super) access=0x0008.0001 super='java.lang.Class<java.lang.Object>' (cl=0x0) vtable (24 entries, 11 in super): 0: void com.bykv.vk.component.ttvideo.player.TTPlayer.A() 1: int com.bykv.vk.component.ttvideo.player.TTPlayer.a(int, float) 2: int com.bykv.vk.component.ttvideo.player.TTPlayer.b(int, int) 3: int com.bykv.vk.component.ttvideo.player.TTPlayer.c(int, long) 4: int com.bykv.vk.component.ttvideo.player.TTPlayer.d(int, java.lang.String) 5: int com.bykv.vk.component.ttvideo.player.TTPlayer.e(android.view.Surface) 6: void com.bykv.vk.component.ttvideo.player.TTPlayer.g(float, float) 7: void com.bykv.vk.component.ttvideo.player.TTPlayer.h(int) 8: void com.bykv.vk.component.ttvideo.player.TTPlayer.i(long) 9: void com.bykv.vk.component.ttvideo.player.TTPlayer.j(com.bykv.vk.component.ttvideo.player.f) 10: void com.bykv.vk.component.ttvideo.player.TTPlayer.l(java.lang.String, int) 11: float com.bykv.vk.component.ttvideo.player.TTPlayer.m(int, float) 12: int com.bykv.vk.component.ttvideo.player.TTPlayer.n(int, int) 13: long com.bykv.vk.component.ttvideo.player.TTPlayer.o(int, long) 14: void com.bykv.vk.component.ttvideo.player.TTPlayer.p(int) 15: void com.bykv.vk.component.ttvideo.player.TTPlayer.r(java.lang.String) 16: int com.bykv.vk.component.ttvideo.player.TTPlayer.s() 17: void com.bykv.vk.component.ttvideo.player.TTPlayer.t(int) 18: int com.bykv.vk.component.ttvideo.player.TTPlayer.u() 19: java.lang.String com.bykv.vk.component.ttvideo.player.TTPlayer.v(int) 20: int com.bykv.vk.component.ttvideo.player.TTPlayer.w() 21: int com.bykv.vk.component.ttvideo.player.TTPlayer.x() 22: int com.bykv.vk.component.ttvideo.player.TTPlayer.y() 23: int com.bykv.vk.component.ttvideo.player.TTPlayer.z() direct methods (35 entries): 0: void com.bykv.vk.component.ttvideo.player.TTPlayer.<clinit>() 1: void com.bykv.vk.component.ttvideo.player.TTPlayer.<init>(android.content.Context, long) 2: void com.bykv.vk.component.ttvideo.player.TTPlayer.B() 3: long com.bykv.vk.component.ttvideo.player.TTPlayer._create(android.content.Context, int, java.lang.String) 4: int com.bykv.vk.component.ttvideo.player.TTPlayer._getCurrentPosition(long) 5: int com.bykv.vk.component.ttvideo.player.TTPlayer._getDuration(long) 6: float com.bykv.vk.component.ttvideo.player.TTPlayer._getFloatValue(long, int, float) 7: int com.bykv.vk.component.ttvideo.player.TTPlayer._getIntValue(long, int, int) 8: long com.bykv.vk.component.ttvideo.player.TTPlayer._getLongValue(long, int, long) 9: java.lang.String com.bykv.vk.component.ttvideo.player.TTPlayer._getStringValue(long, int) 10: int com.bykv.vk.component.ttvideo.player.TTPlayer._getVideoHeight(long) 11: int com.bykv.vk.component.ttvideo.player.TTPlayer._getVideoWidth(long) 12: int com.bykv.vk.component.ttvideo.player.TTPlayer._isLooping(long) 13: int com.bykv.vk.component.ttvideo.player.TTPlayer._isPlaying(long) 14: int com.bykv.vk.component.ttvideo.player.TTPlayer._pause(long) 15: int com.bykv.vk.component.ttvideo.player.TTPlayer._prepare(long) 16: void com.bykv.vk.component.ttvideo.player.TTPlayer._release(long) 17: int com.bykv.vk.component.ttvideo.player.TTPlayer._reset(long) 18: int com.bykv.vk.component.ttvideo.player.TTPlayer._seek(long, int) 19: void com.bykv.vk.component.ttvideo.player.TTPlayer._setCacheFile(long, java.lang.String, int) 20: void com.bykv.vk.component.ttvideo.player.TTPlayer._setDataSource(long, java.lang.String) 21: void com.bykv.vk.component.ttvideo.player.TTPlayer._setDataSourceFd(long, int) 22: int com.bykv.vk.component.ttvideo.player.TTPlayer._setFloatValue(long, int, float) 23: int com.bykv.vk.component.ttvideo.player.TTPlayer._setIntValue(long, int, int) 24: int com.bykv.vk.component.ttvideo.player.TTPlayer._setLongValue(long, int, long) 25: void com.bykv.vk.component.ttvideo.player.TTPlayer._setLooping(long, int) 26: int com.bykv.vk.component.ttvideo.player.TTPlayer._setStringValue(long, int, java.lang.String) 27: void com.bykv.vk.component.ttvideo.player.TTPlayer._setSupprotSampleRates(int[], int) 28: int com.bykv.vk.component.ttvideo.player.TTPlayer._setVideoSurface(long, android.view.Surface) 29: void com.bykv.vk.component.ttvideo.player.TTPlayer._setVolume(long, float, float) 30: int com.bykv.vk.component.ttvideo.player.TTPlayer._start(long) 31: void com.bykv.vk.component.ttvideo.player.TTPlayer._stop(long) 32: java.lang.String com.bykv.vk.component.ttvideo.player.TTPlayer.f() 33: void com.bykv.vk.component.ttvideo.player.TTPlayer.k(java.lang.String) 34: void com.bykv.vk.component.ttvideo.player.TTPlayer.q(long) static fields (4 entries): 0: int com.bykv.vk.component.ttvideo.player.TTPlayer.d 1: int[] com.bykv.vk.component.ttvideo.player.TTPlayer.e 2: java.lang.String com.bykv.vk.component.ttvideo.player.TTPlayer.f 3: boolean com.bykv.vk.component.ttvideo.player.TTPlayer.g instance fields (3 entries): 0: long com.bykv.vk.component.ttvideo.player.TTPlayer.a 1: android.content.Context com.bykv.vk.component.ttvideo.player.TTPlayer.b 2: int com.bykv.vk.component.ttvideo.player.TTPlayer.c
日志 2
要害日志
E/DEBUG: Thread Name: 'tt_pangle_threa'
tt\_pangle\_threa:进一步确认属于是穿山甲(头条)广告 SDK 所在位置导致出现异常
具体日志
E/DEBUG: --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---E/DEBUG: maps:E/DEBUG: total lines: 2308, matched 708 lines, write 708 lines.E/DEBUG: total address size: 1962624 kBE/DEBUG: --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- ---E/DEBUG: Process Name: '【包名】'E/DEBUG: Thread Name: 'tt_pangle_threa'E/DEBUG: pid: 15925, tid: 16120 >>> 【包名】 <<<E/DEBUG: killed by pid: 15925, comm: 【包名】, uid: 12428.E/DEBUG: signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr --------E/DEBUG: x0 0000000000000000 x1 0000000000003ef8 x2 0000000000000006 x3 0000000000000008E/DEBUG: x4 0000000000000199 x5 0000007f882de940 x6 04e82d887f000000 x7 0000007f882de804E/DEBUG: x8 0000000000000083 x9 ffffffffffffffdf x10 0000000000000000 x11 0000000000000001E/DEBUG: x12 ffffffffffffffff x13 0000000001000000 x14 0000000000000f7e x15 0000000000001fe3E/DEBUG: x16 0000007f88320ed0 x17 0000007f882ca510 x18 0000000000000000 x19 0000007f5c0d04f8E/DEBUG: x20 0000000000000006 x21 0000007f5c0d0450 x22 000000000000000b x23 00000000000009dcE/DEBUG: x24 ffffffffffffffff x25 0000007f853fc730 x26 0000007f85386540 x27 0000007f5c0ca801E/DEBUG: x28 0000007f8534c3db x29 0000007f5c0ca730 x30 0000007f882c79a0E/DEBUG: sp 0000007f5c0ca710 pc 0000007f882ca518 pstate 0000000060000000E/DEBUG: v0 00000000000000010000000000000000 v1 0000007f5c0ca2900000007f5c0ca710E/DEBUG: v2 00000000000000000000000000000000 v3 00000000001000000000000000000000E/DEBUG: v4 00000000000000000000000000000000 v5 40100401401004014010040140100401E/DEBUG: v6 00000000001000000000000000100000 v7 000000000000000000000000c1b00000E/DEBUG: v8 00000000000000000000000000000000 v9 00000000000000000000000000000000E/DEBUG: v10 00000000000000000000000000000000 v11 00000000000000000000000000000000E/DEBUG: v12 00000000000000000000000000000000 v13 00000000000000000000000000000000E/DEBUG: v14 00000000000000000000000000000000 v15 00000000000000000000000000000000E/DEBUG: v16 00000000000000000000000042756400 v17 0000000000000000000000003fbb8000E/DEBUG: v18 0000000000000000000000003e8ac000 v19 000000000000000000000000ebad8083E/DEBUG: v20 000000000000000000000000ebad8084 v21 000000000000000000000000ebad8085E/DEBUG: v22 000000000000000000000000ebad8086 v23 000000000000000000000000ebad8087E/DEBUG: v24 000000000000000000000000ebad8088 v25 000000000000000000000000ebad8089E/DEBUG: v26 000000000000000000000000ebad808a v27 000000000000000000000000ebad808bE/DEBUG: v28 000000000000000000000000ebad808c v29 000000000000000000000000ebad808dE/DEBUG: v30 000000000000000000000000ebad808e v31 00000000000000000000000000000001E/DEBUG: fpsr 00000013 fpcr 00000000E/DEBUG: #00 pc 000000000006b518 /system/lib64/libc.so (tgkill+8)E/DEBUG: #01 pc 000000000006899c /system/lib64/libc.so (pthread_kill+64)E/DEBUG: #02 pc 0000000000023ee8 /system/lib64/libc.so (raise+24)E/DEBUG: #03 pc 000000000001c96c /system/lib64/libc.so (abort+52)E/DEBUG: #04 pc 000000000040b380 /system/lib64/libart.so (_ZN3art7Runtime5AbortEv+352)E/DEBUG: #05 pc 00000000000c2218 /system/lib64/libart.so (_ZN3art10LogMessageD2Ev+1204)E/DEBUG: #06 pc 000000000042d980 /system/lib64/libart.so (_ZNK3art6Thread24AssertNoPendingExceptionEv+836)E/DEBUG: #07 pc 0000000000101630 /system/lib64/libart.so (_ZN3art11ClassLinker9FindClassEPNS_6ThreadEPKcNS_6HandleINS_6mirror11ClassLoaderEEE+68)E/DEBUG: #08 pc 00000000003026bc /system/lib64/libart.so (_ZN3art3JNI9FindClassEP7_JNIEnvPKc+2780)E/DEBUG: #09 pc 000000000005d8dc /data/app/【包名】-1/lib/arm64/libttmplayer_lite.soE/DEBUG: #10 pc 000000000005e94c /data/app/【包名】-1/lib/arm64/libttmplayer_lite.so (JNI_OnLoad+360)E/DEBUG: #11 pc 00000000002ccec8 /system/lib64/libart.so (_ZN3art9JavaVMExt17LoadNativeLibraryEP7_JNIEnvRKNSt3__112basic_stringIcNS3_11char_traitsIcEENS3_9allocatorIcEEEEP8_jobjectP8_jstringPS9_+2136)E/DEBUG: #12 pc 000000000000427c /system/lib64/libopenjdkjvm.so (JVM_NativeLoad+280)E/DEBUG: #13 pc 000000000009be20 /system/framework/arm64/boot.oatE/DEBUG: --- --- --- ---
2、代码定位剖析
由日志 1,那么获取到解体安装包和失常安装包,提取 com.bykv.vk.component.ttvideo.player.TTPlayer
类下的 Native
代码进一步剖析
解体包: TTPlayer
类 Native
办法申明
private final native long _create(Context context, int i, String str); public static final native int _getCurrentPosition(long j); public static final native int _getDuration(long j); public static final native float _getFloatValue(long j, int i, float f); public static final native int _getIntValue(long j, int i, int i2); public static final native long _getLongValue(long j, int i, long j2); public static final native String _getStringValue(long j, int i); public static final native int _getVideoHeight(long j); public static final native int _getVideoWidth(long j); public static final native int _isLooping(long j); public static final native int _isPlaying(long j); public static final native int _pause(long j); public static final native int _prepare(long j); public static final native void _release(long j); public static final native int _reset(long j); public static final native int _seek(long j, int i); public static final native void _setCacheFile(long j, String str, int i); public static final native void _setDataSource(long j, String str); public static final native void _setDataSourceFd(long j, int i); public static final native int _setFloatValue(long j, int i, float f); public static final native int _setIntValue(long j, int i, int i2); public static final native int _setLongValue(long j, int i, long j2); public static final native void _setLooping(long j, int i); public static final native int _setStringValue(long j, int i, String str); public static final native void _setSupprotSampleRates(int[] iArr, int i); public static final native int _setVideoSurface(long j, Surface surface); public static final native void _setVolume(long j, float f, float f2); public static final native int _start(long j); public static final native void _stop(long j);
失常包: TTPlayer
类 Native
办法申明
public static final native void _close(long j); private final native long _create(Context context, int i, String str); public static final native String _getAppPath(); public static final native int _getCurrentPosition(long j); public static final native double _getDoubleValue(long j, int i, double d); public static final native int _getDuration(long j); public static final native float _getFloatValue(long j, int i, float f); public static final native int _getIntValue(long j, int i, int i2); public static final native Object _getJObjectValue(long j, int i); public static final native long _getLongValue(long j, int i, long j2); public static final native String _getStringValue(long j, int i); public static final native int _getVideoHeight(long j); public static final native int _getVideoWidth(long j); public static final native int _isLooping(long j); public static final native int _isPlaying(long j); public static final native void _mouseEvent(long j, int i, int i2, int i3); public static final native int _pause(long j); public static final native int _prepare(long j); public static final native void _prevClose(long j); public static final native void _registerPlayerInfo(); public static final native void _release(long j); public static final native int _reset(long j); public static final native void _rotateCamera(long j, float f, float f2); public static final native int _seek(long j, int i); public static final native void _setAudioProcessor(long j, AudioProcessor audioProcessor); public static final native void _setCacheFile(long j, String str, int i); public static final native void _setDataSource(long j, IMediaDataSource iMediaDataSource); public static final native void _setDataSource(long j, String str); public static final native void _setDataSourceFd(long j, int i); public static final native int _setDoubleValue(long j, int i, double d); public static final native int _setFloatValue(long j, int i, float f); public static final native int _setIntValue(long j, int i, int i2); public static final native void _setLoadControl(long j, LoadControl loadControl); public static final native int _setLongValue(long j, int i, long j2); public static final native void _setLooping(long j, int i); public static final native void _setMaskInfo(long j, MaskInfo maskInfo); public static final native void _setMediaTransport(long j, MediaTransport mediaTransport); public static final native int _setStringValue(long j, int i, String str); public static final native void _setSubInfo(long j, SubInfo subInfo); public static final native void _setSupportFormatNB(int i); public static final native void _setSupprotSampleRates(int[] iArr, int i); public static final native int _setSurfaceValue(long j, long j2); public static final native int _setVideoSurface(long j, Surface surface); public static final native void _setVolume(long j, float f, float f2); public static final native int _start(long j); public static final native void _stop(long j); public static final native void _switchStream(long j, int i, int i2); public static final native void _takeScreenshot(long j);
下面两个都是该类下所有的
native 办法
,肉眼可见解体包的 native 代码显著比失常包的少;上文日志 1 中提到
Failed to register native method com.bykv.vk.component.ttvideo.player.TTPlayer._close(J)V
;查看解体包的 native 办法,果然没有此办法
public static final native void _close(long j);
;
前提是: 1、应用同一个工程打包 2、以上代码所依赖的是同一个版本的穿山甲广告 SDK 3、其中有一个模块版本不一样(作者本人的一个 library) 4、打的是 release 包
猜测: 如果是同一个版本的同一份代码,是否有可能是因为混同规定不同,或者抵触导致无用代码被移除,最终造成 native 办法注册失败呈现的解体?
那么接下来去看看打包输入的混同相干文件如何:
mapping.txt:源代码混同的映射表 seeds.txt:未被混同的类和成员 dump.txt:所有代码被解决后的残缺列表 usage.txt:被优化移除、删除的代码 【本文咱们重点关注这个】
3、混同剖析
咱们针对 com.bykv.vk.component.ttvideo.player.TTPlayer._close(J)V
native 办法进行剖析!!!
办法原型是:public static final native void _close(long j);
解体包
mapping.txt
没有发现 \_close(long j) 办法被混同
seeds.txt
没有发现 \_close(long j) 办法被保留
usage.txt
发现
\_close(long j) 办法被移除
除此之外,咱们还发现其余的 native 办法也被移除了!!! (下面有提到解体包的 native 办法比失常包的要少)
失常包
mapping.txt
没有发现 \_close(long j) 办法被混同
seeds.txt
发现
\_close(long j) 办法被保留
usage.txt
没有发现 \_close(long j) 办法被移除
显著了,剖析到这里看到了两个包混同之间的差异:大胆猜想是 native 办法没有找到,引起注册失败,导致解体。
有一点总结:native 办法不能被混同、移除。
4、最初
那么,在我的我的项目中如何解决就比较清楚了,增加混同规定,不移除、不会混同该 native 办法即可。
-keep class com.bykv.vk.** {*;}-keepclasseswithmembernames class * { native <methods>;}-keepclassmembers class com.bykv.vk.component.ttvideo.player.TTPlayer { *;}