逆向工程之内存物理地址

admin 2026-02-17 19:50:14 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 该文档是一篇关于逆向工程中内存物理地址概念的技术文章,核心讲解了x86架构下段寄存器(如DS、CS、SS、ES)的作用、不同内存模型(平坦、保护、实模式)下物理地址的计算方式,并通过C语言与汇编语言的对比示例,展示了条件判断等基本逻辑在两种语言中的实现映射。文章旨在帮助读者理解底层内存访问机制及其在逆向分析中的应用。 综合评分: 68 文章分类: 逆向分析,二进制安全


cover_image

逆向工程之内存物理地址

原创

高尉峰 高尉峰

ShadowRoot

2026年2月14日 10:59 河北

段寄存器

在x86汇编语言中,DSData Segment(数据段)寄存器的缩写,DS用于指向当前数据段的基地址。在访问内存中的数据时,CPU会使用基地址和偏移地址来定位数据的位置。

其他段寄存器:

  • CS (Code Segment) – 代码段
  • SS(Stack Segment) – 堆栈段
  • ES(Extra Segment) – 附加段

例子:

cmp dword ptr ds:[var1], 20  ; 定义一个4字节的var1变量,初始值为20
  • ds:明确指定使用DS段寄存器
  • [var1]:表示var1变量的偏移地址
  • DWORD(Double Word)是汇编语言中的一个数据类型指示符
BYTE    = 1 字节 (8位)   范围: 0-255WORD    = 2 字节 (16位)  范围: 0-65535DWORD   = 4 字节 (32位)  范围: 0-4294967295QWORD   = 8 字节 (64位)  范围: 0-18446744073709551615

内存模型

平坦内存模型:

所有段寄存器(CS, DS, SS, ES)的基址都是0物理地址 = 0 + 变量的偏移地址

保护模式内存模型:

物理地址 = 段基址(从描述符表获取)+ 偏移地址

实模式内存模型:

物理地址 = DS基址 × 16 + 偏移地址
Example:DS寄存器基址(1000h),偏移地址(0020h)物理地址 = 1000h × 16 = 10000h + 0020h = 10020h

例子:

  .386p  .model flat,stdcall  option casemap:none.data  var1 DWORD 20    ; 假设var1的偏移地址0x00403000  var2 DWORD 10    ; 假设var2的偏移地址0x00403004.code  ; 平坦内存模型  mov eax, ds:[var1]  ; 物理地址=0 + 00403000h = 00403000h  mov ebx, [var2]     ; 物理地址=0 + 00403004h = 00403004h                      ; (ds:可以省略)

C语言和汇编语言的关系

C:

#include&nbsp;<stdio.h>#include&nbsp;<windows.h>
int&nbsp;main(int&nbsp;argc,char&nbsp;* argv[]){&nbsp;&nbsp;int&nbsp;var1 =&nbsp;20;&nbsp;&nbsp;int&nbsp;var2 =&nbsp;10;&nbsp;&nbsp;int&nbsp;var3 =&nbsp;50;
&nbsp;&nbsp;if&nbsp;(var1 >=&nbsp;20&nbsp;and&nbsp;var2 <=&nbsp;100&nbsp;and&nbsp;var3 ==&nbsp;50)&nbsp; {&nbsp; &nbsp;&nbsp;printf("xor eax,eax");&nbsp; }&nbsp;&nbsp;return&nbsp;0;}

ASM:

