符号化解析原理

最近研究了一下符号表解析的方法,这里记录一下。

一.获取偏移地址

这里先看一个崩溃的日志,如下:

崩溃日志
崩溃日志

如图,图1第7行,是对应工程名的一行,可以看到一共有3个数字

0x000000010516c414    //运行时的内存地址
0x102dc8000           //运行时的起始地址
37372948(0x23A4414)   //偏移地址
上面3个数字, 0x000000010516c414 = 0x102dc8000 + 37372948
这里,起始地址和内存地址都是运行是的,每次启动都会产生变化。
重要的是偏移地址37372948(0x23A4414),偏移地址是固定的。

二.确定符号表一致性

然后我们来说符号表文件,首页要确定符号表文件和崩溃日志是对应的,这里通过UUID来确定,崩溃日志的UUID就在图2的下面,符号表的UUID可以通过命令dwarfdump --uuid Your.app.dSYM获取。

UUID

三.读取符号表

这里使用MachOView打开符号表文件,这里我们使用的arm64架构,所以也以此架构来说明。首先查看__TEXTsegment的虚拟地址

TEXT

可以看到__TEXT的起始地址是0x0000000100000000,上面我们获取到的偏移地址是37372948(0x23A4414),相加,获得在代码段的虚拟地址为0x1023A4414

0x0000000100000000 + 37372948(0x23A4414) = 0x00000001023A4414

查找符号表,确定0x1023A4414所在位置

函数虚拟内存地址

查找得到0x1023A42BB < 0x1023A4414 < 1023A4F68,所以可知,函数名为__ZL19CLSTerminateHandlerv,因为这个类因为是第三方的framework,不是源码依赖,所以这里显示的有些异常.

0x1023A4414

四、崩溃堆栈

last

Last Exception Backtrace部分,最后的异常堆栈,一样可以像上面一样解析。上图可知,我们image的运行时内存地址是0x102dc8000 ~ 0x109d9bfff,通过对比,异常堆栈中的内存地址0x10787dbdc(第6个), 0x108a160e8(第9个)等等都在上述区间,这里使用0x108a160e8来作为例子解说。

0x108a160e8  这个就是上面说的运行时的内存地址
0x102dc8000 ~ 0x109d9bfff   这个就是运行时的起始地址和结束地址,这里的起始地址和上面的是同一个,是因为上面我们看的也是同一个image。
所以这里可以算出偏移量:  0x108a160e8 - 0x102dc8000 = 0x5C4E0E8
使用偏移量+__TEXT虚拟地址:  0x0000000100000000 + 0x5C4E0E8 = 0x105C4E0E8

这里得到函数的虚拟地址为0x105C4E0E8,同上面一样,查询可得

0x105C4E0E8
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容