首页
社区
课程
招聘
一个子函数没看懂
发表于: 2010-6-1 13:51 4192

一个子函数没看懂

2010-6-1 13:51
4192
003910A0  /> \55            push    ebp
003910A1  |.  8BEC          mov     ebp, esp
003910A3  |.  81EC CC000000 sub     esp, 0CC
003910A9  |.  53            push    ebx
003910AA  |.  56            push    esi
003910AB  |.  57            push    edi
003910AC  |.  51            push    ecx
003910AD  |.  8DBD 34FFFFFF lea     edi, dword ptr [ebp-CC]
003910B3  |.  B9 33000000   mov     ecx, 33
003910B8  |.  B8 CCCCCCCC   mov     eax, CCCCCCCC
003910BD  |.  F3:AB         rep     stos dword ptr es:[edi]
003910BF  |.  59            pop     ecx
003910C0  |.  894D F8       mov     dword ptr [ebp-8], ecx
003910C3  |.  8B45 F8       mov     eax, dword ptr [ebp-8]
003910C6  |.  0FB640 30     movzx   eax, byte ptr [eax+30]
003910CA  |.  6BC0 18       imul    eax, eax, 18
003910CD  |.  0345 F8       add     eax, dword ptr [ebp-8]
003910D0  |.  5F            pop     edi
003910D1  |.  5E            pop     esi
003910D2  |.  5B            pop     ebx
003910D3  |.  8BE5          mov     esp, ebp
003910D5  |.  5D            pop     ebp
003910D6  \.  C3            retn

谁能帮解释下这个子函数

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (13)
雪    币: 273
活跃值: (64)
能力值: ( 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位置处的内容
   因此,此函数多半是一个构造函数。
2010-6-1 15:59
0
雪    币: 360
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
rol
3
参数是ecx,应该是一个结构体指针。
基本作用好像就是通过其中一个数据成员定位另一个数据成员。
返回值eax就是被定位的数据成员的指针。
2010-6-1 16:07
0
雪    币: 18
活跃值: (10)
能力值: ( 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。
很晕
2010-6-1 17:35
0
雪    币: 68
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
好牛啊。。
2010-6-1 17:52
0
雪    币: 273
活跃值: (64)
能力值: ( 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指针了
2010-6-1 18:10
0
雪    币: 360
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
rol
7
有关第一个问题
开了块空间用了,但没全用。为什么开那么大就不明白了,或许跟编译器有关,或许那是结构体的大小。
2010-6-1 18:17
0
雪    币: 18
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
谢谢各位

003910CA  |.  6BC0 18       imul    eax, eax, 18     ;
这种形式是怎样产生的呢。
2010-6-2 11:37
0
雪    币: 429
活跃值: (10)
能力值: ( 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应该是这个对象里的一个数据成员的值,所以后面的运算是用这个值来做运算,而不是在对指针做运算,看明白了吗?
2010-6-2 12:44
0
雪    币: 18
活跃值: (10)
能力值: ( 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指针的偏移量
2010-6-2 13:20
0
雪    币: 3
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
菜鸟飞过!!
2010-6-2 13:47
0
雪    币: 429
活跃值: (10)
能力值: ( 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,就会产生上面那样的效果了
2010-6-2 15:26
0
雪    币: 18
活跃值: (10)
能力值: ( 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]
这种效果.
2010-6-2 17:18
0
雪    币: 429
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
呵呵,你的推想很有道理,不过具体情况如何,你还需要仔细分析一下调用此函数的那个函数
我不是说作者是那样写的,我只是反推出一种可能的实现方式而已
2010-6-2 17:41
0
游客
登录 | 注册 方可回帖
返回
//