从ndk编译,说到so文件结构以及ida导入、导出函数

2023-05-16

一、背景

一直以来对ndk的编译链接所依赖的文件没有完成弄明白,还有ida的导入、导出函数与dynsym section之间的关系是什么?

 

二、ndk编译所依赖的文件

1、我们一般在Application.mk中指定所需要的平台版本和编译后so的架构。

APP_PLATFORM := android-21
APP_ABI := armeabi-v7a

这个android-21对应什么呢?这是android ndk的根目录。

这里指定的编译so时,链接时需要的so文件,如果指定了android-21,那么链接时就到这个目录下寻找so。

2、下面看下Android.mk

LOCAL_PATH := $(call my-dir)
  
include $(CLEAR_VARS)  
  
LOCAL_MODULE    := lesson2
  
LOCAL_SRC_FILES := Lesson2.cpp MyTest.cpp module.c

LOCAL_LDLIBS    := -llog -ldl -lmediandk -lGLESv2

LOCAL_CPPFLAGS += -O3

LOCAL_CFLAGS += -fvisibility=hidden
        
include $(BUILD_SHARED_LIBRARY)

-lmediandk在链接时会使用android-ndk-r21/platforms/android-21/arch-arm/usr/lib/libmediandk.so

-lGLESv2在链接时会使用android-ndk-r21/platforms/android-21/arch-arm/usr/lib/libGLESv2.so

3、Lesson2.cpp

#include <media/NdkMediaDrm.h>
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>

在使用函数的地方还需要包含头文件,这些头文件在哪呢?

android-ndk-r21/sysroot/usr/include

4、使用的交叉编译工具

android-ndk-r21/toolchains/llvm/prebuilt/darwin-x86_64/bin

 

三、ida中Exports、Imports与dynsym之间的关系

arm-linux-androideabi-readelf -s liblesson2.so

