C++类的实质是个结构体。先举个例:
class TestClass
{
int m_val1;
int m_val2;
public:
int getVal1();
int getVal2();
};
int TestClass::getVal1()
{
return m_val1;
}
int TestClass::getVal2()
{
return m_val2;
}
反编译两个函数,得到的是
int __cdecl TestClass__getVal1(int a1)
{
return *(_DWORD *)a1;
}
int __cdecl TestClass__getVal2(int a1)
{
return *(_DWORD *)(a1 + 4);
}
getVal1直接返回this指针的解引用,也就是m_val1的内存地址和实例对象是一致的,m_val2则是在m_val1的后一个int,所以是this指针+4字节。
如果类有虚函数,则与this指针同地址的是一个虚函数表,各个成员变量的偏移会+4。虚表的应用可看看《利用IDA和LLDB探索WebCore的C++类的继承关系》
明白以上这个原理,在反编译C++类的代码时,看见a1+x的地方就能猜出是在访问成员变量。
关于C++的反编译很多资料都有提及了,这里不赘述。除了《IDA Pro权威指南》那本书,推荐两篇文章:
逆向 C++-- 2 识别类下面说说Objective-C的。
在反汇编的窗口搜索(Alt+T)关键字 _objc_ivar
随意找到哪个,双击它,便会跳转到Objective-C类保存成员变量信息的区域,以__objc_ivar:开头的偏移段。
OC(Objective-C)这样做,主要是为了Key-Value Coding,方便了开发者,却也方便了逆向工程者,多了一些C++类没有的信息。
图中绿色的字符是代表相对偏移,即对于self指针的地址加上多少就是访问此成员变量,与上面C++类的概念相同。
对一些复杂类型的变量,还可以查找到它的类型信息。
例如在_OBJC_IVAR_$_UIView._gestureRecognizers上查看引用
选择以__objc_const开头的引用来跳转
这几行是ivar结构体的保存区域。
00000000 __objc2_ivar struc ; (sizeof=0x14) ; XREF: __objc_const:000054E8r
00000000 ; __objc_const:000054FCr ...
00000000 ptr dd ? ; offset
00000004 name dd ? ; offset
00000008 type dd ? ; offset
0000000C align dd ?
00000010 size dd ?
00000014 __objc2_ivar ends
第一行0x0075EE18处是变量偏移指针,第2行是变量的名字,第3行是type信息,可以看出UIView的成员变量_gestureRecognizers的类型是NSMutableArray*。第4到7行其实应该合起来占用4个字节,是align信息,这里的2表示以2字节对齐保存。第8到11行同属一个int,表示这个成员变量占4字节。
看到这,也就大概能明白class-dump的原理了吧。
本文请勿转载。