漏洞银行逆向教程3

Author Avatar
kabeor 3月 31, 2019

标志寄存器

是一个16位的存放条件标志、控制标志寄存器,主要用于反映处理器的状态和ALU运算结果的某些特征及控制指令的执行。

36fbbb3da673e2c9444a194c929333e0.png
87188f5e5b3a0af629a40af69d3cd861.png

53ad6f3b606211295cc0a5bc297e8829.png

各标志在标志寄存器中的位置

条件标志:

  • 进位标志:用于反映运算是否产生进位或借位。如果运算结果的最高位产生一个进位或借位,则CF置1,否则置0。运算结果的最高位包括字操作的第15位和字节操作的第7位。移位指令也会将操作数的最高位或最低位移入CF。

  • 奇偶标志:用于反映运算结果低8位中“1”的个数。“1”的个数为偶数,则PF置1,否则置0。

  • 辅助进位标志:算数操作结果的第三位(从0开始计数)如果产生了进位或者借位则将其置为1,否则置为0,常在BCD(binary-codedecimal)算术运算中被使用。

  • 零标志:用于判断结果是否为0。运算结果0,ZF置1,否则置0。

  • 符号标志:用于反映运算结果的符号,运算结果为负,SF置1,否则置0。因为有符号数采用补码的形式表示,所以SF与运算结果的最高位相同。

  • 溢出标志:反映有符号数加减运算是否溢出。如果运算结果超过了8位或者16位有符号数的表示范围,则OF置1,否则置0。

  • 控制标志:

  • 跟踪标志:当TF被设置位1时,CPU进入单步模式,所谓单步模式就是CPU在每执行一步指令后都产生一个单步中断。主要用于程序的调试。8086/8088中没有专门用来置位和清零TF的命令,需要用其他办法。

  • 中断标志:决定CPU是否响应外部可屏蔽中断请求。IF为1时,CPU允许响应外部的可屏蔽中断请求。

  • 方向标志:决定串操作指令执行时有关指针寄存器调整方向。当DF为1时,串操作指令按递减方式改变有关存储器指针值,每次操作后使SI、DI递减。

ZF标志

ca2d20ee5f093b6db89a1a9d45766815.png

PF标志

ffe582ef099e61015c6549937eddb20a.png

SF标志

a33a3e8eaa2b3a58833971ebf3ab33cb.png

OF标志

5f9609726f77437178c0354a282de0e3.png

adc

ffd4acf6f6e4707500e54b6d31d8af07.png

sbb

47e40b9a5eea33266fe79ff92cd11266.png

cmp指令

16d5aee2eac343bc9ac5e236d7897726.png

8baf906315fa0c7f8b5a99fbe5284d2b.png

TEST命令

9f0c42b96647eb58a5f646a3bf982a4c.png

80386寄存器组

5865d3eef8437cc4dba05130d5b99afe.png

一、通用寄存器

a71d2298fb0a47fce0bc07ef6fbb05dd.png

一组八个通用寄存器是对8086/80286通用寄存器的32位扩展,其用法与在8086/80286中相似,支持8位、16位、32位操作,进行32位操作是,寄存器名称前面冠以“E”。

这八个寄存器的名称如下:EAX(累加器)、EBX(基址)、ECX(计数)、EDX(数据)、ESP(栈指针)、EBP(基址指针)、ESI(源变址)、EDI(目的变址)。

二、段寄存器

975d9b58d813381005c96a9d1df68fab.png

3f785fc97c3c6e46c8502f6941b4bd97.png

80386比8086/80286增加了两个段寄存器FS、GS。

除CS支持代码段,SS支持堆栈段外,程序员可以利用其它的所有段寄存器支持数据段。

每个段寄存器对应这一个64位高速缓存器(有些资料中说有96位,但只使用其中的64位),这在8086中是没有的(在80286中为48位)。

三、指令指针寄存器和标志寄存器

指令寄存器EIP是对8086/80286指令指针寄存器的32位扩展,它包含着待执行指令的32位偏移量,该值总是相对CS所代表的段基址而言的。

