首页
社区
课程
招聘
[求助]求前辈高人讲解此函数的代码结构(类关系)
发表于: 2013-4-21 23:04 7514

[求助]求前辈高人讲解此函数的代码结构(类关系)

2013-4-21 23:04
7514


假设我没理解错,下面这个函数为thiscall,通过ECX传递this指针,那么此函数中

PUSH EAX
MOV ECX,DWORD PTR SS:[EBP-0x4]                  ; |DWORD PTR SS:[EBP-0x4]=  this
SUB ECX,0x38
CALL 00A0A710

那么this - 38 又指向的是什么呢?  通过上下文我分析,这也是一个thiscall,this - 38同样

是一个类指针, 那么这2个类,又是什么关系呢? 父子关系? 还是什么?

求教高人能给讲解一下这段代码的结构,类的关系, 如果能翻译成C语言伪代码,供小弟学习,感激不尽。

我曾经想过如果 this + 38 可能是这样:

class A       (this)

   ....

   ....

   ....

   int funA()

   class B b



int funA()
{
   this->b.funB()

}

可是 类中的类对象应该是  *(this + 38),  更不可能用 this - 38 来寻址丫




00A093B0  /. 55             PUSH EBP                                        ;  EBP压栈保存
00A093B1  |. 8BEC           MOV EBP,ESP                                     ;  获取原始ESP=0012D6E8
00A093B3  |. 83EC 5C        SUB ESP,0x5C                                    ;  开辟局部变量空间=0012D68C
00A093B6  |. 53             PUSH EBX                                        ;  保存EBX
00A093B7  |. 56             PUSH ESI                                        ;  保存ESI
00A093B8  |. 57             PUSH EDI                                        ;  保存EDI
00A093B9  |. 894D FC        MOV DWORD PTR SS:[EBP-0x4],ECX                  ;  创建局部变量一接收this指针
00A093BC  |. C745 F8 010000>MOV DWORD PTR SS:[EBP-0x8],0x1                  ;  创建局部变量二=1
00A093C3  |. C745 F4 000000>MOV DWORD PTR SS:[EBP-0xC],0x0                  ;  创建局部变量三=0
00A093CA  |. 8B45 FC        MOV EAX,DWORD PTR SS:[EBP-0x4]                  ;  EAX = 局部变量一
00A093CD  |. 83B8 3C1F0000 >CMP DWORD PTR DS:[EAX+0x1F3C],0x0               ;  if this->1F3C == 0
00A093D4  |. 74 05          JE SHORT 	  00A093DB                          ;  如果真则跳
00A093D6  |. E9 EA000000    JMP  00A094C5
00A093DB  |> 8B4D FC        MOV ECX,DWORD PTR SS:[EBP-0x4]                  ;  ECX = 局部变量一
00A093DE  |. 8B55 08        MOV EDX,DWORD PTR SS:[EBP+0x8]                  ;  EDX = 参数一
00A093E1  |. 8991 381F0000  MOV DWORD PTR DS:[ECX+0x1F38],EDX               ;  this-> 0x1F38 = 参数一
00A093E7  |. 837D 08 06     CMP DWORD PTR SS:[EBP+0x8],0x6                  ;  判断参数一不为6
00A093EB  |. 75 0C          JNZ SHORT 00A093F9                              ;  为真则跳
00A093ED  |. C745 F8 000000>MOV DWORD PTR SS:[EBP-0x8],0x0                  ;  局部变量二 = 0
00A093F4  |. E9 A7000000    JMP 00A094A0
00A093F9  |> 8B45 08        MOV EAX,DWORD PTR SS:[EBP+0x8]                  ;  EAX = 参数一
00A093FC  |. 50             PUSH EAX                                        ; /Arg1 = 00000002
00A093FD  |. 8B4D FC        MOV ECX,DWORD PTR SS:[EBP-0x4]                  ; |ECX =  this
00A09400  |. 83E9 38        SUB ECX,0x38                                    ; |此处不解
00A09403  |. E8 08130000    CALL 00A0A710                                   ; \00A0A710
00A09408  |. 8945 F4        MOV DWORD PTR SS:[EBP-0xC],EAX                  ;  局部变量三 = 返回值
00A0940B  |. 837D F4 00     CMP DWORD PTR SS:[EBP-0xC],0x0                  ;  判断返回值是否为0
00A0940F  |. 74 7D          JE SHORT      00A0948E                          ;  为0则跳
00A09411  |. B9 01000000    MOV ECX,0x1
00A09416  |. 85C9           TEST ECX,ECX
00A09418  |. 74 74          JE SHORT      00A0948E                          ;  不理解
00A0941A  |. 8D55 EC        LEA EDX,DWORD PTR SS:[EBP-0x14]                 ;  局部变量五 (4字节)
00A0941D  |. 52             PUSH EDX                                        ; /Arg1
00A0941E  |. 8B4D FC        MOV ECX,DWORD PTR SS:[EBP-0x4]                  ; |ECX =  this
00A09421  |. 81C1 281F0000  ADD ECX,0x1F28                                  ; |此处不解
00A09427  |. E8 342D0000    CALL 00A0C160                                   ; \00A0C160
00A0942C  |. 8B00           MOV EAX,DWORD PTR DS:[EAX]                      ;  Stack DS:[00129C34]=01711470
00A0942E  |. 8945 F0        MOV DWORD PTR SS:[EBP-0x10],EAX                 ;  局部变量四接收
00A09431  |. EB 08          JMP SHORT 00A0943B
00A09433  |> 8D4D F0        /LEA ECX,DWORD PTR SS:[EBP-0x10]                ;  局部变量六(4字节)
00A09436  |. E8 552E0000    |CALL 00A0C290
00A0943B  |> 8D4D E8         LEA ECX,DWORD PTR SS:[EBP-0x18]
00A0943E  |. 51             |PUSH ECX                                       ; /Arg1 = 00129C30
00A0943F  |. 8B4D FC        |MOV ECX,DWORD PTR SS:[EBP-0x4]                 ; |同上
00A09442  |. 81C1 281F0000  |ADD ECX,0x1F28                                 ; |
00A09448  |. E8 532D0000    |CALL 00A0C1A0                                  ; \00A0C1A0
00A0944D  |. 50             |PUSH EAX                                       ; /Arg1 = 00129C30
00A0944E  |. 8D4D F0        |LEA ECX,DWORD PTR SS:[EBP-0x10]                ; |不解
00A09451  |. E8 6A2E0000    |CALL 00A0C2C0                                  ; \00A0C2C0
00A09456  |. 25 FF000000    |AND EAX,0xFF
00A0945B  |. 85C0           |TEST EAX,EAX
00A0945D  |. 74 2F          |JE SHORT 00A0948E                              ;  此处不解
00A0945F  |. 8D4D F0        |LEA ECX,DWORD PTR SS:[EBP-0x10]
00A09462  |. E8 092E0000    |CALL 00A0C270
00A09467  |. 8338 00        |CMP DWORD PTR DS:[EAX],0x0
00A0946A  |. 74 20          |JE SHORT 00A0948C
00A0946C  |. 8B55 F4        |MOV EDX,DWORD PTR SS:[EBP-0xC]
00A0946F  |. 52             |PUSH EDX
00A09470  |. 8B45 08        |MOV EAX,DWORD PTR SS:[EBP+0x8]
00A09473  |. 50             |PUSH EAX
00A09474  |. 8D4D F0        |LEA ECX,DWORD PTR SS:[EBP-0x10]
00A09477  |. E8 F42D0000    |CALL 00A0C270
00A0947C  |. 8B08           |MOV ECX,DWORD PTR DS:[EAX]
00A0947E  |. 894D E4        |MOV DWORD PTR SS:[EBP-0x1C],ECX
00A09481  |. 8B55 E4        |MOV EDX,DWORD PTR SS:[EBP-0x1C]
00A09484  |. 8B02           |MOV EAX,DWORD PTR DS:[EDX]
00A09486  |. 8B4D E4        |MOV ECX,DWORD PTR SS:[EBP-0x1C]
00A09489  |. FF50 08        |CALL DWORD PTR DS:[EAX+0x8]
00A0948C  |>^EB A5          \JMP SHORT 00A09433
00A0948E  |> 8B4D 08        MOV ECX,DWORD PTR SS:[EBP+0x8]
00A09491  |. 51             PUSH ECX                                        ; /Arg1 = 00000002
00A09492  |. 8B4D FC        MOV ECX,DWORD PTR SS:[EBP-0x4]                  ; |ECX =  this
00A09495  |. 83E9 38        SUB ECX,0x38                                    ; |此处不解
00A09498  |. E8 83040000    CALL00A09920                                    ; \00A09920
00A0949D  |. 8945 F8        MOV DWORD PTR SS:[EBP-0x8],EAX                  ;  局部变量一=00000001
00A094A0  |> 837D F8 00     CMP DWORD PTR SS:[EBP-0x8],0x0                  ;  判断返回值是否为0
00A094A4  |. 75 1F          JNZ SHORT 00A094C5                              ;  不为0则跳
00A094A6  |. 8B55 08        MOV EDX,DWORD PTR SS:[EBP+0x8]
00A094A9  |. 83C2 0A        ADD EDX,0xA
00A094AC  |. 52             PUSH EDX                                        ; /Arg2
00A094AD  |. 6A 1B          PUSH 0x1B                                       ; |Arg1 = 0000001B
00A094AF  |. 8B4D FC        MOV ECX,DWORD PTR SS:[EBP-0x4]                  ; |
00A094B2  |. 83E9 38        SUB ECX,0x38                                    ; |
00A094B5  |. E8 E6190000    CALL 00A0AEA0                                   ; \00A0AEA0
00A094BA  |. 8B4D FC        MOV ECX,DWORD PTR SS:[EBP-0x4]
00A094BD  |. 83E9 38        SUB ECX,0x38
00A094C0  |. E8 8B060000    CALL 00A09B50
00A094C5  |> 5F             POP EDI
00A094C6  |. 5E             POP ESI
00A094C7  |. 5B             POP EBX
00A094C8  |. 8BE5           MOV ESP,EBP
00A094CA  |. 5D             POP EBP
00A094CB  \. C2 0400        RETN 0x4



