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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 分布式日志传输系统Databus(一)–系统介绍「建议收藏」

    分布式日志传输系统Databus(一)–系统介绍「建议收藏」Databus系统是微博DIP团队开源的分布式日志传输系统。它是一个分布式、高可用的,用于采集和移动大量日志数据的服务。它基于流式数据的简单而灵活的架构,具备健壮性和容错性,具有故障转移与恢复机制。它

    2022年7月2日
    22
  • Spring Data JPA 之 JpaRepository

    Spring Data JPA 之 JpaRepositoryJpaRepository是Spring提供的非常强大的基本接口。1JpaRepository1.1JpaRepository接口定义JpaRepository接口的官方定义如下:publicinterfaceJpaRepository<T,ID>extendsPagingAndSortingRepository<T,ID>,Q…

    2022年10月20日
    3
  • 【SQL基础-4】SQL语句练习实例—在SQLzoo平台练习

    目录1平台操作简介2select基本语句2.1第1节selectbasic2.2第1节练习3SELECTfromWORLD练习3.1第2节SELECTfromWORLDTutorial3.2第2节练习4SELECT_from_Nobel练习4.1第3节SELECT_from_Nobel_Tutorial4.2第3节练习5归纳参考文章1平台操作简介本节练习内容主要是该平台左侧红色框内共9节内容,包括对应9节练习。每一节内容和练习完成

    2022年4月13日
    60
  • Springmvc工作原理详解

    Springmvc工作原理详解关于三层架构和MVC我们的开发架构一般都是基于两种形式,一种是C/S架构,也就是客户端/服务器,另一种是B/S架构,也就是浏览器服务器。在JavaEE开发中,几乎全都是基于B/S架构的开发。那么在B/S架构中,系统标准的三层架构包括:表现层、业务层、持久层。三层架构在我们的实际开发中使用的非常多,所以我们课程中的案例也都是基于三层架构设计的。三层架构中,每一层各司其…

    2022年5月15日
    39
  • chrome加载慢_多线程有什么用

    chrome加载慢_多线程有什么用谷歌浏览器采用的是单线程下载,想要提高下载速度,就得采用多线程的下载方式,Chrome默认还是单线程下载,如果想要谷歌多线程下载,就要手动开启,下面听MacW小编娓娓道来,介绍如何开启Chrome多线程下载!先来看看开启前的下载速度,(同一个文件)看到了吧!默认情况下,只有左右,远没有到达带宽的上限,接下来跟着小编一起开启这个隐藏的功能,国产Chrome内核的浏览器通通适用,包括前段时间推送的新版Edge也可以。chrome://flags/#enable-parallel-downloading

    2022年10月8日
    3
  • python判断文件是否存在、不存在则创建_python判断文件是否存在,不存在就创建一个的实例…「建议收藏」

    python判断文件是否存在、不存在则创建_python判断文件是否存在,不存在就创建一个的实例…「建议收藏」python判断文件是否存在,不存在就创建一个的实例如下所示:try:f=open(“D:/1.txt”,’r’)f.close()exceptIOError:f=open(“D:/1.txt”,’w’)以上这篇python判断文件是否存在,不存在就创建一个的实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。时间:2019-02-17python中查找指定…

    2022年6月16日
    49

发表回复

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

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