【reverse】逆向5 标志寄存器
【reverse】逆向5 标志寄存器
1、引言
通过一个creak.exe文件的爆破,引出现阶段需要学习的知识

2、标志寄存器

标志寄存器有上图这么多个
记住这几个寄存器的位置和名称
下面是6个状态标志位
1.进位标志CF(Carry Flag)
如果运算结果的最高位产生了一个进位或者借位,那么其值为1,否则为0
做个实验
我们先给eax一个5555FFFF的数据,然后再加1

然后将c变成0

运行这两句汇编
发现eax虽然进位了,但不是最高位进位,因为eax是32位的

我们再试一试al

把所有标记寄存器归为0
运行这两句汇编

al是FF,加1之后溢出,但是实际上最高位也就是第八位,进位了,所以c为1
所以,一定要注意是最高位
2. 奇偶标志PF(Parity Flag)
奇偶标志PF用于反映运算结果中最低有效字节中“1”的个数的奇偶性
注意是最低有效字节,也就是只看最后两位
如果“1”的个数为偶数,则PF的值为1,反之为0(一定转为二进制来看)
我们运行下面的指令

首先将al赋值0
然后让al+0x3
hex中0+3 = 3
转为2进制,3 = 0011,有两个1,所以p为1

再执行+3的指令
hex中3+3 = 6
转为2进制,6 = 0110,有两个1,所以p为1

再执行+2的指令
hex中6 + 2 = 8
转为2进制,8 = 1000,只有1个1,所以p=0

3.辅助进位标志AF(Auxiliary Carry Flag)
发生下列情况的时候,辅助进位标志AF的值被置为1,否则为0
- 在字操作时,发生低字节向高字节进位或者借位时
 - 再字节操作时,发生低4位向高4位进位或者借位时
 
看我绿笔画的圈,这个位置的数进不进位,进位就是1,否则是0



4.零进位标志ZF(Zero Flag)
零标志位ZF用来反映运算结果是否为0
如果运算结果为0,ZF=1,否则为0
mov指令不算运算
看这句指令,让eax和自己异或,两个相同的数字异或=0,所以计算结果为0,所以ZF= 1


5.符号标志SF(Sign Flag)
符号标志SF用来反映运算结果的符号位,它与运算结果的最高位相同
首先确定一点,mov指令不影响标志寄存器
第一句汇编,让al存0x7F (0111 1111)
第二句汇编,让al+2

0111 1111 + 0000 0010 = 1000 0001
符号位(也就是从左向右第一位)运算后是1,所以SF=1

6.溢出标志OF(Overflow Flag)
溢出标志OF用于反映有符号数加减运算所得结果是否溢出
如果运算结果超过当前运算位数所能表示的范围,则称为溢出,OF的值置为1,否则OF的值被清为0
如何辨别CF和OF?
CF是最高位进位,而OF时有符号数的溢出
有符号数的范围:
- 正数:0~7F
 - 负数:FF~80
 
有无符号是程序员代码规定的,不是计算机规定的,计算机内相同的数——FF,如果是有符号,那就是-1,如果无符号,那就是15


举几个例子
8位,无符号范围是0~FF
有符号数的范围:正数:0~7F;负数:FF~80
无符号、有符号都不溢出
mov al,8
add al,8
无符号溢出,有符号不溢出(-1+2)
mov al,0xff
add al,2
无符号不溢出(小于FF),有符号溢出(最大的正数还+2,溢出,成为负数)
mov al,7f
add al,2
无符号(大于FF)、有符号(最小的负数还加负数,两负数相加得到正数)都溢出
mov al,0xfe
add al,0x80
然后计算机最底层的处理OF标志其实是这样的:
- 判断符号位是否有进位,有进位,标志1,无进位,标志0
 - 判断最高有效数值位向符号位产生进位否,有进位,标志1,无进位,标志0
 - 将第一步和第二部得到的数字xor一下,得到的数字就是OF标志位的数字
 
我们看下面这个例子(OF的前提是必须是有符号数)

