但是就如此简单的内容为何会单独列一章呢,因为在移植过程中会遇到一个问题: /lib/libstdc++.so.6: version `GLIBCXX_3.4.11′ not found (required...by /lib/libopencv_core.so.3.4) 解决方法: 1.在ubuntu中使用 find / -name "libstdc++.so*" 会出现好多文件,但是我们移植的时候需要注意...rm -rf libstdc++.so.6 将默认库的软连接指向最新动态库 ln -s libstdc++.so.6.0.19 libstdc++.so.6 检查动态库 strings libstdc+...+.so.6 | grep GLIBC 注意:如果移植成x86-64版本的libstdc++.so.6.0.21会出现下面的错误 error while loading shared libraries...: libstdc++.so.6: wrong ELF class: ELFCLASS64 原因是开发板运行ARM版本的,结果使用的是x86-64版本的。
EI_CLASS Offset: 4 (EI_CLASS) Length: 1 Type: Number 判断 ELF 文件是 32位的 还是 64位的。...常量定义: ELFCLASSNONE = 0:无定义【非法】 ELFCLASS32 = 1:32位 ELFCLASS64 = 2:64位 ELFCLASSNUM = 3:未知【非法】 在Android...若32位的指令集遇到64位的SO库, 会输出错误 “is 64-bit instead of 32-bit”, 并APP闪退; 若32位的指令集遇到64位的SO库, 会输出错误 “is 32-bit instead...of 64-bit”, 并APP闪退; 若出现非法的 ELFCLASS, 会输出错误 “has unknown ELF class: ?”...Android 时,读取段表依靠视图,使用的是 e_phoff,而非 e_shoff, 因此可以随意修改。
Archlinux安装scrcpy加载共享库出错 在安装scrcpy时通过sudo pacman -S scrcpy顺利安装,但是运行报错 scrcpy: error while loading shared...libraries: libusb-1.0.so.0: wrong ELF class: ELFCLASS32 这是在64位系统上运行32位库出错,我发现了这个10年的issue https://github.com...也就是说我们只需要运行sudo pacman -S libusb-compat 但是运行之后出现了新的问题 libusb-compat: 文件系统中已存在 /usr/lib/libusb-0.1.so...sudo rm -f /usr/lib/libusb-0.1.so.4 sudo rm -f /usr/lib/libusb-0.1.so.4.4.4 sudo rm -f /usr/lib/libusb...-0.1.so.4.4.4 sudo pacman -S libusb-compat 插上手机,运行scrcpy,成功运行
文件头描述了ELF文件很多重要信息,例如它运行的平台,支持的CPU类型等。使用命令行readelf -h 可以读取指定ELF文件的头部信息,如下图所示: ?...e_machine用于表明它运行的CPU类型,e_entry表示它被加载到内存后,第一条指令所在的虚拟地址,e_phoff表示程序表头相对于该文件内部偏移,后面我们要读取程序表头时需要使用该值。...该数据结构中有很多字段我们不需要关系,需要关心的也就是程序表头和段表头对应的字段,这些字段的使用在后续说明中会详细解读,我们首先展示如何使用python实现ELF文件头的解读,其中链接: https:/...= int.from_bytes(magic[4], "little") #32位还是64位 if elf_class == ELFCLASS32: print("class ELF32...") if elf_class == ELFCLASS64: print("class ELF64") endian = int.from_bytes(magic[5], "
/cmdTest a=10,b=0 Floating point exception (core dumped) 程序内容是在main函数中调用test,计算a/b的值,其中b的值为0,因此程序由于除...但是要特别注意的是,“瘦身”之后的elf文件由于没有了符号信息,许多调试命令将无法正常使用,出现core dump时,问题也较难定位,因此只建议在正式发布时对其进行“瘦身”。...7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 #elf文件魔数字 Class: ELF64...#1 0x000000000040052c in main (argc=1, argv=0x7ffca9536d38) at cmdTest.c:10 (gdb) 输入bt后,就可以看到调用栈了,出错位置在...(divide error)和出错位置(40053b),我们使用addr2line命令获取出错具体行号: addr2line -e cmdTest 40053b /home/hyb/practice/cmdTest.c
; ei_class ELFCLASS64 db 1 ; ei_data ELFDAA2LSB...时计算k表的值。...编写时需要代码尽量小,原则上时利用尽量短的代码,用到的一些trick: 取数据/存数据考虑使用lodsb/lodsw/lodsd,stosb/stosw/stosd这类短的指令 mov可以考虑换成xchg...db 2 ; ei_class ELFCLASS64 db 1 ; ei_data..." ; e_ident db 2 ; ei_class ELFCLASS64 db
Q4:如果程序跑在 64 位的 Zygote 进程上时,可以使用 32 位的 so 文件么,即应用的 primaryCpuAbi 为 arm64-v8a,那么是否可使用 armeabi-v7a 的 so.... //1.读取 elf 文件的 header 的 class 信息 int elf_class = header_.e_ident[EI_CLASS]; #if defined(__LP64_...= ELFCLASS64) { if (elf_class == ELFCLASS32) { DL_ERR("\"%s\" is 32-bit instead of 64-bit",...= ELFCLASS32) { if (elf_class == ELFCLASS64) { DL_ERR("\"%s\" is 64-bit instead of 32-bit",...abi 的 so 文件; 比如,当应用运行在 64 位进程中时,无法使用 32 位 abi 的 so 文件,同样,应用运行在 32 位进程中时,也无法使用 64 位 abi 的 so 文件; 参考资料
它的主要流程如下图所示: 可以看到它的核心原理是保留一段内存并且预先加载了一个备用的 kernel,在主 kernel 出现故障时跳转到备用 kernel,在备用 kernel 中把主 kernel...使用的内存和发生故障时的寄存器信息 dump 到一个磁盘文件中供后续分析。...准备 elf header (运行在 normal kernel) 在系统发生故障时状态是很不稳定的,时间也是很紧急的,所以我们在 normal kernel 中就尽可能早的把 /proc/vomcore...在 kexec_tools 使用 kexec_file_load() 系统调用加载 crash kernel 时,就顺带把 /proc/vmcore 的 elf header 需要的大部分数据准备好了:... + 1); memcpy(ehdr->e_ident, ELFMAG, SELFMAG); ehdr->e_ident[EI_CLASS] = ELFCLASS64; ehdr->e_ident
来源:公众号【编程珠玑】 作者:守望先生 网站:https://www.yanbinghu.com 前言 在Linux中,可执行文件的格式是ELF格式,而有一些命令可以帮助我们了解它们更多的“秘密”,以此来帮助我们解决问题...00 00 00 00 00 Class: ELF64 Data: 2's.../x86_64-linux-gnu/libc.so.6,而如果该文件不存在,则运行时将会出错。...为ELF文件瘦身 前面通过file查看文件时,看到有not stripped的字样,由于它里面包含了一些符号表信息,因为文件会稍大,如果去掉,二进制文件将会变小,但是里面的符号表信息也就没有了,将会影响问题定位...总结 ELF文件中隐藏了丰富的信息,只要使用得当,将会帮助我们更好地进行开发或者问题的定位。
orabm_query_cache.sql orabm_tab.sql orabm_user.sql 注意:缺省的orabm测试用用户会建立在tools.../orabmload Warehouse 1 ld.so.1: ..../orabmload: fatal: /opt/oracle/product/9.2.0/lib/libclntsh.so.9.0: wrong ELF class: ELFCLASS64 Killed
前者和后者通常情况下是独立存在的,是联合行动的,两者差异明显: 可执行文件有标准的 C 语言程序执行入口 main,而共享库则并没有这类强制要求 后者为了确保可以灵活被多个可执行文件共享,所以,符号地址在链接时是相对的...,在装载时动态分配和计算符号地址 接下来做个实验具体看看两者的区别,准备一个“烂大街”的 hello.c 先: #include int main(void) { printf...如果没有 -rdynamic,链接时就没法使用。...\n"); } 当普通共享库使用,默认编译即可,要能够执行的话,实现一下 entry(),编译时打开 EXEC_SHARED 即可: $ gcc -m32 -shared -fpic -o libhello.so...小结 本文详细讲解了如何像 libc.so 和 ld-linux.so 一样,既可以当共享库使用,还能直接执行,并且讲述了两种方法。
减少用户跨网访问,降低用户解析域名时延。...如果项目中用的网络库是okhttp,所有的网络请求都是通过它完成的话就可以使用okhttp提供的DNS解析接口,实现自己的DNS resolver,代码如下: public class HttpDns...getaddrinfo是在libc.so中的定义的,其它库如libandroid_runtime.so、libjavacore.so要使用这个函数的话,只能通过动态导入符号的形式,好在java网络库底层是就是通过这个方式实现的...找到libjavacore.so中getaddrinfo导入符号的位置: ? ? 定位到getaddrinfo在plt表中引用的位置: ?...解决方法是通过一个脚本,pull下测试设备上的所有so到主机上,然后用readelf工具查找so的导入符号,观察是否有getaddrinfo字样的导入符号。 为此我写了一个脚本,方便自动化进行。
在Linux下: 静态库:xxx.a 动态库:xxx.so 在windows下: 静态库:xxx.lib 动态库:xxx.dll 库的制作 动静态库中,要不要包含main函数?...向/etc/ld.so.conf/路径下添加配置文件 当动静态库同时存在时,可执行程序会链接哪个库呢?...像上面动静态库都存在,想链接静态库就需要使用-static ,但前提条件是静态库必须存在 gcc/g++默认使用动态库 在Linux系统下,默认情况安装的大部分库,默认都是优先安装动态库 库:应用程序...在一个大项目中,有许多的.c文件,如果不先编译成.o文件而是直接将.c文件经过编译器输出成可执行程序,那么当程序中某个.c文件出现问题时,就需要将出错的.c文件修改再将所有文件进行重新编译。...数据节与代码节分别会占用数个section size计算得出的是程序中几个数据节的大小 ELF从形成到加载轮廓 ELF形成可执⾏ step-1:将多份 C/C++ 源代码,翻译成为⽬标 .o文件+动静态库
本文介绍了一种在Art虚拟机上实时记录对象分配的实现方案,基于此方案就可以实现不合理对象分配的自动化的识别。...录制时对性能影响很小,但每次获取录制记录时特别慢(开发机实测JDWP封包5秒以上,解包处理10秒以上)。 每次获取到的记录可能有重复,要使用这个数据需要额外做合并去重的操作。...这是什么对象 你也许已经发现RecordAllocation还有一个参数是art::mirror::Class*,这是Java里Class在虚拟机里的镜像,我们知道Java里拿到Class,就能直接调用...我们应该用一种更通用的方法,那就是直接解析ELF 1.3 搜索函数地址 之 解析ELF so是一种ELF格式的文件,在Android系统里由linker加载到内存。...不过基址是系统加载so时记录的,这个应该不会有错;搜索出来的函数偏移和用IDA查看的函数偏移也是一致的。问题到底在哪?
常见的调查线上棘手问题方式大概如下: 以上两种方法在之前调查线上问题时都有使用,但因为二者都有明显的缺点,所以效果不是特别理想。...使用新的gJdwpOptions参数重新启动JDWP-Thread。 在Android中,JDWP相关代码分别被编译成libart.so(Art)和libdvm.so(Dalvik)。...修改或调用其他so库中的代码需要用到动态加载,使用动态加载,应用程序需要先指定要加载的库,然后将该库作为一个可执行程序来使用(即调用其中的函数)。...下面表格展示了这个完整的 API: 在介绍如何调用动态加载功能之前,先介绍一下C/C++编译器在编译目标文件时所进行的名字修饰(符号化)。...一般为了在应用发生崩溃时能获取到调用栈中每个函数对应的行号,需要保留LineNumberTable,同时为了减少包体积会放弃LocalVariableTable。
forward declare if you need to deference the structure members class a 是做了声明 并未定义(在使用之前) 例子4 只声明不定义...上面代码在a.cpp中书写,编译生成文件a.obj,没有问题。...但按照之前的说明,连接时将错误,因为找不到符号_ABC。...即:声明是给编译器用的,定义是给连接器用的 用类来举例 class A { long ABC( long a, long b ); //只声明,没有定义 在cpp中实现...我一般这样用:nm -D libxxx.so |grep T 2.ldd libxxx.so 查看依赖关系 3.readelf -a libxxxx.so 用来读取elf信息 我一般这样用
由于代码中用到了exp函数,它位于数学库libm.so或者libm.a中,因此编译时需要加上-lm。...: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 Class: ELF64 Data...01 03 00 00 00 00 00 00 00 00 Class: ELF64 Data:...Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 Class: ELF64...加载速度不一样 由于静态库在链接时就和可执行文件在一块了,而动态库在加载或者运行时才链接,因此,对于同样的程序,静态链接的要比动态链接加载更快。所以选择静态库还是动态库是空间和时间的考量。
ElfReader::Load 方法首先读取 SO 的elf header,再对elf header进行验证,之后读取program header,根据program header 计算 SO 需要的内存大小并分配相应的空间...将 program header 在内存中单独映射一份,用于解析program header 时临时使用,在 SO 装载到内存后,便会释放这块内存,转而使用装载后的 SO 中的program header...关于loadbias: SO 可以指定加载基址,但是 SO 指定的加载基址可能不是页对齐的,这种情况会导致实际映射地址和指定的加载地址有一个偏差,这个偏差便是 load_bias_,之后在针对虚拟地址进行计算时需要使用...计算 segment 在文件中的页对齐后的起始地址 file_page_start 和长度 file_length。...3.2.1 装载 还原后的 SO 在内存中,所以装载时的主要变化就是从文件装载到从内存装载。 Linker 在装载 PT_LAOD segment时,使用 SO 文件的描述符 fd: ?
大概包含编制好的计算机指令,数据,计算机在须要的时候把这个文件读取到内存中,cpu就能够从内存中一条一条的读取指令来运行了。...所以说想明确elf格式,我们应该了解一下计算机运行程序须要那些信息。所以这一节,我们补充一些计算机系统的基础知识。...事实上计算机的内存是没有那么大的,比方我们实际使用的计算机仅仅有2G,曾经更小,仅仅有几百M,并且一台计算机上不仅仅执行一个进程,一个占用4G,假设有10个进程,那就得着用40G了,哪有那么打的内存呢?...elf文件分三种类型: 1、目标文件(一般是.o); 2、可执行文件(我们的执行文件) 3、动态库(.so) 我们先讲一下可运行文件。...00 00 00 00 00 Class: ELF64 Data:
计算地址的精确方法是什么? 目标 ELF 使用的编译选项对 hook 有什么影响? hook 时遇到偶发的段错误时什么原因?如何处理? ELF 内部函数之间的调用能 hook 吗?...libtest.so的代码虽然看上去有些愚蠢,但是它居然可以正确的工作,那还有什么可抱怨的呢? 赶紧在新版APP中开始使用它吧!...计算 ELF 基地址。...问题分析: 读内存时发生段错误其实是无害的。 我在 hook 执行的流程中,需要直接通过计算内存地址的方式来写入数据的地方只有一处:即替换函数指针的最关键的那一行。...对于内部函数来说,比如一个使用static关键字修饰的函数,编译器在编译时,可能就直接把函数的地址“硬编码”在引用它的地方了。