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)。

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

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

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • 百度编辑器ueditor

    百度编辑器ueditor

  • FileUpload文件上传控件「建议收藏」

    FileUpload文件上传控件「建议收藏」1.FileUpload控件的主要功能是向指定目录上传文件。FileUpload控件不会自动上传控件,而需要设置相关的事件处理程序,然后在程序中实现文件上传。2.FileUpload控件常见的属性

  • Java| 编译和反编译

    Java| 编译和反编译原文链接:http://www.yveshe.com/articles/2018/05/01/1525172129089.html什么是编程语言?在介绍编译和反编译之前,我们先来简单介绍下编程语言(ProgrammingLanguage)。编程语言(ProgrammingLanguage)分为低级语言(Low-levelLanguage)和高级语言(High-levelLa…

  • java微服务架构有哪些_漂浮服务区后端

    java微服务架构有哪些_漂浮服务区后端在本文中我们将主要研究目前主要的BaaS平台的功能,以及Google,Facebook,Apple等互联网巨头在BaaS领域的动作。同时我们也会关注国内一些主流BaaS平台的发展以及国内互联网巨头如百度,华为等在BaaS领域的投入发展。1.国外主流的BaaS平台 在BaaS领域,有几件事情值得关注:2013年4月,Facebook收购Parse;2013年12月,Paypal收…

  • 计算机-普林斯顿结构

    计算机-普林斯顿结构冯·诺伊曼结构,也称冯·诺伊曼模型或普林斯顿结构,是一种将程序指令存储器和数据存储器合并在一起的计算机设计概念结构。依据冯·诺伊曼结构设计出的计算机称做冯.诺依曼计算机,又称存储程序计算机。特点结构…

  • eclipse安装和配置环境教程(vue环境配置)

    官方下载地址:https://www.eclipse.org/downloads/电脑是64位的可以直接点下载64位,不是64位的电脑点下载包,在里面选择不同的版本下载点击下载后,浏览器会下载一个exe的安装包,但是下载完成后点击安装包会提示下载JDK;下载jdk官方网址:http://www.oracle.com/technetwork/java/javase/download…

发表回复

您的电子邮箱地址不会被公开。

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