C++反汇编学习笔记(二)

Chinese:

1、地址 指针 引用

C++中地址标号用16进制表示,取一个变量地址使用&操作符,只有变量才存在内存地址,常量没有地址(不包括const定义的伪常量)

指针是一种数据类型,用于保存各种数据类型在内存中的地址。指针变量也可以取出地址,所以会出现多级指针。

C++中引用不可以单独定义,定义的时候必须初始化。引用表示一个变量的别名,对它的任何操作,本质都是在操作它所表示的变量。

 

2、指针和地址的区别

指针是变量,用于保存变量地址;地址是常量,是内存标号。

指针可修改,可以再次保存其他的变量地址;地址不可修改。

指针可以对其执行取地址操作得到地址;地址不可执行取地址操作。

指针包含对保存地址的解释信息;地址无法解释数据。

 

3、各类型指针的工作方式

通过C++的反汇编指令进行描述

// C++ Code:
int nVar = 0x12345678;

;为地址赋值4字节数据12345678h
mov dword ptr [ebp-10h], 12345678h

// C++ Code:
int *pnVar = &nVar;

lea ecx, [ebp-10h]
mov dword ptr [ebp-14h], ecx

// C++ Code:
char *pcVar = (char*)&nVar;

lea edx, [ebp-10h]
mov dword ptr [ebp-18h], edx

// C++ Code:
short *psnVar = (short*)&nVar;

lea eax, [ebp-10h]
mov dword ptr [ebp-1Ch], eax

// C++ Code:
printf("%08x", *pnVar);

;取出pnVar中保存的地址值并放入ecx中
mov ecx, dword ptr [ebp-14h]
mov edx, dword ptr [ecx]
;printf函数调用部分略

// C++ Code:
printf("%08x", *pcVar);

;取出pcVar中保存的地址值并放入eax中
mov eax, dword ptr [ebp-18h]
;从eax保存的地址中,以1字节方式读取数据,存入ecx中
movsx ecx, byte ptr [eax]

// C++ Code:
printf(“%08x", *psnVar);

;取出psnVar中保存的地址并放入edx中
mov edx, dword ptr [ebp-1Ch]
;从edx保存的地址中,以2字节的方式读取数据,存入eax中
movsx eax, word ptr [edx]


可见指针类型会按照指针类型对地址数据进行解释。去内容操作一般分为两个步骤,先取出指针中保存的地址信息,然后针对这个地址取内容,也就是一个间接寻址的过程,这也是识别指针的重要依据。

 

4、了解引用的内部工作原理

实际上引用类型就是指针类型,只不过它用于存放地址的内存空间对使用者而言是隐藏的。

// C++ Code
 int nVar = 0x12345678;

mov dword ptr [ebp-4], 12345678h

// C++ Code
int &nVarType = nVar;
;取出变量nVar的地址放入eax中
lea eax, [ebp-4]
;将变量nVar的地址存入地址ebp-8处,这个ebp-8处便是引用类型nVarType的地址
;从这条汇编语句中可以得出结论,引用类型在内存中是占有一席之地的
mov dword ptr [ebp-8] eax;

//调用函数Add,Add的参数为int引用类型,将变量nVar作为参数传递
Add(nVar);

;取出变量nVar的地址放入ecx
lea ecx, [ebp-4]
;将ecx作为参数入栈,也就是传递变量nVar的地址作为参数
push ecx;
;函数调用的指令略
call @ILT+15 (Add)  (00401014)
add esp, 4

引用类型的存储方式和指针是一样的,都是使用内存空间存放地址。引用只是通过编译器实现寻址,而指针需要手动寻址。

引用类型也可以作为函数的参数类型和返回类型使用。因为引用实际上就是指针,所以它同样会在参数传递时产生一份拷贝。

// C++ Code
void Add(int &nVar)
{
    nVar++;
}

;取出参数nVar中的内容放入eax中
mov eax, dword ptr [ebp+8]
;对eax执行取内容操作
mov ecx, dword ptr [eax]
add ecx, 1
mov edx, dword ptr [ebp+8]
mov dword ptr [edx], ecx
ret

从汇编代码中可以看出,引用类型的参数也占内存空间,其中保存的数据是一个地址值。取出这个地址中的数据并加1,再将+1后的结果放回。因此,在反汇编下,没有引用这种数据类型。

posted @ 2013-08-07 18:20  我是枫子  阅读(681)  评论(0编辑  收藏  举报