标志寄存器也是对8086/80286标志寄存器的32位扩展,其定义如下(这张图截自Intel关于IA32架构的最新文档):

e6e3d0563758721df9c7334caa288eba.jpg

其中OF、DF、IF、TF、SF、ZF、AF、PF和CF在8086中就已经存在,请参考相关资料。

IOPL(I/O Privilege

Level)是从80286开始出现的,占2个bit表示I/O特权级,如果当前特权级小于或等于IOPL,则可以执行I/O操作,否则将出现一个保护性异常。IOPL只能由特权级为0的程序或任务来修改。

NT(Nested

Task)也是从80286开始出现的,表示嵌套任务,用于控制中断返回指令IRET,当NT=0时,用堆栈中保存的值恢复EFLAGS、CS和EIP,从而实现返回;若NT=1,则通过任务切换实现中断返回。

下面的标志位是80386以后的CPU才有的标志。

VM(Virtual-8086

mode)表示虚拟8086模式,如果VM被置位且80386已出于保护模式下,则CPU切换到虚拟8086模式,此时,对段的任何操作又回到了实模式,如同在8086下运行一样。

RF(Resume

flag)表示恢复标志(也叫重启标志),与调试寄存器一起用于断点和单步操作,当RF=1
时,下一条指令的任何调试故障将被忽略,不产生异常中断。当RF=0时,调试故障被接受,并产生异常中断。用于调试失败后,强迫程序恢复执行,在成功执行每条指令后,RF自动复位。

AC(Alignment

check)表示对齐检查。这个标志是80486以后的CPU才有的。当AC=1且CR0中的AM=1时,允许存储器进行地址对齐检查,若发现地址未对齐,将产生异常中断。所谓地址对齐,是指当访问一个字(2字节长)时,其地址必须是偶数(2的倍数),当访问双字(4字节长)时,其地址必须是4的倍数。

但是只有运行在特权级3的程序才执行地址对齐检查,特权级0、1、2忽略该标志。

VIF(Virtual interrupt

flag)表示虚拟中断标志。以下的三个标志是Pentium以后的CPU才有的。当VIF=1时,可以使用虚拟中断,当VIF=0时不能使用虚拟中断。该标志要和下面的VIP和CR4中的VME配合使用。

VIP(Virtual interrupt pending

flag)表示虚拟中断挂起标志。当VIP=1时,VIF有效,VIP=0时VIF无效。

ID(Identification flag)表示鉴别标志。该标志用来只是Pentium

CPU是否支持CPUID的指令。

d2d51f8cf44c9073402b4fa4de1bd344.png

fbe5b69d75e642200f06d86ac1d39c19.png

四、系统地址寄存器

80386

中有4个系统表寄存器,分别是全局描述符表寄存器(GDTR)、中断描述符表寄存器(IDTR)、局部描述符表寄存器(LDTR)、任务状态寄存器(TR)。系统表寄存器用于在保护方式下,管理4
个系统表,由于只能在保护方式下使用,因此又称为保护方式寄存器。

5fa78f20bd62e5c378f9b34f76273328.png

a13531212829ac5260abf241b3a82e4d.png

实模式

ea5b07755098e8e79357a739b6fac0b9.png

它是 Intel公司80286及以后的x86(80386,80486和80586等)兼容处理器(CPU)的一种操作模式。实模式被特殊定义为20位地址内存可访问空间上,这就意味着它的容量是2的20次幂(1M)的可访问内存空间(物理内存和BIOS-ROM),软件可通过这些地址直接访问BIOS程序和外围硬件。实模式下处理器没有硬件级的内存保护概念和多道任务的工作模式。但是为了向下兼容,所以80286及以后的x86系列兼容处理器仍然是开机启动时工作在实模式下。80186和早期的处理器仅有一种操作模式,就是后来我们所定义的实模式。实模式虽然能访问到1M的地址空间,但是由于BIOS的映射作用(即BIOS占用了部分空间地址资源),所以真正能使用的物理内存空间(内存条),也就是在640k到924k之间。1M 地址空间组成是由 16位的段地址和16位的段内偏移地址组成的。用公式表示为:物理地址=左移4位的段地址+偏移地址