Symbol table '.dynsym' contains 61 entries:
   Num:    Value  Size Type    Bind   Vis      Ndx Name
     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 00000000     0 FUNC    GLOBAL DEFAULT  UND __cxa_atexit@LIBC (2)
     2: 00000000     0 FUNC    GLOBAL DEFAULT  UND __cxa_finalize@LIBC (2)
     3: 00000000     0 FUNC    GLOBAL DEFAULT  UND AMediaDrm_createByUUID
     4: 00000000     0 FUNC    GLOBAL DEFAULT  UND dladdr@LIBC (3)
     5: 00000000     0 FUNC    GLOBAL DEFAULT  UND AMediaDrm_getPropertyByte
     6: 00000000     0 FUNC    GLOBAL DEFAULT  UND snprintf@LIBC (2)
     7: 00000000     0 FUNC    GLOBAL DEFAULT  UND _Znwj@LIBC_O (4)
     8: 00000000     0 FUNC    GLOBAL DEFAULT  UND __android_log_print
     9: 00000000     0 FUNC    GLOBAL DEFAULT  UND __stack_chk_fail@LIBC (2)
    10: 00000000     0 OBJECT  GLOBAL DEFAULT  UND __stack_chk_guard@LIBC (2)
    11: 00000000     0 FUNC    GLOBAL DEFAULT  UND __vsprintf_chk@LIBC (2)
    12: 00000000     0 FUNC    GLOBAL DEFAULT  UND gettimeofday@LIBC (2)
    13: 00000000     0 FUNC    GLOBAL DEFAULT  UND localtime@LIBC (2)
    14: 00000000     0 FUNC    GLOBAL DEFAULT  UND stat@LIBC (2)
    15: 00000000     0 FUNC    GLOBAL DEFAULT  UND strftime@LIBC (2)
    16: 00000000     0 FUNC    GLOBAL DEFAULT  UND time@LIBC (2)
    17: 00000000     0 FUNC    GLOBAL DEFAULT  UND vsnprintf@LIBC (2)
    18: 00000000     0 OBJECT  GLOBAL DEFAULT  UND __sF@LIBC (2)
    19: 00000000     0 FUNC    GLOBAL DEFAULT  UND abort@LIBC (2)
    20: 00000000     0 FUNC    GLOBAL DEFAULT  UND fflush@LIBC (2)
    21: 00000000     0 FUNC    GLOBAL DEFAULT  UND fprintf@LIBC (2)
    22: 00000000     0 FUNC    GLOBAL DEFAULT  UND __aeabi_memclr
    23: 00000000     0 FUNC    GLOBAL DEFAULT  UND __aeabi_memcpy
    24: 00000000     0 FUNC    GLOBAL DEFAULT  UND __gnu_Unwind_Find_exidx
    25: 00001e15    72 FUNC    GLOBAL DEFAULT   13 unw_set_reg
    26: 00001ed1     6 FUNC    GLOBAL DEFAULT   13 unw_step
    27: 00001f0d    28 FUNC    GLOBAL DEFAULT   13 unw_get_proc_name
    28: 00001f3b    12 FUNC    GLOBAL DEFAULT   13 unw_is_signal_frame
    29: 00001a75     8 FUNC    GLOBAL DEFAULT   13 __aeabi_unwind_cpp_pr0
    30: 00001abd   160 FUNC    GLOBAL DEFAULT   13 _Unwind_RaiseException
    31: 00001ed7    32 FUNC    GLOBAL DEFAULT   13 unw_get_proc_info
    32: 00001345   312 FUNC    GLOBAL DEFAULT   13 Java_com_example_ndkrever
    33: 00001aad     8 FUNC    GLOBAL DEFAULT   13 __aeabi_unwind_cpp_pr1
    34: 00001519    72 FUNC    GLOBAL DEFAULT   13 decode_eht_entry
    35: 00005004     0 NOTYPE  GLOBAL DEFAULT  ABS __bss_start
    36: 00001ab5     8 FUNC    GLOBAL DEFAULT   13 __aeabi_unwind_cpp_pr2
    37: 00001d99    72 FUNC    GLOBAL DEFAULT   13 unw_init_local
    38: 00005005     0 NOTYPE  GLOBAL DEFAULT  ABS _end
    39: 00001e5d    56 FUNC    GLOBAL DEFAULT   13 unw_get_fpreg
    40: 0000147d    36 FUNC    GLOBAL DEFAULT   13 JNI_OnLoad
    41: 00005004     0 NOTYPE  GLOBAL DEFAULT  ABS _edata
    42: 00001d15    52 FUNC    GLOBAL DEFAULT   13 _Unwind_GetRegionStart
    43: 00001561   616 FUNC    GLOBAL DEFAULT   13 _Unwind_VRS_Interpret
    44: 00001de1    52 FUNC    GLOBAL DEFAULT   13 unw_get_reg
    45: 00001925   336 FUNC    GLOBAL DEFAULT   13 _Unwind_VRS_Pop
    46: 00001875   176 FUNC    GLOBAL DEFAULT   13 _Unwind_VRS_Set
    47: 00001ef9    20 FUNC    GLOBAL DEFAULT   13 unw_resume
    48: 00001f47     6 FUNC    GLOBAL DEFAULT   13 unw_save_vfp_as_X
    49: 00001f35     6 FUNC    GLOBAL DEFAULT   13 unw_regname
    50: 00001231    80 FUNC    GLOBAL DEFAULT   13 _Z4testv
    51: 00001d49    12 FUNC    GLOBAL DEFAULT   13 _Unwind_DeleteException
    52: 00001d55    18 FUNC    GLOBAL DEFAULT   13 __gnu_unwind_frame
    53: 00001c75     2 FUNC    GLOBAL DEFAULT   13 _Unwind_Complete
    54: 00001d68     0 FUNC    GLOBAL DEFAULT   13 unw_getcontext
    55: 00001e95    60 FUNC    GLOBAL DEFAULT   13 unw_set_fpreg
    56: 00001f29    12 FUNC    GLOBAL DEFAULT   13 unw_is_fpreg
    57: 00001ce1    52 FUNC    GLOBAL DEFAULT   13 _Unwind_GetLanguageSpecif
    58: 00001c79   104 FUNC    GLOBAL DEFAULT   13 _Unwind_Resume
    59: 000017c9   172 FUNC    GLOBAL DEFAULT   13 _Unwind_VRS_Get
    60: 00005000     4 OBJECT  GLOBAL DEFAULT   21 unw_local_addr_space

