Android so文件浅析「建议收藏」

Android so文件浅析「建议收藏」一.简述Android中的so文件是动态链接库,是二进制文件,即ELF文件。多用于NDK开发中。二.基础知识三.so文件格式解析so文件即ELF文件,是一个二进制文件,我们可以用UltraEdit打开查看。如下:上面有一处很明显看到,在so文件解析出来的头文件字段是ELF,也印证.so是一个ELF格式的问题。ELF文件…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

一. 简述
Android中的so文件是动态链接库,是二进制文件,即ELF文件。多用于NDK开发中。

二. 基础知识

三. so文件格式解析
so文件即ELF文件,是一个二进制文件,我们可以用UltraEdit打开查看。如下:
这里写图片描述
上面有一处很明显看到,在so文件解析出来的头文件字段是ELF,也印证.so是一个ELF格式的问题。
ELF文件中各个结构体的内容,我们可以看源码中如下路径:
platform/external/kernel-headers /original/uapi/linux/elf.h
这里写图片描述

下面来逐步解析这个ELF文件

1.  ELF 头部(32bit/64bit)

这里写图片描述
可以看到e_ident[EI_NIDENT] 这个就是ELF 魔术数字(ELF magic number)

几个字段需要关注下,在so加固中修改so会用到:
E_phoff:注释写的很明确,这是程序表头的偏移值;
E_shoff:段表头的偏移值;
E_shstrndx:

2. ELF 段头(32bit/64bit)

这里写图片描述
p_offset:段文件偏移
p_vaddr:段虚拟地址
p_paddr:段物理地址
p_filesz:段大小在文件中

 3. ELF 程序头(32bit/64bit)

这里写图片描述
4. 工具解析ELF
这边常用的是readelf,这个工具运行在linux下的。一般运行的时候readelf –help,就可
以看到命令可以带什么参数,参数的含义等,
这里写图片描述
以下列出常用的几个:
A. readelf –h xxx.so
查看elf的头部信息
这里写图片描述
B. readelf –S xxx.so
查看elf节头信息
这里写图片描述

C. readelf –l xxx.so
查看elf段头信息
这里写图片描述

四. so文件加载
1. 加载方法
so文件的加载有且仅有两种方式:一个是load(),另一个是loadLibrary()
这里写图片描述

A. load
void load (String filename)
这里写图片描述

这个方法其实是直接由库导出被调用,并不是加载动态库。方法中传参为是一个String类型,不过内容是有要求的,是要so文件的绝对路径,,比如说:/system/lib64/libc++.so 。

B. loadLibrary
void loadLibrary (String libname)
这里写图片描述
loadLibrary方法和load方法的区别主要在于传参,此方法的传参也是一个String类型的值,不过这个值也有要求:比如我们需要加载的是libc++.so文件,那么这个libname需要携程c++即可。因为代码中是有实现的,会在前缀加上lib,后缀加上.so。
代码实现路径:/dalvik/vm/native/java_lang_System.c  /dalvik/tree/vm/Native.c
这里写图片描述
这里写图片描述

2.  加载流程

A. Load的加载流程:

这里写图片描述

B. LoadLibrary的加载流程:

这里写图片描述

最终还是调用Runtime类中的doLoad()方法,后续的实现其实和load()方法的一致。


3.  加载中注意

A. 常见的错误:

a. 加载so文件的时候无权限
首先你要看下so文件的绝对路径的权限是什么?外卡路径是没有权限的。Android O上,
对于第三方的apk,一般so文件生成的nativeLibraryPath是在/data/app-lib/XXX/ 下的。

b. 加载so文件的时候文件不存在
请check路径下是否有so文件。

c. ELF had a bad magic number
这里是so文件损坏了,需要check损坏的原因做处理。

B. 目前常用的是使用loadLibrary来动态加载库文件。

五. 扩展知识
1. Android NDK开发
(1).环境搭建
Eclipse的环境搭建在网上很多可以搜搜。这边主要讲下AS的搭建。
A. 首先需要去下个NDK工具包(如果不下载,在创建jni目录的时候AS也会提示NDK not configured的,直接install也行的):
这里写图片描述

B. 在创建项目的时候新建一个jni目录,如下图:
这里写图片描述

C. 配置NDK的路径,如下图:
这里写图片描述
D. 配置Grade中的NDK,如下图:
这里写图片描述

如上步骤基本就已经对于NDK的配置环境搭建完成了,下面开始具体实现啦!

(2).简单案例
对于JNI技术来说:主要是在java中我们定义方法,而在C++中实现这个方法,最后再回到java中进行调用。

注意:
A.javah 命令的使用【附录1】
a.首先要确保本地的java环境变量配置ok,不然无法用javah命令
b.首先先进入到写的java的目录下,比如说:
C:\Users\XXX\AndroidStudioProjects\NDKDemo\app\src\main\java\r\demo\com\ndkdemo

