静态搜索iOS动态链接函数的调用位置

静态搜索iOS动态链接函数的调用位置

可执行文件格式mach-O,是在苹果的操作系统 macOS 和 iOS 上使用的一种二进制文件格式。

在一些iOS安全扫描中,可能存在需要获取函数具体调用位置的需求,能指导用户更精确的定位漏洞。

现在以NSLog函数为例,用静态方式搜索macho中动态链接函数的具体调用位置。

目标

搜索应用macho中调用NSLog函数的具体位置。

思路

整个搜索过程,是一个解析macho文件的过程,把二进制数据解析为合适的数据结构。

用到了macho中多个部分:

String Table

Symbol Table

Dynamic Symbol Table

Section64(TEXT, stubs)

Section64(**TEXT,**text)

具体步骤

1、先找到Symbol Talbe 和 String Table在macho文件中的位置

在Load Commands中找到LC_SYMTAB,能确定StringTable的offset和size,也能找到Symbol Table的offset和Number:

Symbol Table Offset 是 0x18c478

Number of Symbols 是 0x9a2d

String Table offset 是 0x2273b0

String Table Size 是 0x108d58

因为每条symbol数据长度是16个字节,也就是0x10,

所以 Symbol Table 的 size 是 0x9a2d*0x10 = 0x9A2D0

Symbol Table起始地址是 0x18c478

结束地址是 0x18c478 + 0x9A2D0 = 0x226748

String Table 的起始地址是 0x2273b0

结束地址是 0x2273b0 + 0x108d58 = 0x330108

因为字符串的长度不固定,在String Table中的每条数据的长度不固定,

在读取二进制中的String Table数据时,可以用'\x00'作为字符串的分隔符。

2、遍历String Table,找到_NSLog

可以先读取macho中的String Table数据,用'\x00'作为分隔符,生成字符串数组,

遍历字符串数组,判断每条数据是否等于"_NSLog"。

在 0x23331b 位置找到了 _NSLog,机器码"5F4E534C6F6700"就是"_NSLog\n"字符串。

49003(16进制是 0xBF6B)是当前字符串的索引号,暂定为 strTab_index = 49003。

索引号49003是从String Table的起始地址 0x2273b0 开始计算,第49003个字节,

0x2273b0 + 49003 = 0x23331B,刚好是 _NSLog的起始地址。

3、根据步骤2中的49003(0xBF6B),可以在SymbolTable中搜索对应的符号

在MachOView中能看到地址 0x00224988 对应的就是 _NSLog。

如何通过索引号49003找到匹配的符号表数据呢?

在步骤1中已知:

Symbol Table起始地址是 0x18c478 ,

Symbol Table结束地址是 0x226748。

在这个macho中,单条Symbol Table的数据大小是0x10。

仔Symbol Table中第38993条数据的前四个字节的值是0xBF6B,也就是49003,

与String Table上_NSLog字符串的索引号相同,所以这条数据就对应"_NSLog":

38993是当前数据在Symbol Table中的索引号,暂定为 symTab_index = 38993,

0x18c478 + 38993 * 0x10 = 0x224988 正好是当前数据的地址。

4、在Dynamic Symbol Table中根据symTab_index查找数据

在Macho中的Load Commands下的 LC_DYSYMTAB 中能确定Indirect Symbols的位置:

起始地址:0x226748,有 794 条数据,每条数据大小是0x4。

遍历Indirect Symbols中的每一条数据,第111条数据中存储的是38993,

所以这条数据对应的就是"_NSLog",设置 dySymTab_index = 111

0x226748 + 111*0x4 = 0x226904

<a name="5、在 Section64(TEXT, stubs)节查找NSLog函数" class="reference-link">5、在 Section64(**TEXT,**stubs)节查找NSLog函数

在Mach-O文件中,Section64(TEXT, stubs)节存储的是用于进行间接跳转(indirect jumps)的存根(stubs)。这些存根是为了支持懒加载和符号解析的过程。具体来说,_stubs 节通常包含指向实际目标函数或符号的跳转指令。

在动态链接时,如果一个函数或符号的地址尚未被解析,链接器会在__stubs节中放置一个跳转指令,该指令在运行时会被替换为实际地址。这有助于在程序执行过程中进行动态解析和加载。

在Load Commands 中能找到 Section64(TEXT, stubs)节的信息:

offset 是 0xAE518

size 是 0xEE8

所以 Section64(TEXT, stubs)节的位置

起始地址是 0xAE518

结束地址是 0xAE518 + 0xEE8 = 0xAF400

每条数据长度是 0xC

解析Section64(TEXT, stubs)的二进制数据结构,每条数据大小是0xC,

因为步骤4中已知 dySymTab_index = 111,所以找到第111条数据:

0xAE518 + 111*0xC = 0xAEA4C

地址0xAEA4C 存储的是NSLog符号的跳转指令。

在Section64(**TEXT,**text)节中,凡是要调用NSLog函数,都会执行arm指令"bl #0xAEA4C"。

<a name="6、在 Section64(TEXT, text)节查找调用指令"bl #0xAEA4C"" class="reference-link">6、在 Section64(**TEXT,**text)节查找调用指令"bl #0xAEA4C"

在Load Commands 中能找到 Section64(TEXT, stubs)节的信息:

offset 是 0x5C64

size 是 0xA88B4

所以 Section64(TEXT, text)节的信息:

起始地址是 0x5C64

结束地址是 0x5C64 + 0xA88B4 = 0xAE518

查找到部分调用 NSLog 函数的指令:

使用Capstone库把Section64(TEXT, text)中的机器码反编译成arm汇编指令,

可以批量比较每一条指令是否是"bl #0xAEA4C",就能知道代码中调用NSLog函数的具体位置。

相关推荐
李玮豪Jimmy25 分钟前
MacOS 上安装 JDK 并实现多版本灵活切换
macos
mixboot30 分钟前
VoxCPM 1.5.0 macOS
macos·voxcpm
甜可儿32 分钟前
mac环境安装不同版本maven
java·macos·maven
bl4ckpe4ch38 分钟前
从零开始Mac OS 开荒整理笔记
笔记·macos·开荒
ipad协议开发1 小时前
企业微信iPad协议的开发进程
ios·企业微信·ipad
七月巫山晴1 小时前
【iOS】OC中的一些宏
前端·ios·objective-c
初级代码游戏11 小时前
iOS开发 SwiftUI Text的基本用法
ios·swiftui·swift
TheNextByte119 小时前
如何安全有效地清除iPad数据以便出售?
安全·ios·ipad
十二测试录20 小时前
Android和iOS测试区别
android·经验分享·ios·职场发展·ab测试
张飞签名上架1 天前
深耕全球市场:App上架iOS与Google Play全流程指南
macos·ios·cocoa·ios上架·上架·谷歌上架