在Linux桌面上运行Android NDK二进制文件

问题描述:

我从Play商店下载了包含本机代码二进制文件的APK。在APK文件中有一个lib/x86文件夹,该文件夹可能包含一个包含本机过程的库文件,通常是.so扩展名。由于代码在x86中,是否可以编写Java程序来调用桌面上的库?即使你没有该库的源代码。 NDK函数只需接受参数并返回一个值。例如,我们可以写在Linux桌面上运行Android NDK二进制文件

class AppNativeLoader 
{ 
    public static native void generateRand(int seed); 

    static 
    { 
     System.loadLibrary("AndroidNDKLib"); 
    } 
} 

public class WCallTest 
{ 
    public static void main(String[ ] args) 
    { 
     long seed = System.currentTimeMillis(); 

     if(args.length > 0) { 
      seed = Long.valueOf(args[0]); 
     } 

     long rand = AppNativeLoader.generateRand(seed); 

     System.out.println(rand); 
    } 
} 

注意:这只是一个示例。实际环境不同。在RHEL上使用JRE 7时,我提取了x86 .so并将其放在与.class文件相同的目录中。我仍然收到UnSatisfiedLinkerError。有什么不妥?假设没有回调,并且该功能没有使用Android API,这可能吗?

编辑:我临开的lib在IDA,我看到了以下相关

.plt:0000B100 ; Needed Library 'liblog.so' 
.plt:0000B100 ; Needed Library 'libz.so' 
.plt:0000B100 ; Needed Library 'libc.so' 
.plt:0000B100 ; Needed Library 'libm.so' 
.plt:0000B100 ; Needed Library 'libstdc++.so' 
.plt:0000B100 ; Needed Library 'libdl.so' 

这些应该是在我的桌面环境的,不是吗?

并非所有的Linux环境都是相同的(即使跨越分布边界也不能保证正常工作)。 NDK二进制文件是针对Bionic和其他一些特定于Android的库构建的,而您的RedHat系统使用glibc和RedHat存储库中提供的其他一些内容。

tl; dr您无法在桌面Linux上运行Android二进制文件。

+0

那么为什么APK中提供了一个x86库?是不是Windows BlueStacks模拟器的工作原理?并且获取UnsastifiedLinkerError是不兼容的症状? – Nederealm

+0

我在IDA PRO中打开了库,我看到以下依赖关系.plt:0000B100;需要库'liblog.so' .plt:0000B100;需要库'libz.so' .plt:0000B100;需要的库'libc.so' .plt:0000B100;需要的库'libm.so' .plt:0000B100;需要库'libstdC++。so' .plt:0000B100;需要的库'libdl.so' – Nederealm

+0

因为有x86安卓设备。 –

你可以尝试从here下载所需的共享库(请确保选择正确的API版本和架构相匹配的NDK共享库的结构,找出哪些共享库,你需要,你可以简单地使用ldd) 。

然后,要轻松访问共享库公开的方法,可以使用jadx反编译应用程序的java代码,然后在JNI类中编写自己的代码。

然后,要编译你的java代码,你可以使用任何版本的JDK

然后,要执行它,你必须使用与NDK共享库的体系结构相匹配的版本JRE(在你的情况下,你必须下载32位JRE)。

但是,这并不能保证正常工作:我正在使用NDK共享库中的段错误,因为大多数NDK二进制文件被剥离,调试将成为一场噩梦。