文章总结: 该文档是一篇关于逆向工程中内存物理地址概念的技术文章,核心讲解了x86架构下段寄存器(如DS、CS、SS、ES)的作用、不同内存模型(平坦、保护、实模式)下物理地址的计算方式,并通过C语言与汇编语言的对比示例,展示了条件判断等基本逻辑在两种语言中的实现映射。文章旨在帮助读者理解底层内存访问机制及其在逆向分析中的应用。 综合评分: 68 文章分类: 逆向分析,二进制安全
逆向工程之内存物理地址
原创
高尉峰 高尉峰
ShadowRoot
2026年2月14日 10:59 河北
段寄存器
在x86汇编语言中,DS是Data 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 <stdio.h>#include <windows.h>
int main(int argc,char * argv[]){ int var1 = 20; int var2 = 10; int var3 = 50;
if (var1 >= 20 and var2 <= 100 and var3 == 50) { printf("xor eax,eax"); } return 0;}
ASM:
.386p .model flat,stdcall option casemap:noneinclude windows.incinclude kernel32.incincludelib kernel32.lib.data var1 DWORD 20 var2 DWORD 10 var3 DWORD 50 flag DWORD ?.code main PROC ; if(var1 >= 20 and var2 <= 100 and var3 == 50) cmp dword ptr ds:[var1],20 ; 判断是否大于20 jl L1 ; 不大于则跳转 cmp dword ptr ds:[var2],100 ; 判断是否小于100 jg L1 ; 不小于则跳转 cmp dword ptr ds:[var3],50 ; 判断是否等于50 jne L1 ; 不等于则跳转 mov dword ptr ds:[flag],1 ; 说明等式成立 flag=1 jmp L2 L1: mov dword ptr ds:[flag],0 L2: cmp dword ptr ds:[flag],0 je lop_end ; 为0则跳转,不为0则继续执行 xor eax,eax ; 此处是执行if语句内部 xor ebx,ebx xor ecx,ecx jmp lop_end lop_end: nop ; 直接结束 invoke ExitProcess,0 main ENDPEND main
C:
#include <stdio.h>#include <windows.h>
int main(int argc,char * argv[]){ int var1 = 20; int var2 = 10; int var3 = 50;
if (var1 > var2 || var2 <= var3) { printf("xor eax,eax"); } else if(var3 == 50 || var2 > 10) { printf("xor ebx,ebx"); } return 0;}
ASM:
.386p .model flat,stdcall option casemap:noneinclude windows.incinclude kernel32.incincludelib kernel32.lib.data var1 DWORD 20 var2 DWORD 10 var3 DWORD 50.code main PROC ; if (var1 > var2 || var2 <= var3) mov eax,dword ptr ds:[var1] cmp eax,dword ptr ds:[var2] ; var1 > var2 jg L1 mov eax,dword ptr ds:[var2] cmp eax,dword ptr ds:[var3] ; var2 <= var3 jg L2 ; 条件是 var2 > var3 则跳转 L1: xor eax,eax ; printf("xor eax,eax") jmp lop_end L2: ; else if(var3 == 50 || var2 > 10) cmp dword ptr ds:[var3],50 je L3 cmp dword ptr ds:[var2],10 ; var2 > 10 jle lop_end L3: xor ebx,ebx ; printf("xor ebx,ebx") jmp lop_end
lop_end: nop int 3 invoke ExitProcess,0 main ENDPEND main
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:ShadowRoot 高尉峰 高尉峰《逆向工程之内存物理地址》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。








评论