Android readelf 工具查找函数符号

ELF(Executable and Linkable Format)是一种执行文件和可链接文件的格式。它是一种通用的二进制文件格式,用于在各种操作系统中存储可执行程序、共享库和内核模块。

Android 开发当中的 so 库本质上就是一种特殊类型的 ELF 文件,但在用途上它更专注于共享库的功能

so 库通常被设计为在程序运行时动态加载和链接,以提供代码、函数和数据等共享资源给其他程序使用。而可执行程序的 ELF 文件则是一个独立的程序,可以直接运行。因此,在使用方式和加载方式上有所不同,但它们都可以使用相同的 ELF 文件格式进行存储和组织。

readelf 是一个用于显示 ELF 文件的信息的工具,它可以显示 ELF 文件的各个部分的详细信息,例如头部信息、节(section)表、符号表、动态重定位表等。通过使用 readelf,开发者可以查看和分析 ELF 文件的结构和内容,以便了解和调试程序的执行过程。比如在进行 Native Hook 时,需要查看一个 so 库中的函数符号表,就可以使用这个工具进行查看。


在 Android 开发中,NDK 包中就已经包含了 readelf 工具了:

/AndroidSDK/ndk/21.0.6113669/toolchains/aarch64-linux-android-4.9/prebuilt/windows-x86_64/bin/aarch64-linux-android-readelf.exe

这是我电脑中 readelf 的路径,但我发现在 /toolchains/ 中有很多地方都有 readelf 文件且都能正常使用,把 readelf 配置一下环境变量就能正常使用了

使用命令来查看 so 库的节头表信息:

readelf -sW libxxx.so

libxxx.so 需要自行替换想要查看的 so库。但是把所有信息都输出到命令行实在是太多且难以查看,所以最好是输出到一个文件中方便我们来查找需要的信息:

readelf -sW libxxx.so > output.txt

这里我是把信息都输出到一个 txt 文件上了,然后在 txt 文件上直接搜索函数名就会出来对应的函数符号(因为函数符号是包含函数名的


举个例子:

在 C++ 文件中创建一个函数 readelf_native_funtion:

通过一些列操作编译成 so 库(gradle 配置 + Cmake 配置 + mergeReleaseNativeLibs)

然后在 build/intermediates/merged_native_libs/ 找到自己编译好的 so 库,运行 readelf 后打开 txt 文件:

就可以查询到函数 readelf_native_funtion 对应的函数符号是 _Z22readelf_native_funtionv

  • 11
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 根据C语言的编译规则,全局变量和函数都会被编译成ELF文件中的"GLOBAL"符号,而被标记为"static"或者"inline"的变量或函数则会被标记为"HIDDEN"符号。因此,readelf命令中显示的bind字段为GLOBAL的符号对外可见,而bind字段为HIDDEN的符号则对外不可见。所以,被标记为HIDDEN的函数在外部是不可见的,不能被其他的目标文件或库所引用。 ### 回答2: C语言中的readelf是一个用于查看ELF文件的工具,它可以解析ELF文件的不同部分,其中之一就是符号表。 符号表记录了函数、变量以及其他类型的符号ELF文件中的相关信息,包括名称、地址、大小、绑定(bind)和可见性(vis)等属性。 如果readelf符号表中显示bind为GLOBAL,vis为HIDDEN的函数,那么该函数对外是可见的。 bind属性指示符号的绑定类型,GLOBAL表示全局绑定,意味着该符号可以被其他模块或文件引用。因此,当bind为GLOBAL时,表示该函数可以被外部模块或文件访问和调用。 vis属性指示符号的可见性,HIDDEN表示该符号对外是隐藏的,即不可见的。但需要注意的是,HIDDEN仅在ELF文件内起作用,对外部的ELF文件或模块不起作用。 因此,当bind为GLOBAL,vis为HIDDEN时,该函数ELF文件内部可以被其他函数或模块访问和调用,但对于外部的ELF文件或模块而言,该函数是不可见的,不能引用。 总结起来,C语言readelf看到的符号表中bind为GLOBAL,vis为HIDDEN的函数对外是不可见的。 ### 回答3: C语言readelf看到的符号表中,bind为GLOBAL,vis为HIDDEN的函数对外可见。 在C语言中,符号表用于存储函数和变量等标识符的信息。其中,bind字段用于指示其可见范围,vis字段用于指示其外部可见性。 对于bind字段为GLOBAL的函数,表示其全局可见,即可以被其他源文件中的函数和变量所引用和调用,因此对外可见。 而vis字段为HIDDEN的函数,虽然其bind字段为GLOBAL,表示其全局可见,但vis字段为HIDDEN表示其外部不可见,即只能在当前编译单元(源文件)中被引用或调用,对外不可见。其他源文件无法使用该隐藏的函数,无法通过函数名进行调用。 因此,尽管bind字段为GLOBAL,但vis字段为HIDDEN的函数对外不可见。这意味着其他源文件无法直接使用该函数,而只能在当前源文件中使用。此类函数主要用于在当前源文件中共享和使用,而不会被外部其他代码访问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值