保护模式

寻址采用32位段和偏移量,最大寻址空间4GB,最大分段4GB
(Pentium
Pre及以后为64GB)。在保护模式下CPU可以进入虚拟8086方式,这是在保护模式下的实模式程序运行环境。

a4a9ab781ca7531d32f00d7f37c3d711.png

在80286以及更高系列的PC中,即使A20
Gate被打开,在实模式下所能够访问的内存最大也只能为10FFEFH,尽管它们的地址总线所能够访问的能力都大大超过这个限制。为了能够访问10FFEFH以上的内存,则必须进入保护模式。

(286是Intel 80286的另一种叫法) 它又被称作为虚拟地址保护模式。尽管在Intel
80286手册中已经提出了虚地址保护模式,但实际上它只是一个指引,真正的32位地址出现在Intel
80386上。保护模式本身是80286及以后兼容处理器序列之后产成的一种操作模式,它具有许多特性设计为提高系统的多道任务和系统的稳定性。例如内存的保护分页机制硬件虚拟存储的支持。现代多数的x86处理器操作系统都运行在保护模式下,包括Linux,
Free BSD, 和Windows3.0(它也运行在实模式下,为了和Windows
2.x应用程序兼容)及以后的版本。

实模式和保护模式的区别

从表面上看,保护模式和实模式并没有太大的区别,二者都使用了内存段、中断和设备驱动来处理硬件,但二者有很多不同之处。我们知道,在实模式中内存被划分成段,每个段的大小为 64KB ,而这样的段地址可以用 16 位来表示。内存段的处理是通过和段寄存器相关联的内部机制来处理的,这些段寄存器( CS 、 DS 、 SS 和ES )的内容形成了物理地址的一部分。具体来说,最终的物理地址是由 16 位的段地址和 16 位的段内偏移地址组成的。用公式表示为:物理地址 = 左移 4 位的段地址 + 偏移地址。

在保护模式下,段是通过一系列被称之为 “ 描述符表 ” 的表所定义的。段寄存器存储的是指向这些表的指针。用于定义内存段的表有两种:全局描述符表 (GDT) 和局部描述符表 (LDT) 。 GDT 是一个段描述符数组,其中包含所有应用程序都可以使用的基本描述符。在实模式中,段长是固定的 ( 为 64KB) ,而在保护模式中,段长是可变的,其最大可达 4GB 。LDT 也是段描述符的一个数组。与 GDT 不同, LDT 是一个段,其中存放的是局部的、不需要全局共享的段描述符。每一个操作系统都必须定义一个 GDT ,而每一个正在运行的任务都会有一个相应的 LDT 。每一个描述符的长度是 8 个字节,格式如图 3 所示。当段寄存器被加载的时候,段基地址就会从相应的表入口获得。描述符的内容会被存储在一个程序员不可见的影像寄存器 (shadow
register) 之中,以便下一次同一个段可以使用该信息而不用每次都到表中提取。物理地址由 16 位或者 32 位的偏移加上影像寄存器中的基址组成。实模式和保护模式的不同可以从下图很清楚地看出来。

实模式地址

283ccbe56e2f203c838f1731936bfc38.jpg

保护模式地址

ca5d768386e99ceaa5930ef3c2b68b93.jpg

保护模式同实模式的根本区别是进程内存受保护与否。可寻址空间的区别只是这一原因的果。实模式将整个物理内存看成分段的区域,程序代码和数据位于不同区域,系统程序和用户程序没有区别对待,而且每一个指针都是指向”实在”的物理地址。这样一来,用户程序的一个指针如果指向了系统程序区域或其他用户程序
区域,并改变了值,那么对于这个被修改的系统程序或用户程序,其后果就很可能是灾难性的。为了克服这种低劣的内存管理方式,处理器厂商开发出保护模式。这
样,物理内存地址不能直接被程序访问,程序内部的地址(虚拟地址)要由操作系统转化为物理地址去访问,程序对此一无所知。