ida Imports

ida Exports

ida Imports对应到dynsym,就是那些Value为00000000的符号。

ida Exports对应到dynsym,就是那些Value不为00000000的符号(个别_end没有放到ida的Exports中)。

使用arm-linux-androideabi-nm -D liblesson2.so,可以更加清楚和完整的看到函数名,和dynsym是一一对应的。

         U AMediaDrm_createByUUID
         U AMediaDrm_getPropertyByteArray
0000147c T JNI_OnLoad
00001344 T Java_com_example_ndkreverse2_Lesson2_main
00001c74 T _Unwind_Complete
00001d48 T _Unwind_DeleteException
00001ce0 T _Unwind_GetLanguageSpecificData
00001d14 T _Unwind_GetRegionStart
00001abc T _Unwind_RaiseException
00001c78 T _Unwind_Resume
000017c8 T _Unwind_VRS_Get
00001560 T _Unwind_VRS_Interpret
00001924 T _Unwind_VRS_Pop
00001874 T _Unwind_VRS_Set
00001230 T _Z4testv
         U _Znwj
         U __aeabi_memclr
         U __aeabi_memcpy
00001a74 T __aeabi_unwind_cpp_pr0
00001aac T __aeabi_unwind_cpp_pr1
00001ab4 T __aeabi_unwind_cpp_pr2
         U __android_log_print
00005004 A __bss_start
         U __cxa_atexit
         U __cxa_finalize
         U __gnu_Unwind_Find_exidx
00001d54 T __gnu_unwind_frame
         U __sF
         U __stack_chk_fail
         U __stack_chk_guard
         U __vsprintf_chk
00005004 A _edata
00005005 A _end
         U abort
00001518 T decode_eht_entry
         U dladdr
         U fflush
         U fprintf
         U gettimeofday
         U localtime
         U snprintf
         U stat
         U strftime
         U time
00001e5c T unw_get_fpreg
00001ed6 T unw_get_proc_info
00001f0c T unw_get_proc_name
00001de0 T unw_get_reg
00001d68 T unw_getcontext
00001d98 T unw_init_local
00001f28 T unw_is_fpreg
00001f3a T unw_is_signal_frame
00005000 D unw_local_addr_space
00001f34 T unw_regname
00001ef8 T unw_resume
00001f46 T unw_save_vfp_as_X
00001e94 T unw_set_fpreg
00001e14 T unw_set_reg
00001ed0 T unw_step
         U vsnprintf

这里面的U对应到ida的Imports里面,其他对应到ida的Exports里面。

注意有些大型的so,使用arm-linux-androideabi-nm -D 获取的信息是有重复的。比如_edata,__bss_start是重复的。还有些函数地址有两个名字,ida会智能标记上两个名字,但在ida Exports里面只有一份,这就是为什么arm-linux-androideabi-nm -D获取的行数大于ida Exports的原因。

 

四、so中.rel.dyn、.rel.plt、.plt、.got表

.rel.dyn、.rel.plt

00004f68  00000216 R_ARM_JUMP_SLOT   00000000   __cxa_finalize@LIBC
00004f6c  00000116 R_ARM_JUMP_SLOT   00000000   __cxa_atexit@LIBC
00004f70  00000e16 R_ARM_JUMP_SLOT   00000000   stat@LIBC
00004f74  00000816 R_ARM_JUMP_SLOT   00000000   __android_log_print
00004f78  00000916 R_ARM_JUMP_SLOT   00000000   __stack_chk_fail@LIBC

got表

