解读Nativebridge对于houdin的支持

Genymotion Android 11 支持 Arm64 阅读详情

二、应用程序在加载so文件时的变化

原本功能是在javaVMExt::LoadNativeLibrary函数中实现的
(art\runtime\jin_internal.cc文件中):
该函数正常情况下使用dlopen打开so文件,但当x86系统试图打开arm版本的so ,返回错误时,这时就会使用NativeBridge自带的加载过程。

Created with Raphaël 2.2.0 开始 dlopen ? break NativeBridgeIsSupported ? NativeBridgeLoadLibrary FindSymbolWithNativeBridge 结束 yes no yes no
bool JavaVMExt::LoadNativeLibrary(const std::string& path,
                                  Handle<mirror::ClassLoader> class_loader,
                                  std::string* detail) {
  ......
  const char* path_str = path.empty() ? nullptr : path.c_str();
  void* handle = dlopen(path_str, RTLD_LAZY);
  bool needs_native_bridge = false;
  if (handle == nullptr) {
    if (android::NativeBridgeIsSupported(path_str)) {
      handle = android::NativeBridgeLoadLibrary(path_str, RTLD_LAZY);
      needs_native_bridge = true;
    }
  }
  ......
  bool created_library = false;
  {
    MutexLock mu(self, libraries_lock);
    library = libraries->Get(path);
    if (library == nullptr) {  // We won race to get libraries_lock
      library = new SharedLibrary(path, handle, class_loader.Get());
      libraries->Put(path, library);
      created_library = true;
    }
  }
  ......
  bool was_successful = false;
  void* sym = nullptr;
  if (UNLIKELY(needs_native_bridge)) {
    library->SetNeedsNativeBridge();
    sym = library->FindSymbolWithNativeBridge("JNI_OnLoad", nullptr);
  } else {
    sym = dlsym(handle, "JNI_OnLoad");
  }
  ......
}

android::NativeBridgeRuntimeCallbacks

android::NativeBridgeCallbacks全局变量

callbacks->isSupported
callbacks->loadLibrary(libpath, flag)
callbacks->getTrampoline

一、对于部分NativeBridge源代码的更改

添加链接描述

“ro.dalvik.vm.native.bridge” 指定动态链接库

  1. 有自己的数据目录,一般应用程序是有的,在/data/data/目录下。

如果决定要启用NativeBridge,则还需要调用android::PreInitializeNativeBridge对其做预初始化:

2)android.os.Build.SUPPORTED_ABIS,
更正过的

struct NativeBridgeCallbacks {
  // Version number of the interface.
  uint32_t version;
  bool (*initialize)(const NativeBridgeRuntimeCallbacks* runtime_cbs, const char* private_dir,
                     const char* instruction_set);
  void* (*loadLibrary)(const char* libpath, int flag);
  void* (*getTrampoline)(void* handle, const char* name, const char* shorty, uint32_t len);
  bool (*isSupported)(const char* libpath);
  const struct NativeBridgeRuntimeValues* (*getAppEnv)(const char* instruction_set);
  bool (*isCompatibleWith)(uint32_t bridge_version);
  NativeBridgeSignalHandlerFn (*getSignalHandler)(int signal);
};

多出两个函数一个叫做isCompatibleWith,一个叫做getSignalHandler。
3)persist.sys.nativebridge系统属性设置为1
4)ro.product.cpu.abilist系统属性
这个属性会控制特定版本的系统可以安装的app类型,为了是x86系统可以安装只包含arm指令集的apk,我没就需要更改这个属性。
ro.product.cpu.abilist=x86,armeabi-v7a,armeabi
ro.product.cpu.abilisit32=x86,armeabi-v7a,armeabi
5)ro.dalvik.vm.isa.arm系统属性(Android-X86系统中的build.prop)
ro.dalvik.vm.isa.arm=x86
ro.dalvik.vm.isa.=

