逆向工具vmmap的IOS实现

 

一、工具简介vmmap是苹果macOSX操作系统中的一个开发工具,此工具在安装了Xcode开发环境后就可以使...



一、工具简介

vmmap是苹果macOSX操作系统中的一个开发工具,此工具在安装了Xcode开发环境后就可以使用了。工具类似于linux下的/proc/pid/maps文件,主要用于分析展示程序在运行过程中的内存结构,加载的动态库信息(名称、基地址、大小),内存读写权限,内存使用量等等。在程序排错,性能调优,异常模块分析等方面发挥着极其重要的作用,对于开发人员特别是逆向开发人员来讲绝对是一个不可或缺的工具。下图是linux下的maps文件和macOSX下vmmap工具的内容对比截图。

cat /proc/self/maps



vmmap30183



二、移植原因

众所周知IOS操作系统并不开源,vmmap虽然是Xcode附带的一个工具,但Xcode只能运行在macOSX系统上,所以很不幸的是在IOS中并没有vmmap工具,这对于ios逆向人员来说分析内存结构会很麻烦,比如说查看一个app中加载了哪些模块。尽管现阶段苹果规定app中不可以引入第三方动态库和框架,但对于逆向人员来说注入动态库和框架是很平常的事。比如越狱后的手机如果安装了mobilesubstrate框架后,app在运行过程中就会被注入MobileSubstrate.dylib和SubstrateLoader.dylib两个动态库;再比如说越狱开发包theos开发的tweak类动态库,也是会被注入到指定的app进程当中的。所以移植(严格来说叫重实现)vmmap工具到IOS平台显得很重要。

三、IOS实现

参考mac下vmmap工具的输出信息,在IOS上实现了一个简化版的vmmap工具,如下图所示。



这个简化版的工具展示的内容更像是linux的maps文件,如下图所示。



下面着重分析一下代码实现。

1、struct定义

vmmap信息结构体定义如下



2、获取task对象

读取进程信息需要进程句柄,在IOS中即为mach_port_name_t或vm_map_t对象,由pid得到进程句柄对象由get_task_for_pid函数实现,实现代码如下:



3、获取region信息

ios中每个进程的虚拟内存被分割成若干个区块(region),调用vm_region函数可以遍历进程所有区块,获取所有区块信息并保存在map中的代码如下



4、获取dyld信息

动态链接器(dyld)中有一个__all_image_info的导出符号,此符号对应一个dyld_all_image_infos结构体,结构体保存了所有已经加载的动态库信息,获取结构体信息的代码如下:



5、获取image信息

通过第4步获取到的dyld_all_image_infos信息,可以拿到所有已加载动态库信息(每个动态库信息对应一个dyld_image_info结构),代码如下:



6、解析image信息

解析所有的dyld_image_info结构,将其转化为对应的vmmap_region_info结构,保存在map中。



7、获取vmmap信息

组合上面几个基本的功能函数调用,完整的获取虚拟内存信息的代码如下:



8、格式化prot信息



9、打印vmmap信息



10、main函数



四、结束语

上面就是iso上vmmap工具的一个简单实现,主要是读取区块信息及动态库的加载信息,虽然简单但应付一般的进程模块分析已经足够了。

通过亲自实现vmmap工具,可以更加深入的了解ios的内存结构,熟悉内核api的使用,对以后的逆向工作还是有不少的帮助。

本人在写这个工具之前也参考过网上的一些资料,也踩过不少的坑。这里提供一个github上实现vmmap工具的源代码地址(https://github.com/davidrhodus/misc/blob/master/iOS-internals/vmmap.c),有兴趣的朋友可以参考下。

不过这份代码有一些错误,且它用到了一个DYLD_ALL_IMAGE_INFOS_OFFSET_OFFSET宏,但此宏定义在不同的开发头文件中并不总是被定义的,随着dyld的升级此宏很可能会无效(至少我使用的10.3版本的sdk中是不存在此宏的)。


    关注 同程研发中心


微信扫一扫关注公众号

0 个评论

要回复文章请先登录注册