当前位置: 首页 > news >正文

Windows逆向工程入门之整数类型

文章目录

  • C++ 数据类型与内存管理:汇编视角深度解析
    • 1. 基本数据类型与内存布局
      • 数据类型的内存占用
    • 2. 数据赋值的汇编实现
      • 寄存器与内存操作
    • 3. 无符号整数的存储与运算
      • 无符号数的二进制表示
    • 4. 有符号整数的补码表示
      • 补码运算与溢出检测
    • 5. 整数溢出的汇编检测
      • 溢出标志位分析
    • 6. 类型转换的汇编实现
      • 符号扩展与零扩展
    • 7. 全局变量的内存管理
      • 数据段与访问方式
    • 8. 局部变量的栈管理
      • 栈帧结构与变量寻址
    • 9. 综合逆向分析示例
      • 完整的程序分析
    • 关键逆向工程技术总结
      • 1. 数据类型识别
      • 2. 符号性判断
      • 3. 变量类型识别
      • 4. 内存访问模式

C++ 数据类型与内存管理:汇编视角深度解析

1. 基本数据类型与内存布局

数据类型的内存占用

#include <iostream>
#include <Windows.h>void demonstrateDataTypes() {char a = 'A';short b = 0x1234;int c = 0x12345678;long long d = 0x123456789ABCDEF0;std::cout << "Sizeof char: " << sizeof(a) << " bytes" << std::endl;std::cout << "Sizeof short: " << sizeof(b) << " bytes" << std::endl;std::cout << "Sizeof int: " << sizeof(c) << " bytes" << std::endl;std::cout << "Sizeof long long: " << sizeof(d) << " bytes" << std::endl;
}

对应的汇编代码分析:

; char a = 'A';
mov byte ptr [ebp-1], 65          ; 41h = 'A', 1字节存储; short b = 0x1234;  
mov eax, 1234h                    ; 立即数加载到寄存器
mov word ptr [ebp-6], ax          ; 使用AX寄存器(16位)存储到内存; int c = 0x12345678;
mov dword ptr [ebp-0Ch], 12345678h ; 直接32位内存写入; long long d = 0x123456789ABCDEF0;
mov dword ptr [ebp-18h], 9ABCDEF0h ; 低32位
mov dword ptr [ebp-14h], 12345678h ; 高32位

内存布局可视化:

地址       值         说明
0x0019FF74  41         char a = 'A' (1字节)
0x0019FF70  34 12      short b = 0x1234 (小端序)
0x0019FF6C  78 56 34 12 int c = 0x12345678 (小端序)
0x0019FF64  F0 DE BC 9A long long d 低32位
0x0019FF68  78 56 34 12 long long d 高32位

2. 数据赋值的汇编实现

寄存器与内存操作

void demonstrateAssignment() {// 立即数赋值int immediate = 0xDEADBEEF;// 寄存器间赋值int reg_to_reg = immediate;// 内存到内存赋值(实际通过寄存器)int memory_copy = reg_to_reg;// 表达式赋值int expression = immediate + reg_to_reg;
}

汇编代码深度分析:

; int immediate = 0xDEADBEEF;
mov dword ptr [ebp-4], 0DEADBEEFh  ; 直接内存写入; int reg_to_reg = immediate;
mov eax, dword ptr [ebp-4]         ; 1. 内存加载到寄存器
mov dword ptr [ebp-8], eax         ; 2. 寄存器存储到内存; int memory_copy = reg_to_reg;  
mov ecx, dword ptr [ebp-8]         ; 再次通过寄存器中转
mov dword ptr [ebp-0Ch], ecx; int expression = immediate + reg_to_reg;
mov edx, dword ptr [ebp-4]         ; 加载immediate
add edx, dword ptr [ebp-8]         ; 与reg_to_reg相加
mov dword ptr [ebp-10h], edx       ; 结果存储

关键观察:

  • x86架构不支持内存到内存的直接移动
  • 所有数据移动都通过寄存器中转
  • mov指令根据操作数大小决定数据传输量

3. 无符号整数的存储与运算

无符号数的二进制表示

