• 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后的结果放回。因此,在反汇编下,没有引用这种数据类型。

  • 相关阅读:
    解析大型.NET ERP系统 权限模块设计与实现
    Enterprise Solution 开源项目资源汇总 Visual Studio Online 源代码托管 企业管理软件开发框架
    解析大型.NET ERP系统 单据编码功能实现
    解析大型.NET ERP系统 单据标准(新增,修改,删除,复制,打印)功能程序设计
    Windows 10 部署Enterprise Solution 5.5
    解析大型.NET ERP系统 设计异常处理模块
    解析大型.NET ERP系统 业务逻辑设计与实现
    解析大型.NET ERP系统 多国语言实现
    Enterprise Solution 管理软件开发框架流程实战
    解析大型.NET ERP系统 数据审计功能
  • 原文地址:https://www.cnblogs.com/maplewan/p/3243785.html
Copyright © 2020-2023  润新知