&nbsp;&nbsp;.386p&nbsp; .model flat,stdcall&nbsp; option casemap:noneinclude&nbsp;windows.incinclude&nbsp;kernel32.incincludelib kernel32.lib.data&nbsp; var1 DWORD&nbsp;20&nbsp; var2 DWORD&nbsp;10&nbsp; var3 DWORD&nbsp;50&nbsp; flag DWORD ?.code&nbsp; main PROC&nbsp; ;&nbsp;if(var1 >=&nbsp;20&nbsp;and&nbsp;var2 <=&nbsp;100&nbsp;and&nbsp;var3 ==&nbsp;50)&nbsp; &nbsp; cmp dword ptr ds:[var1],20&nbsp; &nbsp; &nbsp;; 判断是否大于20&nbsp; &nbsp; jl L1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; 不大于则跳转&nbsp; &nbsp; cmp dword ptr ds:[var2],100&nbsp; &nbsp; ; 判断是否小于100&nbsp; &nbsp; jg L1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; 不小于则跳转&nbsp; &nbsp; cmp dword ptr ds:[var3],50&nbsp; &nbsp; &nbsp;; 判断是否等于50&nbsp; &nbsp; jne L1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ; 不等于则跳转&nbsp; &nbsp; mov dword ptr ds:[flag],1&nbsp; &nbsp; &nbsp; ; 说明等式成立 flag=1&nbsp; &nbsp; jmp L2&nbsp; L1: mov dword ptr ds:[flag],0&nbsp; L2: cmp dword ptr ds:[flag],0&nbsp; &nbsp; je lop_end &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ; 为0则跳转,不为0则继续执行&nbsp; &nbsp;&nbsp;xor&nbsp;eax,eax &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; 此处是执行if语句内部&nbsp; &nbsp;&nbsp;xor&nbsp;ebx,ebx&nbsp; &nbsp;&nbsp;xor&nbsp;ecx,ecx&nbsp; &nbsp; jmp lop_end&nbsp; lop_end:&nbsp; &nbsp; nop &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;; 直接结束&nbsp; &nbsp; invoke ExitProcess,0&nbsp; main ENDPEND main

C:

#include&nbsp;<stdio.h>#include&nbsp;<windows.h>
int&nbsp;main(int&nbsp;argc,char&nbsp;* argv[]){&nbsp;&nbsp;int&nbsp;var1 =&nbsp;20;&nbsp;&nbsp;int&nbsp;var2 =&nbsp;10;&nbsp;&nbsp;int&nbsp;var3 =&nbsp;50;
&nbsp;&nbsp;if&nbsp;(var1 > var2 || var2 <= var3)&nbsp; {&nbsp; &nbsp;&nbsp;printf("xor eax,eax");&nbsp; }&nbsp;&nbsp;else&nbsp;if(var3 ==&nbsp;50&nbsp;|| var2 >&nbsp;10)&nbsp; {&nbsp; &nbsp;&nbsp;printf("xor ebx,ebx");&nbsp; }&nbsp;&nbsp;return&nbsp;0;}

ASM:

&nbsp;&nbsp;.386p&nbsp; .model flat,stdcall&nbsp; option casemap:noneinclude windows.incinclude kernel32.incincludelib kernel32.lib.data&nbsp; var1 DWORD&nbsp;20&nbsp; var2 DWORD&nbsp;10&nbsp; var3 DWORD&nbsp;50.code&nbsp; main PROC&nbsp; ;&nbsp;if&nbsp;(var1 > var2 || var2 <= var3)&nbsp; &nbsp; mov eax,dword ptr ds:[var1]&nbsp; &nbsp; cmp eax,dword ptr ds:[var2] &nbsp; &nbsp; ; var1 > var2&nbsp; &nbsp; jg L1&nbsp; &nbsp; mov eax,dword ptr ds:[var2]&nbsp; &nbsp; cmp eax,dword ptr ds:[var3] &nbsp; &nbsp; ; var2 <= var3&nbsp; &nbsp; jg L2 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ; 条件是 var2 > var3 则跳转&nbsp; L1:&nbsp; &nbsp;&nbsp;xor&nbsp;eax,eax &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ;&nbsp;printf("xor eax,eax")&nbsp; &nbsp; jmp lop_end&nbsp; L2:&nbsp; ;&nbsp;else&nbsp;if(var3 ==&nbsp;50&nbsp;|| var2 >&nbsp;10)&nbsp; &nbsp; cmp dword ptr ds:[var3],50&nbsp; &nbsp; je L3&nbsp; &nbsp; cmp dword ptr ds:[var2],10&nbsp; &nbsp; &nbsp; ; var2 >&nbsp;10&nbsp; &nbsp; jle lop_end&nbsp; L3:&nbsp; &nbsp;&nbsp;xor&nbsp;ebx,ebx &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ;&nbsp;printf("xor ebx,ebx")&nbsp; &nbsp; jmp lop_end
&nbsp; lop_end:&nbsp; &nbsp; nop&nbsp; &nbsp;&nbsp;int&nbsp;3&nbsp; &nbsp; invoke ExitProcess,0&nbsp; main ENDPEND main

免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:ShadowRoot 高尉峰 高尉峰《逆向工程之内存物理地址》

评论:0   参与:  0