3、指令
1.ADC指令
adc指令就是带进位的加法(这个进位就看CF进位标志,是1就进位,0就不进)
格式:adc R/M,R/M/IMM
R是寄存器,M是内存,IMM是立即数
两边不能同时为内存,且宽度要一样
adc al,cl
adc byte ptr ds:[12ffc4],2
adc byte ptr ds:[12ffc4],al
2.SBB指令
sbb就是带借位的减法(借位也是看CF标志,是1就借位,反之不借)
格式:adc R/M,R/M/IMM
R是寄存器,M是内存,IMM是立即数
两边不能同时为内存,且宽度要一样
sbb al,cl
sbb byte ptr ds:[12ffc4],2
sbb byte ptr ds:[12ffc4],al
3.XCHG指令
xchg指令是交换数据的指令
格式:XCHG R/M,R/M 两边不能同时为内存,宽度要一样
xchg al,cl
xchg dword ptr ds:[12ffc4],eax
xchg byte prt ds:[12ffc4],al
4.MOVS指令
movs指令是移动数据的指令,这个指令必须对edi和esi使用
这个指令有点特殊,我们之前学习的指令都是不能两边同时为内存的
但是这个指令,他必须两边都是内存,且都是edi和esi使用的!
movs byte ptr es:[edi],byte ptr ds:[esi]	简写为:movsb
movs word ptr es:[edi],word ptr ds:[esi]	简写为:movsw
movs dword ptr es:[edi],dword ptr ds:[esi]	简写为:movsd
movsb:移动esi中地址数据到edi中,同时esi、edi都加1
movsw:移动esi中地址数据到edi中,同时esi、edi都加2
movsd:移动esi中地址数据到edi中,同是esi、edi都加4
esi和edi的加和减是由DF标志寄存器决定的,DF=0就是加,DF=1就是减
5.STOS指令
stos指令是将al/ax/eax的值存到[edi]指定的内存单元
stos byte ptr es:[edi]		简写为stosb
stos word ptr es:[edi]		简写为stosw
sots dword ptr es:[edi]		简写为stosd
存哪个寄存器由是数据宽度决定的
byte是al
word是ax
dword是eax
同样的
edi的加和减是由DF标志寄存器决定的,DF=0就是加,DF=1就是减。
加减的值也是和位数相关
byte +- 1
word +- 2
dword +- 4
6.REP指令
按计数寄存器 (ECX) 中指定的次数重复执行字符串指令
mov ecx,10
rep movsd
rep stosd
这里给ecx存10是hex形式,所以循环了16次
rep movsd就是循环16次将esi的值赋给edi,当然,因为刚刚我们提到了DF标志位,所以会根据DF的值来自增或自减。这里是dword,所以是+-4
rep stosd就是将eax中的值存入edi中16次,这里的edi的+-也是通过DF标志位来的。DF=1是减,DF=0是加
4、本节练习
海哥布置的作业,有机会补上!

【reverse】逆向5 标志寄存器的更多相关文章
- EFLAGS寄存器(标志寄存器)
		
这篇文章不是从0开始的,前面还有一些汇编基础指令以及进制,我都没写,时间问题,还是今天空闲,我才想补一下博文,后面我陆续会把前面知识点渐渐补上.我不会重0基础讲起,中间会以.汇编.C.C++交叉的形式 ...
 - CPU标志寄存器
		