0cf80a18ac54b1fe9e22f774ed60e4dc.png

1、RPL 选择子当中的权限位确定的权限

2、CPL 特指CS中的选择子当中的权限位确定的权限

3、EPL EPL=Max(RPL,CPL),即RPL和CPL中数值较大的,或说权限等级较小的

4、DPL 描述符中的权限位确定的权限

5、PL 泛指以上4种特权级

6、任务特权 =CPL

7、I/O特权 由EFLAGS寄存器的位13、14确定的权限

8、一致代码段 一种特殊的代码段,它在CPL>=DPL时允许访问

正常的代码段在CPL=DPL RPL\<=DPL时才允许访问

五、控制寄存器

80386的控制寄存器有4个,其中CR1保留以后使用,从Pentium开始,又增加了一个CR4,CR0的低16位包含了与80286的MSW一致的位定义,保持了和80286的兼容,同时也兼容了从80286开始的两条指令LMSW/SMSW,其基本定义如下:

29800129903fc3ff4db840b72cb129be.jpg

CR0中各位含义如下:
  • PE(Protection
    Enable)保护模式允许,PE=0表示CPU工作在实模式,PE=1表示CPU工作在保护模式

  • MP(Monitor
    Coprocessor)监控协处理器,MP=1表示协处理器在工作,MP=0表示协处理器未工作。

  • EM(Emulation)协处理器仿真,当MP=0,EM=1时,表示正在使用软件仿真协处理器工作。

  • TS(Task
    Switched)任务转换,每当进行任务转换时,TS=1,任务转换完毕,TS=0。TS=1时不允许协处理器工作。

    以上4个定义从80286开始,下面的2个定义从80386开始存在

  • ET(Extension
    Type)处理器扩展类型,反映了所扩展的协处理器的类型,ET=0为80287,ET=1为80387。

  • PG(Paging)页式管理机制使能,PG=1时页式管理机制工作,否则不工作。

    从80486开始又增加了如下位定义。

  • NE(Numeric
    Error)数值异常中断控制,NE=1时,如果运行协处理器指令发生故障,则用异常中断处理,NE=0时,则用外部中断处理。

  • WP(Write Protect)写保护,当WP=1时,对只读页面进行写操作会产生页故障。

  • AM(Alignment
    Mask)对齐标志,AM=1时,允许对齐检查,AM=0时不允许,关于对齐,在EFLAGS的AC标志时介绍过,在80486以后的CPU中,CPU进行对齐检查需要满足三个条件,AC=1、AM=1并且当前特权级为3。

  • NW(Not Write-through)和CD(Cache
    Disable),这两个标志都是用来控制CPU内部的CACHE的,当NW=0且CD=0时,CACHE使能,其它的组合说起来比较复杂,如果有读者真的想搞清楚的话,可以参阅《Intel?
    64 and IA-32 Architectures》中的“Software Developer’s Manual Volume
    3A”这一册,在第10章对这两个标志的各种组合有比较详细的说明。

CR1保留未用;CR2存放引起页故障的线性地址,只有在PG=1时,CR2才有效,当页故障处理程序被激活时,压入页故障处理程序堆栈中的错误码提供页故障的状态信息。