在dlopen so时,会找到android_log_print的虚拟地址,然后根据.rel.dyn、.rel.plt提示的位置,写入got表。

在程序调用android_log_print是,首先会调用.plt,在.plt中得到刚才写入了got表中android_log_print的虚拟地址。然后跳转执行。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

从ndk编译,说到so文件结构以及ida导入、导出函数 的相关文章

  • Win10C盘文件夹内容详解(持续更新,欢迎留言)

    本文参考以下博客 Roaming和Local的区别 C Users 用户名 AppData 1 Local和Roaming之间的区别 xff1a Local 比较大 xff0c 非漫游应用数据 Roaming 一般是漫游应用数据 2 Roa
  • STM32运行FreeRTOS

    使用ARM Keil 的 Keil uVision IDE xff0c 在 STM32上运行 FreeRTOS 内核 物料清单 软件 在创建新项目之前 xff0c 我们必须安装软件包 下面是打印屏幕 xff0c 其中包含如何执行此操作的步骤
  • ESP32实践FreeRTOS

    将部分代码作为应用程序中的任务独立执行可以简化大型复杂问题的设计 当有多个 CPU 时 xff0c 任务支持还允许选定的功能并行运行 本文将调查 Arduino 框架对 ESP32 系列设备的 FreeRTOS 任务支持 除了少数例外 xf
  • 黑马程序员—5—Java基础:多态学习笔记和学习心得体会

    lt ahref 61 34 http www itheima com 34 target 61 34 blank 34 gt android 培训 lt a gt lt ahref 61 34 http www itheima com 3
  • 图像去噪算法简介

    一 xff0c 背景 随着各种数字仪器和数码产品的普及 xff0c 图像和视频已成为人类活动中最常用的信息载体 xff0c 它们包含着物体的大量信息 xff0c 成为人们获取外界原始信息的主要途径 然而在图像的获取 传输和存贮过程中常常会受
  • Android 7 Nougat 源码目录结构

    code style margin 0px auto font family none padding 0px color inherit background color transparent art Android Runtime x
  • 【无人驾驶规划】BOSS无人车规划算法

    无人驾驶规划 BOSS无人车规划算法 1 boss运动规划结构2 轨迹生成2 1 状态约束2 2 车辆模型2 3 控制参数化2 4 初始化轨迹2 5 轨迹优化 3 on road模式规划3 1 路径生成3 2 轨迹生成3 3 轨迹速度配置3
  • 这也太全面了 阿里王牌级“Docker全线笔记”,Github已标星80k+,我太爱

    写在开头 司汤达说过 xff1a 一个人只要强烈地坚持不懈地追求 xff0c 他就能达到目的 Docker的创始人Solomon Hykes就是以这样的精神 xff0c 在docker即将坚持不下去的时候 xff0c 选择的不是放弃 xff
  • 如何在keil5中新建.c和.h文件?

    有两种方法 xff1a 方法1 在keil5内部添加两个文件分别为 c和 h文件 xff0c 可以保存在一个新建的文件夹里 xff08 前提是此文件夹是在keil5内部保存时新建的文件夹 xff0c 而不是在keil5软件外自己新建的文件夹
  • CMake(十二):构建类型

    本章和下一章涉及两个密切相关的主题 构建类型 在某些IDE工具中也称为构建配置或构建方案 是一种高级控件 xff0c 它选择不同的编译器和链接器行为集 构建类型的操作是本章的主题 xff0c 而下一章将介绍控制编译器和链接器选项的更具体细节
  • CMake:构建、链接静态库和动态库

    CMake 构建 链接静态库和动态库 导言一 多目录多文件CMake构建方式1 项目结构2 message h3 message cpp4 hello world cpp5 CMakeLists txt6 构建及编译 二 静态库和动态库简介
  • msckf_mono构建运行方法

    背景 博主是在读Davide Scaramuzza投稿到ICRA 2018的VIO综述文章 A Benchmark Comparison of Monocular Visual Odometry Algorithms for Flying
  • IMU相关技术资料整理

    关于IMU噪声参数 xff1a IMU噪声参数模型的参考文档 xff1a https github com ethz asl kalibr wiki IMU Noise Model针对消费级IMU器件的噪声参数进行适度的不确定性放大 xff
  • Shell中空格引起的血案

    最近开始写点shell脚本 xff0c 对linux命令还是比较熟悉的 xff0c 但是shell脚本却没写过 xff0c 没想 xff0c 刚开始写 xff0c 就郁闷重重 各种语法错误 xff01 xff01 xff01 最简单的自定义
  • OpenCV-Python视频分析(移动物体检测,物体追踪)

    1 概述 该文章介绍OpenCV Python中关于视频分析的两个主要内容 xff0c 分别为 xff1a x1f41f 背景差分法移动物体检测 x1f41f Meanshift和Camshift算法物体追踪 PS xff1a 视频分析还要
  • 最新2014欢聚时代(YY)软件研发笔试题

    今天上午刚考完 C C 43 43 题目难度你们感受一下 xff01 总分80 43 60 61 140 题目上的答案请忽略
  • python 计算经纬度之间的距离

    def get distance lon1 lat1 lon2 lat2 lon1 lat1 lon2 lat2 61 map radians lon1 lat1 lon2 lat2 radians 角度转弧度 d lon 61 lon2
  • python多线程爬虫教学,清晰易懂。

    首先需要知道什么是多线程 xff0c 多线程的作用 首先举个例子 xff0c 并发和并行 xff1a 并发 xff1a 并发 xff0c 在操作系统中 xff0c 是指一个时间段中有几个程序都处于已启动运行到运行完毕之间 xff0c 且这几
  • Matlab 读取txt文本中的数据

    使用matlab读取txt文本中的数据 数据最好有一定的规律 我们可以使用函数importdata来导入数据 下面使用一个例子来说明该函数的使用 start path C 设置默认文件夹 filename pathname uigetfil
  • 2018-07-25-github-如何在Github上面创建Release

    github release 看别的Github项目都有一条类似timeline 时间线 的版本列表 xff0c 如下图 xff0c 所以在Github上面摸索了一下 xff0c 弄好了记录一下 创建一个Release TestBefore