这个标志寄存器似乎很重要,不干掉它,中断这玩意还进行不下去了,但是过于复杂,都是一些跟计算结果相关的位,头痛 (这是别人写的一篇非常好的关于标志寄存器的文章http://blog.csdn.net/w ...
 - 8086cpu中的标志寄存器与比较指令
		
在8086CPU中有一个特殊的寄存器--标志寄存器,该寄存器不同于其他寄存器,普通寄存器是用来存放数据的读取整个寄存器具有一定的含义,但是标志寄存器是每一位都有固定的含义,记录在运算中产生的信息,标志 ...
 - 标志寄存器在Debug中的表示
		
在Debug中,标志寄存器是按照有意义的各个标志位单独表示的. 下面列出Debug对我们已知的标志位的表示.
 - 标志寄存器PSW和汇编条件转移指令解释
		
标志寄存器PSW 标志寄存器PSW(程序状态字寄存器PSW) 标志寄存器PSW是一个16为的寄存器.它反映了CPU运算的状态特征并且存放某些控制标志.8086使用了16位中的9位,包括6个状态标志 ...
 - 《汇编语言(第三版)》pushf 和 popf 指令,以及标志寄存器在 Debug 中的表示
		
pushf 和 popf pushf 的功能是将标志寄存器的值压栈,而 popf 是从栈中弹出数据,输入标志寄存器. pushf 和 popf,为直接访问寄存器提供了方法. 格式 pushf popf ...
 - 原来... 用debug如何查看当前标志寄存器的标志位值?
		
-r 用这个指令,得到的信息右下角: NV UP EI PL NZ NA PO NC这些符号代表的就是标志寄存器里常用标志位的值. 这个是符号值对应表: 溢出标志OF(Ov ...
 - 学 Win32 汇编[20]: 洞察标志寄存器
		
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 NT IOPL OF DF IF TF SF ZF AF PF CF 未使用 嵌套标志 I/O权限标志占2位 溢出标志 方向 ...
 - Intel 8086 标志寄存器及JCC指令表
		
汇编 JCC指令表 JCC指条件跳转指令,CC就是指条件码. JCC指令 中文含义 英文原意 检查符号位 典型C应用 JZ/JE 若为0则跳转:若相等则跳转 jump if zero;jump if ...
 
随机推荐
- HSPICE与非门仿真
			
一.HSPICE的基本操作过程 打开HSPICE程序,通过OPEN打开编写好的网表文件. 按下SIMULATE进行网表文件的仿真. 按下AVANWAVES查看波形图(仿真结果). 二. 网表文件结构总 ...
 - CF764B Timofey and cubes 题解
			
Content 有一个序列 \(a_1,a_2,a_3,...,a_n\),对于 \(i\in[1,n]\),只要 \(i\leqslant n-i+1\),就把闭区间 \([i,n-i+1]\) 内 ...
 - CF1445A Array Rearrangement 题解
			
Content 有 \(t\) 组询问,每组询问给定两个长度为 \(n\) 的数列 \(\{a_i\}_{i=1}^n,\{b_i\}_{i=1}^n\) 和一个整数 \(x\),求是否能够重新对两个 ...
 - 关于后端 Entity Model Domain 的分界线
			
前言:在我们开发中经常用一种类型的值来接收来自Dao层的数据并将它传送给前端,或者作为逻辑处理,一般这种类型有三种 Entity Model Domain 我们该如何准确的应用这三种类型呢?这三 ...
 - java 常用类库:时间类LocalDate;LocalTime;LocalDateTime;Calendar 类;Date ;
			
LocalDate类 LocalDate类代表不带时区的日期,列入2020-12-20.该类提供了静态的now()方法来获取当前的日期.这个类是线程安全的. LocalTime类 代表不带时区的时间, ...
 - JAVA获取六位随机数
			
public static String getSixNum() { String str = "0123456789"; StringBuilder sb = new Strin ...
 - JAVA微信支付——企业付款(企业向微信用户个人付款、转账)
			
本地开发环境支付回调调试方法可以参考:https://www.cnblogs.com/pxblog/p/11623053.html 需要自行引入相关依赖 官方文档地址:https://pay.weix ...
 - xcode 常用指令
			
使用LLDB进行调试时,如何打印一个数组:p *(int(*)[10])ptr或者是从ptr的第3个元素开始显示10个元素p *(int(*)[10])&ptr[3]
 - 【LeetCode】227. Basic Calculator II 解题报告(Python)
			
[LeetCode]227. Basic Calculator II 解题报告(Python) 标签(空格分隔): LeetCode 作者: 负雪明烛 id: fuxuemingzhu 个人博客: h ...
 - 第十个知识点:RSA和强RSA问题有什么区别?
			
第十个知识点:RSA和强RSA问题有什么区别 这个密码学52件事数学知识的第一篇,也是整个系列的第10篇.这篇介绍了RSA问题和Strong-RSA问题,指出了这两种问题的不同之处. 密码学严重依赖于 ...