1.函数的实现存储于_TEXT 段
包括 _TEXT (汇编源码) _TEXT,_text 、 _TEXT,_Stubs 段等
其中
_TEXT,_text存储的是本地源码
_TEXT,_Stubs 存储的是共享动态库源码
2. 函数的查找依赖符号表,符号表中存储了函数名、函数源码指针等信息。
符号表的位置
3. 符号表
符号表的数据结构
struct nlist_64 {
union {
uint32_t n_strx; /* 函数名在String Table中的偏移量*/
} n_un;
uint8_t n_type; /* 函数集合类型 */
uint8_t n_sect; /* 函数源码所在的section */
uint16_t n_desc; /* 描述信息一般空置 */
uint64_t n_value; /* 函数源码地址(函数指针)*/
};
3.1 符号表查找函数源码
去_Text,text 地址 1790查找对应的函数源码信息
ret 在汇编中相当于return 标志一个函数结束
3.2 符号表查找函数名
由于函数名的偏移地址是一个双层数据结构
union {
uint32_t n_strx; /* 函数名在String Table中的偏移量*/
} n_un;
所以无法直接看出
但是根据fishhook源码可知
//根据符号取得 字符串表(函数名)偏移量
uint32_t strtab_offset = symtab[symtab_index].n_un.n_strx; //可以直接在符号表中拿到符号
//取出 取得函数名 (带点)
char *symbol_name = strtab + strtab_offset;
- 1.函数名长度有长有短,所以函数名的计算方式是StringTable起始地址 + 偏移量
- 函数名字符串第一个字符串是"." 也就是函数名之间都是以"."分开的
4. 间接符号表
间接符号表中存储的是符号在符号表中的下标
从图上看,这个间接符号表貌似是存储了函数地址 section信息等,但是实际上只是0000087B-000007C 这个数据宽度只够存储一个下标。剩余的信息都是MachOView软件自动填充的
5 函数与方法的区别
函数与方法的区别如下:
函数是一段指定格式的汇编代码。
方法是一种特殊的函数。方法一般不接调用。是通过objc_msgsend调用。而objc_msgsend 的第一个入参即是对象。所以通常也可以说方法的调用是依赖对象的
方法的函数名为 -[类名 + 方法名]或者+[类名 + 方法名]
如图