其他更改部分

看了半天发现好像剩下的只剩使用指定程序打开某一类程序

而原始NativeBridgeCallbacks结构体的定义如下(代码位于system\core\include\nativebridge\native_bridge.h文件中):

struct NativeBridgeCallbacks {
  uint32_t version;
  bool (*initialize)(const NativeBridgeRuntimeCallbacks* runtime_cbs, const char* private_dir,
                     const char* instruction_set);
  void* (*loadLibrary)(const char* libpath, int flag);
  void* (*getTrampoline)(void* handle, const char* name, const char* shorty, uint32_t len);
  bool (*isSupported)(const char* libpath);
  const struct NativeBridgeRuntimeValues* (*getAppEnv)(const char* instruction_set);
};

但这里的实现却是在libnb.so里面,libnb.so里面的实现又是通过回调转到libhoudini.so。所以,这个所谓的nativebridge本质上就是实现以上几个接口后实现的功能。

system的native_bridge.cpp通过外部实现的这几个接口来传递编码转换的初始化函数。

总结:
libnb里面有7个回调接口,原本native_bridge.cpp里面只利用了5个,为了增加houdin我们利用增加的在native_bridge里面做了检查和信号处理。
getsignalHandler利用在这里调用这个函数的地方在这里(代码位于art\runtime\native_bridge_art_interface.cc文件中):

void InitializeNativeBridge(JNIEnv* env, const char* instruction_set) {
  if (android::InitializeNativeBridge(env, instruction_set)) {
    if (android::NativeBridgeGetVersion() >= 2U) {
#ifdef _NSIG
      for (int signal = 0; signal < _NSIG; ++signal) {
        android::NativeBridgeSignalHandlerFn fn = android::NativeBridgeGetSignalHandler(signal);
        if (fn != nullptr) {
          SetSpecialSignalHandlerFn(signal, fn);
        }
      }
#endif
    }
  }
}

最后函数就会利用getTrampoline跳到转化指令集里面执行。

不过有一点还不清楚,那就是绑定指定程序执行的操作有啥用。先不管了。

android 5.0 具体变化文件:
art/runtime/sigchainlib/sigchain_dummy.cc 、 sigchain.cc 、 sigchain.h
art/runtime/jni_internal.cc 、 native_bridge_art_interface.cc 、native_bridge_art_interaface.h

libnb.so位置      device/generic/common/nativebridge/
native_bridge.cc 位于、system/core/libnativebridge/native_bridge.cc

结果

经过对代码的不断跟踪和错误修正,最终结果如下:
在这里插入图片描述
我们这仅仅是编译了简单的jni函数,实现了native层的hello world但根据日志中显示加载文件为arm/libplthook-lib.so
可以看出我们成功的执行了arm指令下的so文件中的字符串转换。并且我们编译的程序so库中只包含arm指令,没有x86的so。感兴趣的同学可以自己试试。

并且,那个标定指令使用指定程序打开某一类程序
这一部分的东西并没什么卵用,因为我到这里根本没有设置相应的文件。

大功告成。

学习源码这么长时间,第一次添加自己的逻辑,感觉不错。哈哈哈哈

Android6.0中的NativeBridge 主要参考:http://blog.csdn.net/roland_sun/article/details/49688311 一文,换成了Android6.0的实现过程。从Android从5.0开始,在其ART虚拟机的实现中,引入了一个叫做NativeBridge的中间模块。这个模块基本上就是为了在JNI调用时进行动态转码用的,自带了基本上所有的处理逻辑。 首先,我们来看看NativeBridge的 阅读详情

相关推荐

Android NativeBridge过程分析

Art的NativeBridge使用hodini作为callback实际去加载类库 其中做了少量的一些操作 1 Zoygote fork应用进程的时候 frameworks/base/core/jni/com_android_internal_os_Zygote.cpp ForkAndSpecializeCommon函数 bool use_native_bridge = !is_system_server && (instructionSet != NULL) &&