[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (9)
雪    币: 18
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
消灭0回复.....
2013-4-22 14:32
0
雪    币: 2300
活跃值: (4595)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
透过表面看实质,类就是结构体。
结构体内可嵌套结构体,类也一样。
2013-4-22 14:56
0
雪    币: 196
活跃值: (135)
能力值: ( LV10,RANK:170 )
在线值:
发帖
回帖
粉丝
4
这说明用到了多重继承,减去的就是前一个父类的大小.
class CT :public CA, CB
{
  ......
}
sizeof(CA)  = 0x38;
2013-4-22 16:14
0
雪    币: 18
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
请看  2nd  edit
2013-4-22 16:15
0
雪    币: 18
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
按前辈的指教,写代码验证,这种继承只会逆出 this + 38, 那么this - 38,应该是

什么样的关系所造成的呢?

class CFirst
{
	public:

		CFirst();

		PROCESS_INFORMATION pi;

		int add(int,int);

};

class CSecond 
{
	public:

		CSecond();

		WNDCLASSEX wcex;

		int sub(int,int);

};

class CThird 
{

	public:

		CThird();

		STARTUPINFO si;
			
		int imul(int,int);
};

class CFourth :public CFirst,CSecond,CThird
{

public:

	CFourth();

	POINT pt;

	int func(int,int);
};




int CFirst::add(int a,int b)
{
	return a + b;
}

int CSecond::sub(int a,int b)
{
	return a - b;
}

int CThird::imul(int a,int b)
{
	return a * b;
}

int CFourth::func(int a,int b)
{

	return this->imul(a,b);
}




int _tmain(int argc, _TCHAR* argv[])
{

	CFourth* theThird = new CFourth();

	
	return theThird->func(9,7);
}




00411610  mov         dword ptr [ebp-8],ecx 
00411613  mov         eax,dword ptr [b] 
00411616  push        eax  
00411617  mov         ecx,dword ptr [a] 
0041161A  push        ecx  
0041161B  mov         ecx,dword ptr [this] 
[COLOR="Red"]0041161E  add         ecx,40h[/COLOR] 
00411621  call        CThird::imul (4111FEh) 
2013-4-22 20:21
0
雪    币: 196
活跃值: (135)
能力值: ( LV10,RANK:170 )
在线值:
发帖
回帖
粉丝
7
Sorry,我没说清楚,子类的内存包含了所有的父类,所以由子类向父类转的时候只会出现+,,当由后一个父类向
前一个父类转的时候需要减去前一个父类的大小.

结合你的代码,当由CThird*转到CFirst或CSecond时会出现减.
2013-4-22 20:48
0
雪    币: 18
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
前辈能给几句启发式的代码吗? 我目前的水平实在很难理解怎么转
2013-4-22 21:57
0
雪    币: 61
活跃值: (21)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
CThird* theThird = new CThird();
((CFourth *)theThird)->add(9,7);

这样写就可以了
2013-4-22 22:44
0
雪    币: 18
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
感谢前辈,按这样写,确实是sub,

我还想请教一个问题,正向编写程序的时候,什么情况下,会写出这样的代码呢?
2013-4-22 23:19
0
游客
登录 | 注册 方可回帖
返回