【问题标题】:replace a function in a .so file替换 .so 文件中的函数
【发布时间】:2014-03-11 12:30:15
【问题描述】:

为什么: 我有一个 3 方 Android 共享库(无源)libxyz.so,dalvik vm 显示 JNI_OnLoad returned bad version (-1) infilepath。我假设 vm 是正确的,并且该函数确实返回了这个错误的值而不是一个有效的值。 (据我了解,直到现在这被忽略了,因为 debuggable 在 AndroidManifest.xml 中设置为 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

【问题讨论】:

  • 如果您可以转储 so 文件并共享 JNI_OnLoad 部分,可能有人可以向您展示如何修改。
  • 试试$ android-ndk-r9c/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/bin/arm-linux-androideabi-objdump -d libxyz.so | grep JNI_OnLoad -A 20
  • 说实话,我看不出-1可能来自哪里。
  • 23ddc: e3e00000 mvn r0, #0 23de0: e28dd00c add sp, sp, #12 23de4: e8bd8000 pop {pc}
  • 两件事:JNI_OnLoad 返回 ERR (-1),而不是错误的值,并且在它内部调用了一些其他函数。它实际上返回是因为第一个函数不返回 0。23dd4: e3500000 cmp r0, #0 23dd8: 0a000002 beq 23de8 &lt;JNI_OnLoad+0x48&gt;。您可以在这里以多种方式变得狂野,立即返回顶部,在第一个函数之后删除/禁用与 0 的比较。由你决定。但可能这些事情以后可能会让你重蹈覆辙。

标签: android gcc java-native-interface arm shared-libraries


【解决方案1】:

它是什么:

正如@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,但不知为何它对我不起作用。

【讨论】:

    【解决方案2】:

    虽然有一次我可以避免解决这个问题,但我又遇到了一次。

    这是我目前所拥有的:

    objcopy --rename-sym 不适用于.so。 (至少,现在是 2014 年。)

    JNI_OnLoad() 调用System.loadLibrary()System.load() 也不起作用(这些库报告为已在日志中加载,但它们的符号未出现),我没有尝试修复它。

    但是你可以 make two native shared libraries calling each other,所以你可以制作一个额外的库来定义感兴趣的函数,你(EDIT1:) 可以rename that function in the original binary library(你必须保留散列函数值),但你必须 load() em> 或 loadLibrary() 来自 Java 的新库。

    EDIT2:

    现在,我们如何扩展调用库的依赖列表?我们没有。在调用库的导入列表中,您可以找到一个可以重新编译和扩展的库,并在该库中定义重命名函数的新版本。如果您更改(就地)依赖列表中的库名称,则无需关心哈希函数和存储桶。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-07
      • 1970-01-01
      • 1970-01-01
      • 2015-02-14
      • 1970-01-01
      • 2021-09-04
      相关资源
      最近更新 更多