woai110120130的专栏 889

Android runtime机制(二)zygote进程的启动流程

在这一章里,我们将继续跟进zygote进程的启动过程。在zygote进程启动过程中,虚拟机的创建、jni functions注册及java层ZygoteInit是我们需要关注和理解的,这有助于我们开发更加高效的Android程序。

Gory的专栏 3263

NbInjection:通过替换系统本机网桥支持来注入合子过程的PoC

Nb注入 这是一个替换系统属性“ ro.dalvik.vm.native.bridge”以注入合子进程的示例。 我已经在我的Google Pixel 3(Android 10,Magisk 20.4)上对其进行了测试,它似乎运行良好; 但是它可能不兼容所有设备,如果要使用它,请根据您的设备修改代码。 关于它的工作原理,您可以参考这篇中文。 建造 从Android Studio或命令行运行gradle task :module:assembleMagiskRelease ,magisk模块的zip文件将保存到module / build / outputs / magisk /中。 讨论 执照 麻省理工学院执照

用Docker跑Android系统,在x86电脑玩ARM手机游戏

ReDroid (Remote anDroid) 是自架「云手机」的方案,透过docker在电脑上跑Android系统容器,再利用Scrcpy的镜射萤幕功能连线到Android桌面。目前来看,ReDroid的泛用性比Waydroid好,因为不只造福Linux使用者,连那些想摆脱专有模拟器、想自架云手机的用户都可以利用ReDroid达成目的。目前即使有安装libndk,Android 11的Play商店还是不给下载ARM架构的APP,请配合APKPure之类的应用程式商店安装APP。ReDroid容器的。

blockish的专栏 2万+

SAP 对接CBS(http方式)

CLEAR:lv_xml_crc32_string. CONCATENATEcrc32_passwordcrc32_keyi_stringINTOlv_xml_crc32_string. CONDENSElv_xml_crc32_string. CALLFUNCTION'SCMS_STRING_TO_XSTRING' EXPORTING text=lv_xml_crc32_string encoding='8400' "GB...

3597

EGO-Planner文章解读(一)——论文原理和算法实现

详细解读egoplanner论文和代码

fegxg的博客 3989

android的native_bridge

开门见山。native_bridge就是让不同指令集能够运行。这里主要是在X86上跑ARM后续的均以android6.0为例在加载so文件的时候。最后调用到了art/runtime/java_vm_ext.cc当中的JavaVMExt::LoadNativeLibrary void* handle = dlopen(path_str, RTLD_NOW); bool needs_native...

groundhappy的专栏 5215

CZT与FFT频谱分析方法对比:从任意频带重采样到高精度频谱分析

M = 85 % 输出点数f0 = 70 Hz % 起始频率DELF = 0.4 Hz % 频率步长频率分辨率提高到0.4 Hz分析带宽聚焦在[70, 103.6]Hz更清晰地分辨出78Hz和82Hz的频率分量。

2403_88098319的博客 1859

Android-X86集成houdini所做的修改

Android-X86其实是基于Android的源码编译出来的一个X86版本,可以运行在X86系列处理器上。对于应用程序来说,如果全是使用Java语言编写的话,不会有什么问题。就算用到了JNI函数,如果编译出来了一个X86的动态库,并且包含在apk文件中,也不会有问题。要命就要命在有许多应用程序内部,只有ARM指令集的动态库,就不能在Android-X86平台下运行了,并且这类应用还不在少数。为了

Roland_Sun的专栏 2万+

【QGIS】利用“创建网格”功能实现区域等距分割与坐标转换实战

本文详细介绍了如何在QGIS中使用“创建网格”工具实现区域等距分割。通过实战演示,将北京市行政区划切割为150米正方形网格,并重点讲解了关键步骤:选择投影坐标系EPSG:3857以确保网格尺寸精确,以及将结果转换为常用的WGS84经纬度坐标。文章还涵盖了进阶技巧与常见问题解决方案,帮助用户高效完成空间网格化分析任务。

