逆向工程中发现的__thiscall成员函数是否为类型转换函数?为何采用__thiscall调用约定?
拆解这个__thiscall成员函数:作用、调用约定与实际场景
先直接给你说透这个函数:
1. 这个函数到底是干啥的?
从IDA反编译的代码和原始汇编来看:
int __thiscall sub_40A490(void *this) { return *(_DWORD *)this; }
对应的汇编:
sub_ proc near mov eax, [ecx] retn sub_ endp
说白了这就是个类成员的getter方法——它的唯一作用就是返回调用它的对象(this指针指向的实例)里第一个DWORD类型的成员变量。
结合后面的调用代码来看,这个返回值应该是个计数器:你看代码里拿它和0比大小,还用来当循环的上限(++v3 >= sub_40A490(...)),大概率是某个容器类(比如自定义数组、链表)的元素数量,用来控制遍历的次数。
2. 为啥要用__thiscall调用约定?
这很好理解:__thiscall是MSVC下C++非静态成员函数的默认调用约定,它的最大特点就是用ecx寄存器传递this指针。哪怕这个函数逻辑再简单(只是取个成员变量),只要它是某个类的非静态成员方法,编译器就会生成__thiscall的代码。
你觉得它像“类型转换函数”,其实效果上确实有点像(把对象指针转成它第一个成员的数值),但本质上它是属于类的成员函数,必须遵循成员函数的调用规则,所以得用__thiscall来传递this指针——毕竟它得知道是哪个对象的成员要被读取对吧?
3. 结合调用代码看它的实际作用
看这段调用它的代码:
char __cdecl sub_4011B0(int a1, int a2) { char v2; // bl int v3; // esi _DWORD *v4; // eax int v5; // eax if ( !a1 || !a2 ) return 0; v2 = byte_593B70[4 * *(_DWORD *)(a1 + 504) + *(_DWORD *)(a2 + 504)]; if ( !v2 ) { v3 = 0; if ( sub_40A490((void *)(a1 + 1196)) > 0 ) { while ( 1 ) { v4 = (_DWORD *)sub_40A480(v3); v5 = sub_40A0E0(*v4); if ( v5 ) { if ( *(_DWORD *)(v5 + 44) == *(_DWORD *)(a2 + 44) ) return 1; } else { sub_4CE390(v3); } if ( ++v3 >= sub_40A490((void *)(a1 + 1196)) ) return 0; } } } return v2; }
这里a1应该是某个主类对象的指针,a1 + 1196是这个对象内部嵌套的一个容器类实例的指针。调用sub_40A490就是拿这个容器的元素总数:
- 先判断总数是否大于0,决定要不要进入遍历循环
- 循环里用
v3从0开始计数,直到v3超过总数就终止循环 - 每轮循环取出一个元素,检查它的某个成员(
v5+44的位置)和a2对象的对应成员是否匹配,匹配到就返回1,遍历完没匹配就返回0
所以这个sub_40A490就是容器类里的getElementCount()之类的方法,专门用来返回容器里的元素个数。
内容的提问来源于stack exchange,提问作者geo10
相关产品推荐
相关产品推荐

