WHY:
我有一个三方Android共享库(没有源代码),libxyz.so,而dalvik vm说JNI_OnLoad returned bad version (-1) in
filepath 。我假设vm是正确的,并且该函数确实返回了这个错误的值而不是有效的值。 (据我所知,直到现在这被忽略了,因为在AndroidManifest.xml中debuggable
设置为true。)
我如何用另一个.so库中的函数替换.so库中的函数?
(不确定我是否必须调用旧函数,在一般情况下是的,在我的情况下可能没有,但是如何调用旧函数的建议也将受到赞赏。)
00023da0 <JNI_OnLoad>:
23da0: e52de004 push {lr} ; (str lr, [sp, #-4]!)
23da4: e59f3094 ldr r3, [pc, #148] ; 23e40 <JNI_OnLoad+0xa0>
23da8: e24dd00c sub sp, sp, #12
23dac: e28d1008 add r1, sp, #8
23db0: e3a02000 mov r2, #0
23db4: e5212004 str r2, [r1, #-4]!
23db8: e08f3003 add r3, pc, r3
23dbc: e3a02801 mov r2, #65536 ; 0x10000
23dc0: e583000c str r0, [r3, #12]
23dc4: e2822004 add r2, r2, #4
23dc8: e5903000 ldr r3, [r0]
23dcc: e1a0e00f mov lr, pc
23dd0: e593f018 ldr pc, [r3, #24]
23dd4: e3500000 cmp r0, #0
23dd8: 0a000002 beq 23de8 <JNI_OnLoad+0x48>
23ddc: e3e00000 mvn r0, #0
23de0: e28dd00c add sp, sp, #12
23de4: e8bd8000 pop {pc}
23de8: e59d3004 ldr r3, [sp, #4]
23dec: e59f2050 ldr r2, [pc, #80] ; 23e44 <JNI_OnLoad+0xa4>
23df0: e1a00003 mov r0, r3
23df4: e79f1002 ldr r1, [pc, r2]
23df8: e5933000 ldr r3, [r3]
23dfc: e1a0e00f mov lr, pc
23e00: e593f018 ldr pc, [r3, #24]
23e04: e2501000 subs r1, r0, #0
23e08: 0afffff3 beq 23ddc <JNI_OnLoad+0x3c>
23e0c: e59d3004 ldr r3, [sp, #4]
23e10: e59f2030 ldr r2, [pc, #48] ; 23e48 <JNI_OnLoad+0xa8>
23e14: e1a00003 mov r0, r3
23e18: e593c000 ldr ip, [r3]
23e1c: e08f2002 add r2, pc, r2
23e20: e3a03033 mov r3, #51 ; 0x33
23e24: e1a0e00f mov lr, pc
23e28: e59cf35c ldr pc, [ip, #860] ; 0x35c
23e2c: e3500000 cmp r0, #0
23e30: a3a00801 movge r0, #65536 ; 0x10000
23e34: a2800004 addge r0, r0, #4
23e38: aaffffe8 bge 23de0 <JNI_OnLoad+0x40>
23e3c: eaffffe6 b 23ddc <JNI_OnLoad+0x3c>
23e40: 00103d6c andseq r3, r0, ip, ror #26
23e44: 00103204 andseq r3, r0, r4, lsl #4
23e48: 00103a84 andseq r3, r0, r4, lsl #21
答案 0 :(得分:0)
它是什么:
由于 @auselen 绝对正确写入,该函数无法初始化,因此返回-1。也就是说,它需要通过名称访问包含本机函数的类的一些内部类。
我使用了以下proguard法术:
-keep public class com.xyz.abc.XYZ
-keepclassmembers class com.xyz.adc.XYZ { *; }
-keep class com.xyz.abc.XYZ$* { *; }
非常感谢 @auselen !
编辑:同时,我再一次面临这样的问题。objcopy
有--redefine-sym
,但是为什么它对我不起作用。
答案 1 :(得分:0)
虽然在一个案例中我可以避免解决这个问题,但我再次面对它了。
这是我到目前为止所做的:
objcopy --rename-sym
不适用于.so
。 (至少现在是2014年。)
从System.loadLibrary()
调用System.load()
或JNI_OnLoad()
也不起作用(这些库报告为已加载到日志中,但它们的符号未显示),我没有尝试修复它
但你可以 make two native shared libraries calling each other,所以你可以创建一个额外的库来定义感兴趣的函数,你(EDIT1 :)可以rename that function in the original binary library(你必须保留哈希函数值),但你必须加载()或 loadLibrary()来自Java的新库。
EDIT2:
现在,我们如何扩展调用库的依赖列表?我们没有。在调用库的导入列表中,您可以找到可以重新编译和扩展的库,并在该库中定义重命名函数的新版本。如果在依赖项列表中更改(就地)库名称,则无需关心哈希函数和存储桶。