weixin_29232507的博客 95

ZYNQ PS裸机开发RS485

RS485 是一种通用的通信标准,广泛用于数据采集和控制应用中。它的主要优点之一是它允许将多个 RS485 设备放在同一条总线上,这使得多个节点可以相互连接。RS-485是美国电子工业协会(EIA)在1983年批准了一个新的平衡传输标准(balanced transmission standard),EIA一开始将RS(Recommended Standard)做为标准的前缀,不过后来为了便于识别标准的来源,已将RS改为EIA/TIA。

baidu_34971492的博客 831

用于Android ART虚拟机JNI调用的NativeBridge介绍

有一个项目叫做Android-X86,它是一个可以在X86平台上运行的Android系统。目前许多市面上销售的Intel Atom处理器的平板电脑,就是使用的这个系统。对于普通用Java代码编写的程序来说,理论上在Android-X86平台上运行是没有任何问题的。但是,如果你的程序包含JNI函数,并且还只用ARM编译器编译,那么在Android-X86系统上肯定跑不起来,X86处理器怎么可能会执行

Roland_Sun的专栏 1万+

人形机器人硬件电路设计入门

人形机器人属于。

blotemj.blog.youkuaiyun.com 229

Android原生模拟器运行ARM APP

Google原生模拟器运行ARM APPINSTALL_FAILED_NO_MATCHING_ABISGoogle原生APP安装微信(Android 6.0) INSTALL_FAILED_NO_MATCHING_ABIS 安装APK的时候出现这个错误,其实是当你试图安装一个具有本地库的应用程序时,它没有你的CPU架构的本地库。例如,如果您为armv7编译了一个应用程序,并试图将其安装在使用英特尔...

ALakers的博客 1万+

【逐函数讲解ORB_SLAM3源码】获取普通帧率、关键帧、IMU数据