void unsignedArithmetic() {unsigned char uc = 255;unsigned short us = 65535;unsigned int ui = 4294967295U;// 无符号运算unsigned int result1 = ui + 1;      // 溢出到0unsigned int result2 = ui - 1;      // 正常递减std::cout << "uc = " << (int)uc << std::endl;std::cout << "us = " << us << std::endl;  std::cout << "ui = " << ui << std::endl;std::cout << "ui + 1 = " << result1 << std::endl;std::cout << "ui - 1 = " << result2 << std::endl;
}

汇编实现分析:

; unsigned char uc = 255;
mov byte ptr [ebp-1], 0FFh           ; 0xFF = 255; unsigned int result1 = ui + 1;
mov eax, dword ptr [ebp-0Ch]         ; 加载ui
add eax, 1                           ; 无符号加法
mov dword ptr [ebp-10h], eax         ; 存储结果; 无符号比较指令
cmp eax, 100
ja  above_label                      ; 无符号大于跳转
jb  below_label                      ; 无符号小于跳转

无符号数的关键特征:

  • 所有位都表示数值大小
  • 使用addsub等无符号运算指令
  • 比较使用ja(above)、jb(below)等无符号跳转

4. 有符号整数的补码表示

补码运算与溢出检测

void signedArithmetic() {int positive = 42;int negative = -42;int max_int = 2147483647;int min_int = -2147483648;// 补码验证std::cout << "42的补码: " << std::hex << positive << std::endl;std::cout << "-42的补码: " << std::hex << negative << std::endl;// 有符号溢出int overflow = max_int + 1;std::cout << "MAX_INT + 1 = " << overflow << std::endl;
}

汇编层面分析:

; int negative = -42;
mov dword ptr [ebp-8], 0FFFFFFD6h    ; -42的补码表示; 有符号加法
mov eax, dword ptr [ebp-0Ch]         ; 加载max_int
add eax, 1                           ; 加法运算
mov dword ptr [ebp-14h], eax         ; 结果可能溢出; 有符号比较
cmp eax, 100
jg  greater_label                    ; 有符号大于跳转  
jl  less_label                       ; 有符号小于跳转; 符号扩展指令
movsx eax, byte ptr [ebp-1]          ; 字节符号扩展到双字
movsx ebx, word ptr [ebp-6]          ; 字符号扩展到双字

补码运算特点:

  • 最高位为符号位(0正1负)
  • 使用movsx进行符号扩展
  • 比较使用jg(greater)、jl(less)等有符号跳转

5. 整数溢出的汇编检测

溢出标志位分析

void demonstrateOverflow() {unsigned int u_max = 0xFFFFFFFF;int s_max = 0x7FFFFFFF;int s_min = 0x80000000;unsigned int u_overflow = u_max + 1;int s_overflow = s_max + 1;std::cout << "无符号溢出: " << u_overflow << std::endl;std::cout << "有符号溢出: " << s_overflow << std::endl;
}

汇编标志位分析:

; 无符号加法及溢出检测
mov eax, 0FFFFFFFFh
add eax, 1                           ; 结果=0, CF=1(进位标志)
jc  carry_occurred                   ; 如果CF=1跳转; 有符号加法及溢出检测  
mov ebx, 7FFFFFFFh
add ebx, 1                           ; 结果=0x80000000, OF=1(溢出标志)
jo  overflow_occurred                ; 如果OF=1跳转; 带进位加法
mov ecx, 0FFFFFFFFh
adc ecx, 0                           ; ecx = ecx + 0 + CF

CPU标志位说明:

  • CF(进位标志):无符号运算溢出时设置
  • OF(溢出标志):有符号运算溢出时设置
  • ZF(零标志):结果为0时设置
  • SF(符号标志):结果为负时设置

6. 类型转换的汇编实现

符号扩展与零扩展

void typeConversionExamples() {// 符号扩展char negative_char = -100;short sign_extended = negative_char;  // 应该保持-100int sign_extended_int = negative_char;// 零扩展unsigned char positive_char = 200;unsigned short zero_extended = positive_char;  // 应该保持200unsigned int zero_extended_int = positive_char;// 截断unsigned int big_value = 0x12345678;unsigned short truncated_short = big_value;    // 0x5678unsigned char truncated_char = big_value;      // 0x78std::cout << "符号扩展: " << sign_extended << std::endl;std::cout << "零扩展: " << zero_extended << std::endl;std::cout << "截断: " << std::hex << truncated_short << std::endl;
}

汇编转换指令:

; 符号扩展 (MOVSX)
movsx eax, byte ptr [ebp-1]          ; 字节→双字,带符号扩展
movsx ebx, word ptr [ebp-6]          ; 字→双字,带符号扩展; 零扩展 (MOVZX)  
movzx ecx, byte ptr [ebp-7]          ; 字节→双字,零扩展
movzx edx, word ptr [ebp-0Ah]        ; 字→双字,零扩展; 截断操作
mov eax, dword ptr [ebp-10h]         ; 加载32位值
mov word ptr [ebp-14h], ax           ; 存储低16位(截断)
mov byte ptr [ebp-15h], al           ; 存储低8位(截断)

7. 全局变量的内存管理

数据段与访问方式

// 全局变量定义
int initialized_global = 0x12345678;      // .data段
int uninitialized_global;                 // .bss段  
const int read_only_global = 0xABCD;      // .rdata段void accessGlobalVariables() {// 读取全局变量int local_copy = initialized_global;// 修改全局变量uninitialized_global = 0x9999;// 全局变量地址访问int* global_ptr = &initialized_global;*global_ptr = 0x5555;std::cout << "全局变量值: " << std::hex << initialized_global << std::endl;std::cout << "全局变量地址: " << global_ptr << std::endl;
}

汇编层面的全局变量访问:

; int local_copy = initialized_global;
mov eax, dword ptr [initialized_global]  ; 直接内存访问
mov dword ptr [ebp-4], eax; uninitialized_global = 0x9999;
mov dword ptr [uninitialized_global], 9999h; int* global_ptr = &initialized_global;
mov dword ptr [ebp-8], offset initialized_global; *global_ptr = 0x5555;
mov eax, dword ptr [ebp-8]              ; 加载指针值
mov dword ptr [eax], 5555h              ; 通过指针写入

内存段说明:

  • .data段:已初始化的全局/静态变量
  • .bss段:未初始化的全局/静态变量(程序启动时清零)
  • .rdata段:只读数据(常量)

8. 局部变量的栈管理

栈帧结构与变量寻址

void stackFrameDemo(int param1, int param2) {// 局部变量声明int local1 = 0x1111;int local2 = 0x2222;int local3 = 0x3333;// 数组局部变量int array[4] = {0x4444, 0x5555, 0x6666, 0x7777};// 复杂表达式int result = param1 + param2 + local1 + array[2];std::cout << "结果: " << std::hex << result << std::endl;// 查看栈地址std::cout << "参数1地址: " << &param1 << std::endl;std::cout << "局部变量地址: " << &local1 << std::endl;std::cout << "数组地址: " << array << std::endl;
}

栈帧的汇编布局:

; 函数序言
push ebp
mov ebp, esp
sub esp, 30h                    ; 为局部变量分配栈空间; 参数访问 (ebp+偏移)
mov eax, dword ptr [ebp+8]      ; 访问param1
mov ebx, dword ptr [ebp+0Ch]    ; 访问param2; 局部变量初始化 (ebp-偏移)
mov dword ptr [ebp-4], 1111h    ; local1
mov dword ptr [ebp-8], 2222h    ; local2  
mov dword ptr [ebp-0Ch], 3333h  ; local3; 数组初始化
mov dword ptr [ebp-1Ch], 4444h  ; array[0]
mov dword ptr [ebp-18h], 5555h  ; array[1]
mov dword ptr [ebp-14h], 6666h  ; array[2]
mov dword ptr [ebp-10h], 7777h  ; array[3]; 数组元素访问
mov ecx, dword ptr [ebp-14h]    ; 访问array[2]; 函数尾声
mov esp, ebp                    ; 恢复栈指针
pop ebp                         ; 恢复基址指针
ret

典型栈帧布局:

高地址
[ebp+0Ch]   param2
[ebp+8]     param1  
[ebp+4]     返回地址
[ebp]       保存的ebp    ← ebp指向这里
[ebp-4]     local1
[ebp-8]     local2
[ebp-0Ch]   local3
[ebp-10h]   array[3]
[ebp-14h]   array[2] 
[ebp-18h]   array[1]
[ebp-1Ch]   array[0]    ← esp指向这里(分配后)
低地址

9. 综合逆向分析示例

完整的程序分析

