gmh5225 发表于 2014-12-28 23:12

汇编逆向(六)

本帖最后由 gmh5225 于 2014-12-28 23:15 编辑

写这个纯属就是自己记录下自己的学习经历,没有其他的意思。
详细命令请百度谷歌 8086汇编指令




继上几次C函数的调用方式 (1) __cdecl(2) __stacall(3) __fastcall
这次是C++的,多了一个类的自身对象 thiscall
thiscall会隐含一个this参数,在执行call前会给ecx


原型:
class Mythiscall
{
public:
      int add(int,int);
};
int Mythiscall::add(int a,int b)
{
      return a+b;
}
int main()
{   
      Mythiscall t;
      int a=3,b=4,c=0;
      c=t.add(a,b);
      printf("%d",c);
      system("pause");
      return 0;
} 反汇编:
0128103E    50            push    eax
0128103F    8B4D FC         mov   ecx, dword ptr
01281042    51            push    ecx
01281043    8D4D F3         lea   ecx, dword ptr          ; 传递一个隐藏的this参数,赋值给ecx
01281046    E8 B5FFFFFF   call    testtest.Mythiscall::add
而加法函数内部:
01281000 >55            push    ebp
01281001    8BEC            mov   ebp, esp
01281003    51            push    ecx
01281004    894D FC         mov   dword ptr , ecx            this参数赋值给第一个局部变量
01281007    8B45 08         mov   eax, dword ptr
0128100A    0345 0C         add   eax, dword ptr
0128100D    8BE5            mov   esp, ebp
0128100F    5D            pop   ebp
01281010 >C2 0800         retn    0x8上面的讲完了,那么就讲C++的核心,面向对象,类,那类里面又属什么是核心呢,那就是虚函数了。


先看C++源代码:
class Myfun
{
      public:
                virtual int add(int a,int b)
                {
                        return a+b;
                }
                virtual int mul(int a,int b)
                {
                        return a*b;
                }
};
int main()
{
      Myfun *m=new Myfun();
      m->add(2,3);
      m->mul(2,3);
      return 0;
}
OD反汇编:

00CD1040 >/[        DISCUZ_CODE_21        ]nbsp; 55            push    ebp
00CD1041|.8BEC          mov   ebp, esp
00CD1043|.83EC 0C       sub   esp, 0xC
00CD1046|.6A 04         push    0x4                                     ;为新指针m分配空间
00CD1048|.FF15 A820CD00 call    dword ptr [<&MSVCR100.operator new>]    ;msvcr100.operator new
00CD104E|.83C4 04       add   esp, 0x4
00CD1051|.8945 F8       mov   dword ptr , eax                ;new一个指针
00CD1054|.837D F8 00    cmp   dword ptr , 0x0
00CD1058|.74 0D         je      short testtest.00CD1067               ;判断指针是否为空
00CD105A|.8B4D F8       mov   ecx, dword ptr
00CD105D|.E8 3E000000   call    testtest.Myfun::Myfun                   ;指针指向Myfun类
00CD1062|.8945 F4       mov   dword ptr , eax                ;返回的eax指针
00CD1065|.EB 07         jmp   short testtest.00CD106E
00CD1067|>C745 F4 00000>mov   dword ptr , 0x0
00CD106E|>8B45 F4       mov   eax, dword ptr
00CD1071|.8945 FC       mov   dword ptr , eax
00CD1074|.6A 03         push    0x3                                     ;压3
00CD1076|.6A 02         push    0x2                                     ;压2
00CD1078|.8B4D FC       mov   ecx, dword ptr                 ;this指针 传入ecx
00CD107B|.8B11          mov   edx, dword ptr                   ;this指针指向虚函数
00CD107D|.8B4D FC       mov   ecx, dword ptr
00CD1080|.8B02          mov   eax, dword ptr                   ;虚函数指针指向add函数
00CD1082|.FFD0          call    eax                                     ;调用add函数
00CD1084|.6A 03         push    0x3                                     ;压3
00CD1086|.6A 02         push    0x2                                     ;压2
00CD1088|.8B4D FC       mov   ecx, dword ptr                 ;this指针 传入ecx
00CD108B|.8B11          mov   edx, dword ptr                   ;this指针指向虚函数
00CD108D|.8B4D FC       mov   ecx, dword ptr
00CD1090|.8B42 04       mov   eax, dword ptr                 ;虚函数指针指向mul函数
00CD1093|.FFD0          call    eax                                     ;调用mul函数
00CD1095|.33C0          xor   eax, eax
00CD1097|.8BE5          mov   esp, ebp
00CD1099|.5D            pop   ebp
00CD109A\.C3            retn
add函数内部
00CD1000 >/.55            push    ebp
00CD1001|.8BEC          mov   ebp, esp
00CD1003|.51            push    ecx
00CD1004|.894D FC       mov   dword ptr , ecx                ;this指针
00CD1007|.8B45 08       mov   eax, dword ptr                 ;参数1
00CD100A|.0345 0C       add   eax, dword ptr                 ;参数2
00CD100D|.8BE5          mov   esp, ebp
00CD100F|.5D            pop   ebp
00CD1010\.C2 0800       retn    0x8
mul函数内部
00CD1020 >/.55            push    ebp
00CD1021|.8BEC          mov   ebp, esp
00CD1023|.51            push    ecx
00CD1024|.894D FC       mov   dword ptr , ecx                ;this指针
00CD1027|.8B45 08       mov   eax, dword ptr                 ;参数1
00CD102A|.0FAF45 0C   imul    eax, dword ptr                 ;参数2
00CD102E|.8BE5          mov   esp, ebp
00CD1030|.5D            pop   ebp
00CD1031\.C2 0800       retn    0x8


我们发现,调用虚函数的时候,是用了2级指针去访问的,第一级指针是this指针,第二级是虚函数指针,然后再用虚函数指针去访问相应的函数


520Kelly 发表于 2014-12-28 23:24

说得好深奥、真的是接触不到这么高级的东西

膜拜gmh师傅

神秘小子 发表于 2014-12-28 23:25

看过就要支持谢谢大神教程{:5_116:}

htqweszxc 发表于 2014-12-29 08:27

支持大神   谢谢

Cyan 发表于 2014-12-29 10:01

感谢 学习下

fcguo800 发表于 2017-11-30 14:54

非常感谢楼主,继续学习中。

别管我了行 发表于 2022-2-25 02:37

ghostxu 发表于 2022-3-9 01:01

感谢分享,很给力!~

weiran324 发表于 2022-3-30 23:24

学习学习,,,

weiran324 发表于 2022-3-31 18:32

学习学习,,,
页: [1] 2
查看完整版本: 汇编逆向(六)