然后终端中输入:javac JNIDemo.java

此时该目录下会生成JNIDemo.class。

c.最为关键的是.h文件的生成,
这里经常出现的错误为:错误: 找不到 ‘r.demo.com.ndkdemo.JNIDemo’ 的类文件。

给出一个方法:
cd C:\Users\XXX\AndroidStudioProjects\NDKDemo\app\src\main\java
javah –d ../jni r.demo.com.ndkdemo.JNIDemo

此时在/jni 目录下就会生成:r_demo_com_ndkdemo_JNIDemo.h

(3).JNI类型
看我们第二第二步生成的c++文件内容,如下:
这里写图片描述

这里看到方法为r_demo_com.ndkdemo_JNIDemo_setjni。这个名字的命名还是很有规律的,前面r_demo_com.ndkdemo 是你当前project的包名,JNIDemo是你java类名,setjni 是java类中具体的方法。
接着看方法中的参数:JNIEnv类型和jobject类型。
A. JNIEnv类型:这是一个指针,主要是对java端的代码进行操作,比如创建java类中的对象,调用java对象的方法等。
常用的函数有:NewObject 、NewString 、Get Field等
B. Jobject类型。

六.后续
【附录1】:
用法:
javah [options]
其中, [options] 包括:
-o 输出文件 (只能使用 -d 或 -o 之一)
-d


输出目录

-v -verbose 启用详细输出

-h –help -? 输出此消息

-version 输出版本信息

-jni 生成 JNI 样式的标头文件 (默认值)

-force 始终写入输出文件

-classpath 从中加载类的路径

-cp 从中加载类的路径

-bootclasspath 从中加载引导类的路径

是使用其全限定名称指定的
(例如, java.lang.Object)。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/191840.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • inputstream.read() 方法 乱码_InputStreamReader

    inputstream.read() 方法 乱码_InputStreamReadernewInputStreamReader(request.getInputStream(),“UTF-8”)引起了乱码,改为newInputStreamReader(newBufferedInputStream(request.getInputStream()))后解决了乱码问题针对这个乱码问题,在网上搜索后有以下3种情况[1]数据库表里面字符集设置错误[2]由于未加编码过滤器导致SpringMVC接收参数时造成的乱码[3]代码中涉及byte数组转换String时出现了问题一、解

    2022年9月26日
    4
  • Centos安装字体

    Centos安装字体

    2021年5月30日
    112
  • 模糊控制器matlab仿真_有关bp神经网络Matlab的书

    模糊控制器matlab仿真_有关bp神经网络Matlab的书以下多套系统源码:1、MATLAB二级倒立摆三级倒立摆(在MATLAB下的二级倒立摆、三级倒立摆的仿真。内有所有需要的m文件)2、倒立摆matlab代码3、神经网络倒立摆控制(利用matlab对倒立摆的仿真,效果十分不错)4、二级倒立摆模型(这是一个演示直线二级倒立摆的matlab运行模型,这个模型能够根据仿真数据动画演示出二级倒立摆的运动情况。)5、倒立摆源码(倒立摆源码程序,注释很详细,是学习倒立摆原理,PID算法很好的参考资料。代码书写规范,注释详细。)6、二级倒立摆神经网络控制7

    2022年8月18日
    6
  • 一步步学习SPD2010–第十章节–SP网站品牌化(12)–关键点

    一步步学习SPD2010–第十章节–SP网站品牌化(12)–关键点1.      SPD提供了许多工具帮助你管理CSS样式和文件2.      SPD使用一系列配置选项来决定它如何添加CSS标签到你的页面。3.      SPFoundation和SPServer主要的CSS是corev4.css。

    2022年6月21日
    27
  • java 中getmapping,在Java spring尝试使用@getmapping到API时返回空JSON[通俗易懂]

    我有一个带有记录器的@bean,该记录器返回它从JIRAAPI获得的JSON数据。我当前正在记录启动程序时的响应。现在我想开始在我的控制器中使用@getmapping,并想在localhost:8080/上执行GET请求时记录信息。这是Controller类中的@bean,我想将其更改为@getmapping@BeanpublicCommandLineRunnerrun(RestTempla…

    2022年4月12日
    227
  • OSPF路由协议_ospf协议是一种什么路由协议

    OSPF路由协议_ospf协议是一种什么路由协议OSPF:开放式最短路径优先协议无类别链路状态路由协议,组播更新224.0.0.5/6;跨层封装到三层,协议号89;基于拓扑工作,故更新量大—–需要结构化部署–区域划分、地址规划触发更新、每30min周期更新OSPF的数据包:Hello包DBD–数据库描述包LSR–链路状态请求LSU–链路状态更新携带各种LSALSack–链路状态确认状态机—-OSP…

    2025年6月25日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号