#include <iostream>
#include <Windows.h>// 全局变量
int global_counter = 0;int calculateSum(int a, int b) {int local_sum = a + b;global_counter++;return local_sum;
}void memoryPatternDemo() {// 小端序验证int value = 0x12345678;unsigned char* byte_ptr = (unsigned char*)&value;std::cout << "小端序内存布局:" << std::endl;for(int i = 0; i < 4; i++) {std::cout << "地址 " << (void*)(byte_ptr + i) << ": 0x" << std::hex << (int)byte_ptr[i] << std::endl;}// 函数调用分析int result = calculateSum(0x100, 0x200);std::cout << "计算结果: 0x" << std::hex << result << std::endl;std::cout << "全局计数器: " << global_counter << std::endl;
}int main() {std::cout << "模块基址: 0x" << GetModuleHandle(NULL) << std::endl;std::cout << "全局变量地址: 0x" << &global_counter << std::endl;memoryPatternDemo();return 0;
}

对应的关键汇编模式:

; 函数调用序列
push 200h                      ; 参数2入栈
push 100h                      ; 参数1入栈  
call calculateSum              ; 函数调用
add esp, 8                     ; 清理栈参数; calculateSum 函数内部
calculateSum proc
push ebp
mov ebp, esp
sub esp, 4                     ; 局部变量空间; local_sum = a + b
mov eax, [ebp+8]               ; 参数a
add eax, [ebp+0Ch]             ; 参数b
mov [ebp-4], eax               ; 存储到local_sum; global_counter++
mov ecx, [global_counter]
add ecx, 1
mov [global_counter], ecx; return local_sum
mov eax, [ebp-4]               ; 返回值通过EAX传递mov esp, ebp
pop ebp
ret
calculateSum endp

关键逆向工程技术总结

1. 数据类型识别

  • 字符/字节byte ptr 操作,1字节传输
  • 短整型word ptr 操作,2字节传输
  • 整型dword ptr 操作,4字节传输
  • 长整型:可能需要多个dword操作

2. 符号性判断

  • 无符号:使用jajbmovzx指令
  • 有符号:使用jgjlmovsx指令

3. 变量类型识别

  • 全局变量:直接内存访问,固定地址
  • 局部变量[ebp-偏移] 方式访问
  • 参数[ebp+偏移] 方式访问

4. 内存访问模式

  • 小端序:低字节在低地址
  • 栈增长:向低地址方向增长
  • 对齐:变量通常按自然边界对齐

通过这种深度的汇编分析,可以准确理解C++代码的内存行为,为逆向工程和性能优化提供坚实基础。

http://www.dtcms.com/a/439006.html

相关文章:

  • 怎么用wordpress做网盘google seo 营销网站
  • c2c网站类型可以翻外墙的浏览器
  • 1.HTTPS协议原理
  • 中山网站制作建设深圳网站设计 深圳市利
  • FontViewOK(字体管理软件) 多语便携版
  • Day90 基本情报技术者 单词表26 ソフトウェア品質管理
  • 腾讯开源啦,源码地址+部署脚本,工业级原生多模态
  • 参与网站网站建设连云港北京网站建设
  • 如何建设自己的网站 知乎wordpress 无广告视频插件
  • 算法 - FOC开环速度控制
  • 企业建设网站费用福建省建设厅网站信用评分
  • 北京私人做网站请seo的人帮做网站排名
  • 网站建设基础策划书网站做跳转会有什么影响
  • 网站建设怎么销售数据库网站
  • 做企业网站安装什么系统好google 网站优化工具
  • 网站内容分析阿里云备案网站建设方案书
  • 一键免费生成网页的网站wordpress做的外贸网站6
  • 域名注册网站那个好wordpress文字幻灯片
  • MySQL 8.0 InnoDB ReplicaSet 完整配置指南与切换
  • PCB学习——STM32F103VET6-STM32接口部分
  • [光学原理与应用-480]:《国产检测设备对比表》
  • 再谈Linux多进程——进程处理与守护进程
  • 广东平台网站建设制作大型网站只做要多少钱
  • 【LLM】基于ms-Swift大模型SFT和RL训练
  • 基于VisionMaster实现数据实时存储至MySQL
  • 文化共享工程网站建设情况做外贸比较好的网站
  • 淮安建设工程协会网站查询建立网上商城应考虑哪些问题
  • 五华网站建设 优帮云wordpress用户私信功能
  • MVC架构模式与三层架构的关系详解
  • 建设网站个人简介范文下载安装wordpress 主题