随机推荐

  • SSH登录卡在‘Last login‘提示界面的一种原因

    以前解决过SSH登录卡顿的问题 xff0c 它一般来源于 xff1a GSSAPIAuthentication UseDNS 以上设置项被默认打开或意外打开 而这次遇到的问题不是卡顿 xff0c 而是卡在 Last login xff0c
  • 【云原生之Docker实战】使用Docker部署openwrt软路由

    云原生之Docker实战 使用Docker部署openwrt软路由 一 openwrt介绍 二 检查本地docker状态 1 查看docker版本 2 查看docker信息 3 查看本地docker网络 三 安装docker compose
  • 值得收藏:图解算法——动态规划系列

    个人博客导航页 xff08 点击右侧链接即可打开个人博客 xff09 xff1a 大牛带你入门技术栈 小浩 xff1a 宜信科技中心攻城狮一枚 xff0c 热爱算法 xff0c 热爱学习 xff0c 不拘泥于枯燥编程代码 xff0c 更喜欢
  • TensorFlow之循环神经网络&自然语言处理 学习总结

    作者 xff1a jliang https blog csdn net jliang3 junliang 20190303 说明 xff1a 以下所有代码使用版本TensorFlow1 4 0或1 12 0版本 import tensorf
  • Docker镜像容器的迁移问题

    本文是本人项目踩坑经验 xff0c 如有错漏请见谅 xff01 背景需求 xff1a 一个已经配置好的容器 xff08 无build文件 xff09 需要部署到生产环境中 xff0c 容器内有程序绑定了宿主环境的硬件信息 需求部署后能让第三
  • 视觉里程计1 高翔

    小白 xff08 我 xff09 本着学习 xff0c 提高自我 xff0c 增加知识的想法 xff0c 决定认真分析高翔博士slam 在此立下一个flag xff1a 每周进行知识总结 xff08 CSDN xff09 xff1b 每周要
  • InvokeHelper函数的用法

    ActiveX控件的方法和属性操作与生成的C 43 43 类成员函数相关联都是通过InvokeHelper函数的调用来完成的 xff0c InvokeHelper函数的第一个参数是由Component Gallery xff08 控件提供者
  • 前向声明! struct netif; —— 只声明,无具体内部细节

    今天在看到 Linux阅码场 的 宋宝华 xff1a Linux内核编程广泛使用的前向声明 Forward Declaration xff0c 非常感谢 xff01 前向声明 编程定律 先强调一点 xff1a 在一切可能的场景 xff0c
  • MCU初始化流程——从上电到main()之间

    说明 xff1a 以下介绍示例的MCU地址空间如下 xff1a ROM空间为 xff1a 0x0000 0000 0x0000 8000 RAM空间为 xff1a 0x2000 0000 0x2000 2000 堆栈 SP 生长方向为 递减
  • FreeRTOS 启动第一个任务 prvStartFirstTask vPortSVCHandler

    asm void prvStartFirstTask void asm void prvStartFirstTask void PRESERVE8 Use the NVIC offset register to locate the sta
  • 组播知识 - IGMP

    https zhuanlan zhihu com p 258619129 组播初识 一 为什么要启用组播 xff1f 1 节省不必要的数据发送 2 需要发送相同的数据去往多个不同的接收者 3 减少带宽的占用 4 优化网络设备的处理进程 5
  • copy_from_user函数详细分析

    copy from user函数的目的是从用户空间拷贝数据到内核空间 xff0c 失败返回没有被拷贝的字节数 xff0c 成功返回0 这么简单的一个函数却含盖了许多关于内核方面的知识 比如内核关于异常出错的处理 从用户空间拷贝数据到内核中时
  • linux驱动中的宏 _IOC_NR, _IOC_TYPE, _IOC_SIZE, _IOC_DIR

    转载自 xff1a http blog csdn net u010245383 article details 29391805 虽然排版都点点乱 xff0c 但是内容还是较全面的 在驱动程序里 xff0c ioctl 函数上传送的变量 c
  • 【转载】更进一步的了解Keil Flash的下载算法

    转载自 xff1a https jingyan baidu com article 414eccf64f03be6b431f0af8 html 前面提到了通用算法的选择 xff0c 那么问题来了 xff0c 这个算法文件如何来的呢 xff1
  • 自己动手写操作系统-经典书籍

    汇编语言 xff0c 王爽编写 王爽老师这本书 xff0c 绝对是经典中的经典 xff0c 比其他介绍汇编语言的书强很多 这本书以例子贯穿整本书 不像其他书罗列一堆指令 这本书只介绍了常用指令 xff0c 而且每个指令都有例子 xff0c
  • golang 闭包 函数作为参数和返回值

    一 函数闭包 package main import 34 fmt 34 func adder func int int 函数作为返回值 sum 61 0 自由变量 xff0c 每次调用都保留上次的结果 return func v int
  • go routine channel select

    一 go routine channel package main import 34 fmt 34 34 time 34 func worker id int c chan int for n 61 range c 读取channel f
  • 我的vimrc配置文件

    34 vundle begin set nocompatible 34 与vi不一致 filetype off filetype plugin on 34 检测插件 set rtp 43 61 vim bundle vundle 34 载入
  • extern C 透彻理解

    一 背景 一直以来对extern C的理解都停留在表面 xff0c 只知道为了C C 43 43 混合编程 今天来透彻理解下这个概念 二 整体的项目结构 jni Android mk LOCAL PATH 61 call my dir in
  • 从ndk编译,说到so文件结构以及ida导入、导出函数

    一 背景 一直以来对ndk的编译链接所依赖的文件没有完成弄明白 xff0c 还有ida的导入 导出函数与dynsym section之间的关系是什么 xff1f 二 ndk编译所依赖的文件 1 我们一般在Application mk中指定所