CR3的bit12–bit31存放页目录的基地址,因为也目录总是页对齐的(一页为4K),所以页目录基地址从bit12开始就可以了。只有当CR0中的PG=1时,CR3的页目录基地址才有效。
从80486开始,在CR3的低12位定义了两个控制位,如下:

  • PCD(Page-level Cache
    Disable)页CACHE禁止,当PCD=0时,页目录表进行高速缓存,PCD=1时,不进行高速缓存;该位控制PCD引脚控制外部CACHE工作还是不工作。

  • PWT(Page-level Writes
    Transparent),CACHE的写入分为透写(Write-Through)和回写(Write-Back),80486以上的CPU内部的CACHE都是透写的,但对外部CACHE而言,允许某些页是回写的,而另一些页是透写的,当PWT=1时,外部CACHE对页目录进行透写,否则进行回写;此位驱动PWT引脚以控制外部CACHE是透写还是回写。

    CR4是从Pentium CPU开始出现的。

  • VME(Virtual-8086 Mode
    Extensions)虚拟8086方式扩展,VME=1允许使用虚拟8086扩展模式,否则只能使用80386/80486的虚拟8086模式。

  • PVI(Protected-Mode Virtual
    Interrupts)保护模式虚拟中断,PVI=1时,在保护模式下支持虚拟中断标志VIF(EFLAGS中),PVI=0则不支持虚拟中断标志。

  • TSD(Time Stamp
    Disable)时间戳禁止,TSD=1时,允许在特权级为0的程序中执行RDTSC指令(读时间戳计数指令),TSD=0时,允许任何特权级执行RDTSC指令。

  • DE(Debugging Extensions)调试扩展,

  • PSE(Page Size
    Extensions)页大小扩展,PSE=1时,页大小可以扩展到2M或4M,PSE=0时,页大小只能是4K.

  • PAE(Physical Address
    Extension)物理地址扩展,PAE=1时,页物理地址可以扩展到36bits以上,PAE=0时只能用32bits的物理地址。

  • MCE(Machine-Check
    Enable)硬件检查使能,Pentium以后的CPU有一种硬件检测功能,MCE=1时允许使用该功能。

  • PGE(Page Global
    Enable)全局页使能,PGE=1时,允许使用全局页,PGE=0时禁止使用全局页。

  • PCE(Performance-Monitoring Counter
    Enable)性能监视计数器使能,当PCE=1时,允许在任何保护级下执行RDPMC指令,PCE=0时,只有特权级0的程序可以执行RDPMC指令。

  • OSFXSR(Operating System Support for FXSAVE and FXRSTOR instructions)

  • OSXMMEXCPT(Operating System Support for Unmasked SIMD Floating-Point
    Exceptions)

  • VMXE(VMX-Enable Bit)VMX使能位,VMXE=1时,允许VMX操作。

  • SMXE(SMX-Enable Bit)SMX使能位,SMXE=1时,允许SMX操作。

  • OSXSAVE(XSAVE and Processor Extended States-Enable Bit)

六、调试寄存器

一共有8个调试寄存器DR0–DR7,DR0-DR3可以分别设置4个断点的线性地址,DR4-DR5保留未用,DR6是断点状态寄存器,DR7是断点控制寄存器(包括断点类型、断点长度,断点开放/禁止)

七、测试寄存器

一共有8个测试寄存器TR0–TR7,TR0-TR2保留,TR3-TR5用作CACHE测试,TR6为命令测试寄存器,TR7为测试数据寄存器。

数据传送指令

0c47a83640959d7c625818e1b694e5d8.png
ccba9090b3091d3df2a18e808da4819c.png
9a5ce8b3ce516dd8bb9bc5135500767a.png
6beecf08059e0448b89b1da58cb89d9b.png
68ed70d33227e087747326a980e9ac71.png
ff7c1f365ec61dce1ff59085006e4c8d.png
d973137fc7bce212251bdef43ff1c6bd.png
80ea7f2725c3c6a38f5150661f597c69.png
9f455c0ea3981c6c955982c39fd9af12.png

算术运算指令

1f03d065699c062e4a935ff21c4ea93c.png
d20668bdc119c5ee4413ffe57bf726f3.png
453e1347cc9676c7d7fc30cbdb5335b9.png
97a053548fe6d902d09a54e571a82bfa.png
060f4fb3226c2727e6a0d686454edcc6.png
44ba5dc30cc16e227687804cd6bc42e3.png
ae291f4a22042cec9286e1e5e188b37c.png
914d2c2494e0d9ec4a64ead1e2e2b4f6.png
ef08185ae80a94473e79b3fd145bd0c2.png
b35e8a6208468e90fe54addc38e84f16.png

商和余数都放2字节

From https://kabeor.github.io/漏洞银行逆向教程3/ bye

This blog is under a CC BY-NC-SA 4.0 Unported License
本文链接:https://kabeor.github.io/漏洞银行逆向教程3/