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


相关推荐

  • FDD和TDD区别

    FDD和TDD区别转载链接:https://www.jianshu.com/p/496291b4aa2e

    2022年5月17日
    36
  • Django(62)自定义认证类「建议收藏」

    Django(62)自定义认证类「建议收藏」前言如果我们不用使用drf那套认证规则,我们想自定义认证类,那么我们首先要知道,drf本身是如何定义认证规则的,也就是要查看它的源码是如何写的源码分析源码的入口在APIView.py文件下的di

    2022年7月29日
    2
  • Java练手小程序——QQ聊天「建议收藏」

    Java练手小程序——QQ聊天「建议收藏」1.思路图    2.主要功能     实现一对一聊天实现多对多聊天好友上线自动刷新功能3.知识点   界面布局:一是流布局,二是卡片布局(现在应该都不用了) socket通信之对象流objectinput/outputStream     将线程里面的信息显示到界面上4.项目代码    4.1服务端 

    2022年9月6日
    3
  • LaTeX的下载安装及简易使用

    LaTeX的下载安装及简易使用前言毕业论文中需要使用Ctex来写,但是之前完全没有接触过这个软件,所以就打算记录一下自己的学习过程。本来打算自己写一下相关的一些东西,但是发现大佬们已经写得特别棒了,就把一些大佬写得东西的链接写出来,希望能帮到有需要的小伙伴们。1.关于LaTeX和CTeXLaTeX是一种基于ΤΕΧ的排版系统,由美国计算机学家莱斯利·兰伯特(LeslieLamport)在20世纪8…

    2022年4月28日
    50
  • pycharm2021专业版激活码【注册码】

    pycharm2021专业版激活码【注册码】,https://javaforall.net/100143.html。详细ieda激活码不妨到全栈程序员必看教程网一起来了解一下吧!

    2022年3月18日
    50
  • pycharm 编辑器_运行编辑器怎么运行

    pycharm 编辑器_运行编辑器怎么运行作为PyCharm编辑器的起步,我们理所当然的先写一个Helloword,并运行它。(此文献给对IDE不熟悉的初学者)1,新建一个项目File–>NewProject… 2,新建一个文件右键单击刚建好的helloWord项目,选择New–>PythonFile3,输入文件名输入文件名,

    2022年8月26日
    2

发表回复

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

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