交叉引用cross reference是指 这个地址的 数据或代码 引用了哪个地址 以及 被哪些地址的代码所引用。引用了哪个地址,在反汇编就能看出来,一行汇编代码自然只会引用一个地址。但被引用是一对多的关系,正如一个函数可以被很多函数在内部调用。查看“被引用”是静态分析中得到堆栈的方法,当然,因为一对多的关系,还需要猜。这主要是看分析的目的是什么,与运行时动态分析相比各有好处,静态分析能得到完整的调用关系图。
在IDA里,cross reference也会缩写成XREF。
XREF主要是两种,数据引用和代码引用,只要看见有分号注释的 XREF 的地方,把鼠标悬停上去,都能看到部分交叉引用的代码。如果被引用的地方有很多,还可以通过快捷键Ctrl+X或菜单,得到更完整的交叉引用信息。例如在图中的Data XREF右键单击,弹出菜单:
选择Jump to cross reference,弹出对话框:
可以看到它被9个位置的代码引用。选中其中一条点击ok,即会跳转到那个地址。
由于Objective-C是一种弱类型语言,各种函数和成员变量都可以用字符串获取得到,开发者以实际为字符串的selector来调用函数,会令静态分析的引用分析变得复杂。下面做一个演示。
通过class-dump或xdb,可以知道UIView有这样一个私有API。
- (void)_addSubview:(id)arg1 positioned:(int)arg2 relativeTo:(id)arg3
现在去IDA里搜索,由于category的可能存在,一般搜索一个类的具体某个函数时,关键字是不带类名的,这个函数在IDA中的表示是
来搜索,有重复的就search again,直到找到是UIView的函数。它的反汇编代码头部信息为:
__text:00059DAC ; =============== S U B R O U T I N E =======================================
__text:00059DAC
__text:00059DAC ; Attributes: bp-based frame
__text:00059DAC
__text:00059DAC __UIView_Internal___addSubview_positioned_relativeTo__ proc near
__text:00059DAC ; DATA XREF: __objc_const:0075DBE4o
想知道哪些函数会调用这个函数,很自然想到在上面的DATA XREF处查看。可是,00059DAC这个位置实际只是Objective-C运行时实现中的IMP,即函数实现地址(具体请查看xcode文档)。开发者通过selector的方式调用函数,直接引用的是selector,而不会直接引用到IMP。 编译过程中,selector本身的字符串会被一个method对应,method再对应IMP,反编译的搜索过程就是它的反过程。
在00059DAC处查看XREF,得到:
跳转后,发现一堆的字符串:
这三行其实Method结构体的所有成员。
00000000 __objc2_meth struc ; (sizeof=0xC) ; XREF: __objc_const:000050C0r
00000000 ; __objc_const:000050CCr ...
00000000 name DCD ? ; offset
00000004 types DCD ? ; offset
00000008 imp DCD ? ; offset
0000000C __objc2_meth ends
第一行是字符串的起始地址,name,即源码中以@selector()括起来的字符串。第二行是对selector中参数类型的描述,Type encode请参考《利用Objective-C运行时hook函数的三种方法》,class-dump估计就是靠这些types信息确定各个selector的参数类型。第三行是IMP,所以上面的XREF会jump到这里来。
因为是selector对应字符串,所以要在0075DBDC处继续查看XREF。这是个字符串指针,所以是操作数,与函数的交叉引用稍有不同,右键单击,弹出菜单:
选择Jump to xref to operand。这里也有提示,快捷键是X,不是函数交叉引用的Ctrl+X,他们的区别是后者弹出来的是非模态对话框,X弹出来的是模态的:
这里会发现有三个引用,前两个是普通的引用,最后一个,可以看到IDA分析出是 __objc_selrefs,即有selector对此字符串做引用,所以需要选择__objc_selrefs处的引用,跳转过去:
如果做重命名多了,会发现这个地方的代码格式很熟悉,因为这里就是程序selector的放置区域,双击反汇编代码中默认命名的selector如off_XXXX就会来到这。
在DATA XREF上查看:
会发现非常多的引用,这些引用才是会最终调用到00059DAC的函数。
从上表也可看出,UIView的addSubview:,insertSubview:atIndex:,insertSubview:aboveSubview:等许多公开接口实际都会调用这个私有API。
上一篇:IDA反汇编/反编译静态分析iOS模拟器程序(五)F5反编译
下一篇:IDA反汇编/反编译静态分析iOS模拟器程序(七)识别类的信息
本文请勿转载。