精华内容
下载资源
问答
  • 段寄存器

    2021-01-15 12:46:20
    一、段寄存器有哪些 ? 段寄存器有ES、CS、SS、DS、FS、GS、LDTR、TR共8个。 通常我们用汇编读写某一个地址时,如下: Mov dword ptr ds:[0x123846],eax 这时我们把eax 的值往地址去写,写的地址是: ds.base +...

    一、段寄存器有哪些 ?

    段寄存器有ESCSSSDSFSGSLDTRTR8个。

    ES:扩展段。在串操作时(比如cmovs)目标操作数的基址是ES,源操作数是DS

    CS:代码段,配合EIP使用。

    SS: 堆栈段,凡是基址是EBPESP的,段前缀就是SS

    DS:数据段,默认的都是DS

    FSGS80386 之后定义的。

    段寄存器结构:

    段寄存器的大小是 96 位

    段寄存器结构可以抽象成以下结构

    struct Segment

    {

      WORD Selector;  //16位段选择子,可见部分.  使用OD 或者X64dbg看段寄存器只会显示16位的段选择子可见部分.当读段寄存器(如mov ax,CS)的时候,只会返回这16位。或者push seg 操作针对的都是这16位。如果目标操作数是32位(如mov eax ,CS),则将16位零扩展成32位赋给目标操作数。但是写的时候,就会涉及到96位

      WORD Attribute; //16位表示的段属性, 表示了当前段寄存器是可读的可写的还是可执行的

      DWORD Base;     //32位表示的基址,表示段从哪里开始

      DWORD limit;    //32位表示,表示的是基址的长度. base + limit 可以确定一个段的大小

    }

    在x86下.我们可以看如下寄存器表示图.

    寄存器名称

    段选择子(Select)

    段属性(Attributes)

    段基址(Base)

    段长(Limit)

    ES(附加扩展段)

    0x0023

    可读,可写

    0x00000000

    0xFFFFFFFF

    CS(代码段)

    0x001B

    可读,可写

    0x00000000

    0xFFFFFFFF

    SS(堆栈段)

    0x0023

    可读,可写

    0x00000000

    0xFFFFFFFF

    DS(数据段)

    0x0023

    可读,可写

    0x00000000

    0xFFFFFFFF

    FS(分段机制)

    0x003B

    可读,可写

    0x7FFDF000

    0xFFF

    GS

    未使用

    未使用

    未使用

    未使用

     

    二、段寄存器读写

    可以使用MOV指令对段寄存器进行读写。

    读操作时,可以读到段寄存器的段选择子部分的16位。例如 mov ax,es 指令会把es寄存器的段选择子读到ax。

    写操作时,会写入96位,其中源操作数的16位写入到段寄存器的段选择子部分,另外80位会根据段选择子从GDT表(全局描述表)中获取。因此,

    1 .mov ax,cs

    2. mov ds,ax

    实际上是把cs完整的复制给了ds。

    三、段属性探测

    CS代码段属性探测

    int Var = 0;

    int main()

    {  

        __asm   

        {      

            mov ax,cs      

            mov ds,ax       

            mov dword ptr ds:[Var],eax         ;等价于 mov dword ptr cs:[Var],eax  

        }

    }

    将CS赋值到AX中. AX赋值给DS. 此时DS就代表CS了. 如果以把eax之给 CS.则会出现错误.

    说明权限确实是不可写.

    其它代码段段属性探测

    int Var = 0; int main()

    {   

        __asm   

        {       

            mov ax,ss

            mov ds,ax       

            mov dword ptr ds:[Var],eax   

        }

    }

    段基地址探测

    通常我们用汇编读写某一个地址时,如下:
    Mov dword ptr ds:[0x123846],eax
    这时我们把eax 的值往地址去写,写的地址是:
    ds.base + 0x123456

    int main()

    {

        __asm

        {

            mov ax,fs

            mov gs,ax

            mov eax,gs:[0]

        }

    }

    段长探测

    在段地址探测中,访问有效地址等价于段.base + 偏移地址

    int main()

    {

        __asm

        {

            mov ax, fs

            mov gs, ax

            mov eax, gs: [0]  //fs.base + 0 读取

            mov eax,gs:[0x1000]//fs.base + 0x1000

            mov eax, dword ptr ds : [eax + 0xFFF] ;

           // mov eax,gs:[0x1000] //fs.base + 0x1000 读取

        

        }

    }

    展开全文
  • 32位的处理器运行在保护模式下时,除了先前的4个段寄存器,还引入了两个新的段寄存器FS/GS,这些寄存器都是16比特位宽。64位模式下的段寄存器有特殊性,后面有一节介绍。 IA-32处理器中的段寄存器(C...

    Segment Registers

    本节主要讲述Intel处理器中的段寄存器,用于支持处理器的段式存储器管理机制。16位的8086/Intel286处理器有4个段寄存器CS/DS/SS/ES。32位的处理器运行在保护模式下时,除了先前的4个段寄存器,还引入了两个新的段寄存器FS/GS,这些寄存器都是16比特位宽。64位模式下的段寄存器有特殊性,后面有一节介绍。

    IA-32处理器中的段寄存器(CS/DS/ES/SS/FS/GS)用于保存16位宽的段选择符(segment selector)。要访问存储器中的特定段,对应的段选择符必须要加载到正确的段寄存器中。

    当设计应用程序代码时,程序员通常使用汇编器的指示符和符号(directives and symbols)来创建段选择符。汇编器和其他的工具软件会根据这些指示符和符号生成真正的段选择符值。如果是设计系统程序代码,程序员则可以直接创建段选择符(以后有专题介绍)。

    段寄存器如何被使用主要取决于操作系统/管理软件采用的存储器管理模型的类型。

    当使用平坦(未分段的)存储器模型时,段寄存器加载的段选择符指向重叠的段,在线性地址空间中,每个段的起始地址都是0(参看下图)。这些重叠的段构成了程序可见的线性地址空间。通常,会定义两个重叠的段:一个是代码段,另一个是数据/栈段。CS寄存器指向代码段;其他的所有段寄存器指向数据/栈段。

     

    当使用分段存储器模型时,每个段寄存器通常会加载不同的段选择符,这样段寄存器指向线性地址空间中不同的段(参看下图)。任何时候,程序可以同时访问线性地址空间中最多6个段。如果要访问的段没有段寄存器指向,程序必须先将段对应的段选择符加载到某个段寄存器之后,才可以访问段中的数据。

    每个段寄存器都关联下列三种存储类型(即段类型)之一:代码段,数据段,栈段。例如,CS段寄存器包含代码段的段选择符,代码段保存正在执行的指令。处理器从代码段读取指令时,使用有CS寄存器中的段选择符与EIP寄存器联合构成的逻辑地址。EIP保存要执行的下一条指令在代码段中的偏移量。CS寄存器不能有应用程序显式地的加载。相反,可以通过某些指令或处理器内部操作隐式地加载。这些指令/内部操作,例如过程调用,中断处理,或者任务切换,用于改变程序的执行流,从而导致更新CS寄存器。

    DS/ES/FS/GS这四个寄存器指向四个数据段。多个数据段的存在允许高效地且安全地访问不同的数据结构类型。例如,可以创建如下的四个数据段:第一个数据段保存当前程序模块的数据结构,第二个数据段保存更高级别程序模块导出的数据,第三个数据段保存动态创建的数据结构,最后一个数据段保存另一个程序共享出来的数据。要想访问更多的数据段,应用程序必须按需将数据段对应的段选择符加载到DS/ES/FS/GS寄存器中的其中一个当中。

    SS寄存器包含栈段的段选择符,这里栈段用于存储程序/任务/当前正在执行的处理器程序的栈帧。所有的栈操作都使用SS栈段寄存器来定位栈段。与CS代码段寄存器不同,SS寄存器可以显式地加载,这样就允许应用程序建立多个栈段,并在这些段间切换。

    Segment Registers in 64-Bit Mode

    在64位模式下:处理器把CS/DS/ES/SS的段基都当作0,忽略与之关联的段描述符中的段基地址。这样就为代码/数据/栈创建了平坦的地址空间。但是FS/GS段寄存器是例外。在计算线性地址时,这两个段寄存器可能被用作额外的基址寄存器(当寻址局部数据或寻址某些操作系统数据结构时)。

    尽管分段机制被禁用了,但是段寄存器加载操作可能导致处理器执行段访问辅助。在这些辅助行为中,启用了分段机制的处理器依然会对被加载的值执行绝大多数的传统检查(即使这些检查对64位模式不起作用)。这样的检查是必要的,因为在64位模式下加载的段寄存器可能被运行在兼容模式的应用程序使用。

    在64位模式下,禁用CS/DS/ES/SS/FS/GS的段限长检查。

    展开全文
  • 段地址和段寄存器

    2020-09-16 10:45:28
    1、8086外部提供了20位的地址总线,CPU内部只能提供16位地址 两个16位地址转换为20位 地址加法器合成物理地址的方法: ...CS、DS、SS、ES当8086要访问内存时,由这4个段寄存器提供内存单元的段地址 CS和IP是.

    1、8086外部提供了20位的地址总线,CPU内部只能提供16位地址

    两个16位地址转换为20位

    地址加法器合成物理地址的方法:

    物理地址 = 段地址*16 + 偏移地址(16进制数*16就是向左移动一位)

    在8-86PC机中,存储单元的地址用两个元素来描述。即段地址和偏移地址

    段地址随意定义只要找到物理地址就行

     2、段寄存器

    段寄存器就是提供段地址的

    8086CPU有4个段寄存器

    CS、DS、SS、ES当8086要访问内存时,由这4个段寄存器提供内存单元的段地址

    CS和IP是8086CPU中最关键的寄存器,他们指示了CPU当前要读取指令的地址

    CS代码段寄存器

    IP指令指针寄存器(偏移地址的寄存器)

    //所以可以通过改变CS IP中的neir来控制CPU执行目标内容,如何改变CS IP

    不可以用MOV AX,123

    转移指令:JMP 2AE3:3(专用指令)

    仅仅修改IP:

    MOV AX,200

    JMP BX

    JMP AX

    上面是用寄存器中的值修改IP

    代码段

    对于8086PC机,可以根据需要将一组内存单元定义为一个段

    可以将长度为N的一组代码存放在一组地址连续的、起始地址为16的倍数的内存单元中,这段内存是用来存放代码的从而定义一个代码段。

     

     

     

     

     

     

     

    展开全文
  • 对于段寄存器/标志位寄存器/指令指针...段寄存器首先帖一下各个段寄存器和对应的含义CS:Code Segement,代码段寄存器SS:Stack Segment,栈段寄存器DS:Data Segment,数据段寄存器ES:Extra(Data) Segment,数...

    66d4f054d6be0f2c7e33fa3f32cf0a3a.png

    对于段寄存器/标志位寄存器/指令指针寄存器

    对于这几个寄存器我们这里简单的介绍一下,在刚接触这几个寄存器的时候,并不用说非常深入的研究这几个寄存器,等积累到一定后,就很好理解了。

    段寄存器

    首先帖一下各个段寄存器和对应的含义

    • CS:Code Segement,代码段寄存器
    • SS:Stack Segment,栈段寄存器
    • DS:Data Segment,数据段寄存器
    • ES:Extra(Data) Segment,数据段寄存器
    • FS:Data Segment,数据段寄存器
    • GS:Data Segment,数据段寄存器

    这里的用法就是不同的段代表了不同区域,最常见的就是数据段取值ds:[]和栈段取值ss:[],如图下OD中的汇编指令就是从数据段ds:[]中取值。这里重点在哪里呢?其实只要知道汇编指令中ds:[]这些是从那个段里取值就行,常见的如ss:[],ds:[]。这里的难点是fs寄存器,它用于SEH、PEB、TEB这些,不过这些都是之后的内容,大家这里知道就行。

    d38ef503453b64db0bcee6a717500a83.png
    从ds数据段中取值

    标志位寄存器

    标志位寄存器算是比较难以理解的一个部分了,首先标志位寄存器是4字节大小的寄存器,而它的每个位都包含了不同含义

    1bda29d33a52ad8e63757cd4f17e6acc.png
    逆向工程核心原理中标志位寄存器图

    OD中列出了几个比较总要的标志位如下(逆向工程师偷师一下别人的资料):

    • CF:若算术操作产生的结果在最高有效位(most-significant bit)发生进位或借位则将其置1,反之清零。这个标志指示无符号整型运算的溢出状态,这个标志同样在多倍精度运算(multiple-precision arithmetic)中使用。
    • PF:如果结果的最低有效字节(least-significant byte)包含偶数个1位则该位置1,否则清零。
    • AF:如果算术操作在结果的第3位发生进位或借位则将该标志置1,否则清零。这个标志在BCD(binary-code decimal)算术运算中被使用。
    • ZF:若结果为0则将其置1,反之清零。
    • SF:该标志被设置为有符号整型的最高有效位。(0指示结果为正,反之则为负)
    • TF:将该位设置为1以允许单步调试模式,清零则禁用该模式。
    • DF:这个方向标志(位于EFLAGS寄存器的第10位)控制串指令(MOVS, CMPS, SCAS, LODS以及STOS)。设置DF标志使得串指令自动递减(从高地址向低地址方向处理字符串),清除该标志则使得串指令自动递增。STD以及CLD指令分别用于设置以及清除DF标志。
    • OF:如果整型结果是较大的正数或较小的负数,并且无法匹配目的操作数时将该位置1,反之清零。这个标志为带符号整型运算指示溢出状态。

    看了上面这些可能会有点懵,我们这里主要就说一下ZF、OF和CF这几个标志位,还是来一个实际例子来看看

    #include<stdio.h>
    #include<Windows.h>
    
    int main()
    {
    	int i = 1;
    	if (i == 1)
    	{
    		unsigned int a = 0xFFFFFFF5;	//无符号整型最大为0xFFFFFFFF,加0x25溢出
    		unsigned int b = 0x00000025;
    		unsigned int c = a + b;
    
    		int d = 0x7FFFFFF0;		//有符号整型最大为0x7FFFFFFF,加0x25溢出
    		int e = 0x00000025;
    		int f = d + e;
    	}
    
    	return 0;
    }
    

    首先就是最简单的1=1的问题了,cmp指令就是“local.2-0x1”,这个汇编指令并不会改变local.2的值,那这里的运算用来做什么呢?其实就类似于if判断,然后这个判断用什么来标识结果呢?其实就是ZF标志位,ZF是当结果位0时置1,这里“local.2-0x1”运算结果为零,所以ZF置1,然后再结合下面的jnz就是完整的一个判断了。而jnz就是ZF=0时才实现跳转,至于jz/jnz这些跳转,我们这里可以暂时不用管,以后会列举出所有的跳转再慢慢对比。

    fb1dfba8c7be210c7eb02e6482b6f94c.png
    判断设置ZF标志位

    然后就是CF和OF,CF是无符号整型溢出置1,OF是有符号整型溢出置1

    4e2d3d46c51b97203ce081e2efedcf00.png
    无符号溢出设置CF标志位

    9fda567c5ad0f4a52626d44c5534adfd.png
    有符号溢出设置OF标志位

    这里就简单的列举了3个例子,还有其他的大家可以自己写代码来测试一下

    指令指针寄存器

    所谓的指令指针寄存器就是我们用OD时最常见的eip,它指向的就是我们将要运行的汇编指令,而这里我们知道这个就行。下图就是我们运行完了0096DB63处的mov ebp,esp后,eip就指向了0096DB65

    5de865418d209c2193007cf3268185e3.png
    寄存器窗口的eip和汇编代码窗口的eip

    参考

    <<逆向工程核心原理>>

    x86—EFLAGS寄存器详解:https://blog.csdn.net/jn1158359135/article/details/7761011

    展开全文
  • 01 段寄存器

    2019-01-15 20:56:15
    引言:要学习保护模式中段的机制,首先就要学习段寄存器。 首先,我们来看一下下面这段代码: mov dword ptr ds:[0x123456],eax 在上面我们真正读写的地址是:ds.base + 0x123456 代码中的ds就是我们这里要介绍...
  • 中级 段寄存器

    2020-05-15 22:00:26
    段寄存器:ES SS CS DS FS GS LDTR TR ​ 读和写的区别 读:只能读16位bit: mov ax,ds 写:写的是96位bit: mov ds,ax 1.怎么证明有段寄存器有96bit? 2.写段寄存器的时候,只写了16bit?剩下的80bit呢? struct ...
  • 2.9 段寄存器

    2019-07-08 23:12:00
    段寄存器就是提供段地址的 8086CPU有4个段寄存器: CS(代码地址)、DS(数据地址)、SS(堆栈地址)、ES(什么地址都有,前面三个不够放就放这) 当8086CPU要访问内存时,由这4个段寄存器提供内存单元的段地址...
  • 02段寄存器

    2017-08-20 13:25:00
    段寄存器: 在使用汇编写某个地址时:mov dword ptr ds:[0x123456],eax 其实我们真正读写的地址是:ds.base + 0x123456 而段寄存器共有八个 分别为: ES CS SS DS FS GS LDTR TR 2.段寄存器的结构. ...
  • 段式存储管理 计算机需要对内存进行分段,以分配给不同的程序使用 段式存储与页式存储不同,段的大小不定,段内...以下段寄存器均为8086CPU中的情况: 四个段寄存器(16位): CS:代码段寄存器 DS:数据段寄存器 SS
  • 2.9段寄存器

    千次阅读 2017-04-06 11:41:20
    我们前面讲到,8086CPU...段地址在8086CPU的段寄存器中存放。8086CPU有4个段寄存器:CS、DS、SS、ES。当8086CPU要访问内存时,由这4个段寄存器提供内存单元的段地址。本章只看一下CS。    问:段寄存器是什么?  
  • 8086段寄存器

    2020-08-21 14:20:20
    8086的访问内存的时候:物理地址=段地址×16+偏移地址,这个段地址由段寄存器来提供。8086有4个段地址寄存器,分别是CS,DS,ES,SS。其中CS是最为关键的,因为CS:IP指示了CPU需要读取的地址。IP是指令指针寄存器,...
  • 汇编语言--段寄存器

    万次阅读 2020-09-08 21:53:12
    我们可以将一段内存定义为一个段,用一个段地址指示段,用偏移地址访问段内的单元,可以用分段的方式来管理内存。 ... 段寄存器:8086CPU有4个段寄存器:CS、DS、SS、ES,提供内存单元的段地址 ...
  • 段寄存器结构基础

    2021-03-18 11:01:36
    1、段寄存器结构 Segment{ WORD Selector; //段选择子(可见)16位 WORD Attributes; //段属性 (不可见)16位 WORD Base; //段起始地址(不可见)32位 WORD Limit; // 段大小(不可见)32位 } 段寄存器总...
  • 2-段寄存器

    千次阅读 多人点赞 2016-09-14 14:50:05
    段寄存器 段寄存器有96位 段寄存器数据来源从 ds 说起如果你稍稍懂一点汇编,当你执行下面这行代码的时候,它会把 32 位整数 5 写入到地址 0x0012f000 这个位置处。dword 就表示这是一个 double word 宽度的数,一个...
  • 段选择符 段寄存器

    2016-08-31 19:39:35
    突然在书上看到CS、DS、SS、ES叫做段选择符,不知所云,...在80386中,有6个16位的段寄存器,但是,这些段寄存器中存放的不再是某个段的基地址,而是某个段的选择符(Selector)。因为 16位的寄存器无法存放32位的
  • 读一个段寄存器只读16位,写一个段寄存器写96位 Struct SegMent{ WORD Selector;//16位selector WORD Attribute;//16位的Attribute WORD Base;//32位的Base DWORD Limit //32位的Limit }; 可以通过MOV指令对...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 8,878
精华内容 3,551
关键字:

段寄存器