能力值:
( LV12,RANK:210 )
|
-
-
2 楼
//注释说明
003910A0 /> \55 push ebp ;保存前一个栈帧的基地址
003910A1 |. 8BEC mov ebp, esp ;开辟一个新的栈帧
003910A3 |. 81EC CC000000 sub esp, 0CC ;给新栈帧分配0xcc的栈空间
003910A9 |. 53 push ebx ;ebx入栈
003910AA |. 56 push esi ;esi入栈
003910AB |. 57 push edi ;edi入栈
003910AC |. 51 push ecx ;保存ecx,我想应该是面向对象中的this指针,因为下面要使用ecx作为计数器初始化栈帧空间,所以ecx内容必须先保存起来
003910AD |. 8DBD 34FFFFFF lea edi, dword ptr [ebp-CC] ;指向栈帧最上的地址
003910B3 |. B9 33000000 mov ecx, 33 ;因为分配了0xcc的栈空间/4=0x33次初始化
003910B8 |. B8 CCCCCCCC mov eax, CCCCCCCC ;初始化的内容为0xcccccccc即int3断点
003910BD |. F3:AB rep stos dword ptr es:[edi];初始化栈帧空间
003910BF |. 59 pop ecx ;this指针出栈
003910C0 |. 894D F8 mov dword ptr [ebp-8], ecx;保存this指针
003910C3 |. 8B45 F8 mov eax, dword ptr [ebp-8] ;eax=this指针
003910C6 |. 0FB640 30 movzx eax, byte ptr [eax+30] ;零扩展this指针+0x30的数据成员(应该是一个char类型类似的数据),反正占一个字节,并且是movzx,所以应该是无符号数的
003910CA |. 6BC0 18 imul eax, eax, 18 ;this指针+0x30的数据成员*0x18,将结果保存到eax中
003910CD |. 0345 F8 add eax, dword ptr [ebp-8] ;将this指针保存到eax中作为函数返回值。
003910D0 |. 5F pop edi
003910D1 |. 5E pop esi
003910D2 |. 5B pop ebx
003910D3 |. 8BE5 mov esp, ebp
003910D5 |. 5D pop ebp ;恢复栈空间
003910D6 \. C3 retn ;返回到调用函数的位置
通过分析得出此函数操作的是一个对象,同时此函数并无对对象的栈空间进行操作,所以此函数的返回值一定不是自定义对象,但是同时却修改了对象的0x30位置处的内容
因此,此函数多半是一个构造函数。
|
能力值:
( LV2,RANK:10 )
|
-
-
3 楼
参数是ecx,应该是一个结构体指针。
基本作用好像就是通过其中一个数据成员定位另一个数据成员。
返回值eax就是被定位的数据成员的指针。
|
能力值:
( LV2,RANK:10 )
|
-
-
4 楼
谢谢二位的回答。
还有两个问题没明白
第一是前面栈开了块空间,这个空间没有用吧?
第二是 通过this找偏移的这个过程.
003910C6 |. 0FB640 30 movzx eax, byte ptr [eax+30] ;零扩展this指针+0x30的数据成员(应该是一个char类型类似的数据),反正占一个字节,并且是movzx,所以应该是无符号数的
003910CA |. 6BC0 18 imul eax, eax, 18 ;this指针+0x30的数据成员*0x18,将结果保存到eax中
003910CD |. 0345 F8 add eax, dword ptr [ebp-8] ;将this指针保存到eax中作为函数返回值。
这里第二句,如上所说现在eax里应该是this的30偏移处.
eax = eax * 18这里怎么会以这样的方式来变化eax呢?这样变换后eax的值还会是this的偏移么?
第三句eax += ecx同样对这个eax现在的值不太理解
我跟的过程发现调此函数前ecx = A调完该函数eax = A。
很晕
|
能力值:
( LV2,RANK:10 )
|
-
-
5 楼
好牛啊。。
|
能力值:
( LV12,RANK:210 )
|
-
-
6 楼
[QUOTE=oldn;817106]谢谢二位的回答。
还有两个问题没明白
第一是前面栈开了块空间,这个空间没有用吧?
第二是 通过this找偏移的这个过程.
003910C6 |. 0FB640 30 movzx eax, byte ptr [eax+30] ;零扩展this指针+0x30的数据成员(应该是一...[/QUOTE]
第一个问题没明白你要问什么?
第二个问题,还是对this指针的理解,它始终指向当前对象的第一个数据成员,比如如下代码
class fuck
{
int a;
int b;
int c;
};
fuck test ;//则此时this指针指向变量a的内存地址,当要操作数据时直接使用this+offset即可定位其它数据成员
movzx eax, byte ptr [eax+30] //执行完后eax中将是对象的数据成员内容,而不在this指针了
|
能力值:
( LV2,RANK:10 )
|
-
-
7 楼
有关第一个问题
开了块空间用了,但没全用。为什么开那么大就不明白了,或许跟编译器有关,或许那是结构体的大小。
|
能力值:
( LV2,RANK:10 )
|
-
-
8 楼
谢谢各位
003910CA |. 6BC0 18 imul eax, eax, 18 ;
这种形式是怎样产生的呢。
|
能力值:
( LV2,RANK:10 )
|
-
-
9 楼
[QUOTE=oldn;817106]谢谢二位的回答。
还有两个问题没明白
第一是前面栈开了块空间,这个空间没有用吧?
第二是 通过this找偏移的这个过程.
003910C6 |. 0FB640 30 movzx eax, byte ptr [eax+30] ;零扩展this指针+0x30的数据成员(应该是一...[/QUOTE]
第一个问题很简单,因为这个程序是debug版的,所以必然会有这样的一段初始化的代码,尽管没有用到,这段代码也不会做任何优化,如果是release版的,就不会有这段代码,就算你这样写了,没有用到的化也会被优化掉
至于第二个问题,你看清楚是movzx eax, byte ptr [eax+30] ,所以现在eax已经不是一个指向this的30偏移处的指针,而是已经把this的30偏移处的内容给取出来了,所以此时的eax应该是这个对象里的一个数据成员的值,所以后面的运算是用这个值来做运算,而不是在对指针做运算,看明白了吗?
|
能力值:
( LV2,RANK:10 )
|
-
-
10 楼
嗯,我现在明白
movzx eax, byte ptr [eax+30] 这句后eax里是this里某个成员的值。
但后面的 imul eax, eax, 18 ;
我是没理解这种形式是如何产生的。
比如说eax + 18的话我们可以认为18这是一种偏移量, 但这里是X18, 没搞懂这种形式是怎样产生的,会是结构体数组么?
而且看后面add eax, dword ptr [ebp-8] ;说明,前面eax产生的是this指针的偏移量
|
能力值:
( LV2,RANK:10 )
|
-
-
12 楼
菜鸟飞过!!
|
能力值:
( LV2,RANK:10 )
|
-
-
13 楼
[QUOTE=oldn;817499]嗯,我现在明白
movzx eax, byte ptr [eax+30] 这句后eax里是this里某个成员的值。
但后面的 imul eax, eax, 18 ;
我是没理解这种形式是如何产生的。
比如说eax + 18的话我们可以认为18这是一种偏移量, 但这里是X18...[/QUOTE]
有可能是结构体数组或是二维数组,但是信息不足,无法下定论,暂时只能理解为它取了一个值出来对此值进行运算后把this此偏移量处的指针做为返回值,imul eax, eax, 18应该是手动产生的,如return this + this->i*18,就会产生上面那样的效果了
|
能力值:
( LV2,RANK:10 )
|
-
-
14 楼
谢楼上的分析
我之前也想可能是结构体数组(结构体大小0x18长,位置由eax来确定), 只是出于对这种反汇编产生形式的猜测。
您说的return this + this->i*18这种形式,正常写c++代码应该不会出现这样的才对..
但这么写应该会产生
003910CA |. 6BC0 18 imul eax, eax, 18
003910CD |. 0345 F8 add eax, dword ptr [ebp-8]
这种效果.
|
能力值:
( LV2,RANK:10 )
|
-
-
15 楼
呵呵,你的推想很有道理,不过具体情况如何,你还需要仔细分析一下调用此函数的那个函数
我不是说作者是那样写的,我只是反推出一种可能的实现方式而已
|
|
|