获得imu的旋转 mRwc * mImuCalib.mTcb.rotationMatrix(); Sophus::SE3 mTwc 创建ORB_SLAM3系统 Create SLAM system. It initializes all system threads and gets ready to process frames. ORB_SLAM3::System SLAM(argv[1],argv[2],ORB_SLAM3::System::IMU_RGBD, true, 0, file_nam

小秋 AI SLAM 入门实战教程 1245

Unity中的Timeline

Timeline与动画系统类似,但是它可以针对多个物体做出一系列多个动画,它可以创建多个轨道,对象激活与隐藏轨道,动画轨道,声音轨道等。每个轨道都可以单独编辑,轨道内的不同资源可以排列并且融合

L的博客 1万+

Dalvik虚拟机简要介绍转载

转载来着老罗的http://blog.csdn.net/luoshengyang/ 博客, Android应用程序是运行在Dalvik虚拟机里面的,并且每一个应用程序对应有一个单独的Dalvik虚拟机实例。除了指令集和类文件格式不同,Dalvik虚拟机与Java虚拟机共享有差不多的特性,例如,它们都是解释执行,并且支持即时编译(JIT)、垃圾收集(GC)、Java本地方法调用(JNI)和Jav

2456

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

Android Zygote进程源码分析

一  app_process64 Zygote所对应的可执行文件是/system/bin/app_process64 Zygote的代码路径frameworks/base/cmds/app_process 1.0  app_process64 init.rc中import /init.${ro.zygote}.rc,而ro.zygote=zygote64_32 i

Android 6.0 源码学习 2213

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

Riru&Edxposed学习研究(一)手把手安装Edxposed

一、前期准备 测试手机设备准备环境: 手机型号:oneplus3 系统版本:Android10 手机提前刷入twrp recovery镜像。 关于如何刷twrp可以参考如下文章: 安卓10源码学习开发定制(2)刷机操作之Recovery刷机演示 Magisk刷机包准备: Magisk下载地址如下: https://github.com/topjohnwu/Magisk/releases 此处我选择Magisk v21.1版本,下载地址: https://github.com/t.

xiaomaNo01的专栏 9314

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

探索 NativeBridge:实现 Java 和原生代码之间的无缝通信

探索 NativeBridge:实现 Java 和原生代码之间的无缝通信 NativeBridge 是一个开源库,它为开发者提供了在 Java 应用程序中调用 C/C++ 原生代码的能力。这个工具的目标是简化 Java 与原生代码之间的交互过程,并且支持跨平台的编译和运行。 NativeBridge 的功能和应用场景 有了 NativeBridge,你可以: 轻松地在 Java 代码中调用 C/...

gitblog_00009的博客 550

NativeBridge:我在Pub上发布的第一个插件

坦白地说,在发布 native_bridge 之前,自己从没有想过会在 pub 上发布一款自己开发的 Flutter 插件。一方面是觉得自己水平有限,很难产出比较有实用价值的内容。虽然之前有写过 Plugin 开发相关的文章,但那也只是用来自我学习的 Demo,对大家来说没有太多的应用价值。另一方面也是因为对 pub 的发布流程非常陌生,尤其对大陆开发者来说还会遇到一些额外的问题。 而这次能够促使我去发布 NativeBridge 插件,主要还是之前的 NativeBridge 系列文章在掘金的受欢迎度较

bugyinyin的博客 274

Android x86的arm兼容库移植--初步分析及尝试手动移植houdini/ndk_translation

本文章对手动移植x86平台Android的arm兼容库提供一些思路,以及一些解释。

Rrex_的博客 5418

Android源码解析之loadLibrary() 的执行过程

转载自:http://gityuan.com/2017/03/26/load_library/ 重要参照(可惜格式原因,不然我想转这篇,该篇4.2.2):https://my.oschina.net/wolfcs/blog/129696 我想抱怨一句,为啥都快底层的东西了,都还老是变来变去啊…… 本文讲述的Android 6.0系统体系架构, 分析动态库的加载过程. lib

Tomes.V.White 2206

全栈开发核心技术 Native Bridge原理与实现

NativeBridge 现在的互联网项目需要哪些部分组成,比如淘宝,天猫,京东,微博,等等.我们会发现现阶段一个互联网项目它同时具有网页端,app甚至还有一个微信入口 现在很多项目都是使用NativeBridge技术来实现的,我们说的FaceBook的框架ReactNative以及著名的混合App框架PhoneGap等也是使用的类似NativeBridge原理. 京东的活动页面,点击进去,

caopeng26的专栏 2082

如何打开Android X86对houdini的支持

前面的文章中介绍了如何在VirtualBox虚拟机中安装Android X86。不过,安装结束后,试了几个只有ARM版.so文件的apk程序,发现都打不开。难道是新版Android X86动态将ARM指令集转成X86指令集的houdini兼容性有问题? 经过一番研究,发现默认情况下,其实Android X86是不带houdini的,也就是不能运行只有ARM版.so文件的程序。 不过,可以通过几

Roland_Sun的专栏 5万+

Capacitor Native Bridge详解:JavaScript与原生代码通信机制

在跨平台应用开发中,JavaScript(JS)与原生代码(Native Code)的通信是核心挑战。传统WebView仅能加载网页,而Capacitor通过**Native Bridge(原生桥接器)** 实现了JS与iOS/Android原生API的双向通信,让Web技术能调用摄像头、文件系统等设备能力。本文将深入解析Capacitor Native Bridge的架构设计、通信流程及关键技术...

gitblog_00897的博客 897
上一篇: Android X86上运行基于ARM">ARM处理器的应用程序
下一篇: android内核漏洞利用过程学习
inquisiter
博客等级 码龄10年 374粉丝 228原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值