滴水逆向--01-20 JCC
JMP
只修改 EIP,其余什么也不做
1 | MOV EIP, 寄存器/立即数 ;简写为:JMP 寄存器/立即数 |
CALL
修改 EIP,ESP 也会 -4,把下一句要执行的地址压栈
1 | PUSH 地址B |
RETN
修改 EIP,ESP + 4,弹出栈顶返回地址赋给 EIP。类似于 POP EIP
1 | LEA ESP, [ESP+4] |
比较指令(CMP、TEST)
-
CMP 指令
指令格式:CMP R/M, R/M/IMM(不能同时为内存)
相当于 SUB 指令,但是并不像 SUB 一样保存结果,只改标志寄存器的值,根据相减的结果来改变零标志位
常用于比较两个数是否相等,相等时 ZF=1,==一般看 ZF 和 SF 位比较多==
- 无符号数比较
CMP结果 ZF CF 目的操作数 < 源操作数 0 1 目的操作数 > 源操作数 0 0 目的操作数 = 源操作数 1 0 - 有符号数比较
CMP结果 标志位 目的操作数 < 源操作数 SF ≠ OF 目的操作数 > 源操作数 SF = OF 目的操作数 = 源操作数 ZF = 1 -
TEST 指令
指令格式:TEST R/M, R/M/IMM
在一定程序上与 CMP 指令是类似的,两个数值进行与操作,也是不保存结果,但是影响标志位 ZF
常见用法:判断某个寄存器是不是等于 0,只有是 0 是自己跟自己 and 才会是 0
1
TEST EAX, EAX ;用来判断eax中值是否为0,如果是0,则ZF置为1
JCC 指令
-
JE、JZ
JE:Jump Equal 相等时跳转
JZ:Jump Zero 结果为 0 时跳转
根据 ZF 位判断是否跳转,ZF=1 则跳转,否则不跳。也就是结果相等就跳转
-
JNE、JNZ
遇上面相反,ZF=0 时跳转,也就是结果不相等的时候就跳
-
JS
JS:Jump if Sign
根据 SF 位判断是否跳转,SF=1 则跳转,否则不跳。也就是结果为负数就跳转
-
JNS
与上面相反,SF=0 时跳转,也就是结果为非负数则跳转
-
JP、JPE
JP:Jump if Parity
JPE:Jump if Parity Even
根据 PF 位判断是否跳转,PF=1 则跳转,也就是如果结果低8位中1的个数为偶数则跳转
-
JNP、JPO
JPO:Jump if Parity Odd
与上面相反,PF=0 则跳转,也就是如果结果低8位中1的个数为奇数则跳转
-
JO
JO:Jump if Overflow
根据 OF 位判断是否跳转,OF=1 则跳转,也就是如果结果溢出了就跳
-
JNO
与上面相反,OF=0 则跳,也就是没溢出就跳
-
JB、JNAE
JB:Jump if Below
JNAE:Jump if Not Above or Equal
前面的数跟后面的数比较小于则跳转(无符号数),即 CF=1 跳转
-
JNB、JAE
与上面相反,大于等于则跳转(无符号数),即 CF=0 跳转
-
JBE、JNA
JBE:Jump if Below or Equal
JNA:Jump if Not Above
小于等于则跳转(无符号数),即 CF=1 或者 ZF=1 跳转
-
JNBE、JA
与上面相反,大于则跳转(无符号数),即 CF=0 并且 ZF=0 跳转
-
JL、JNGE
JL:Jump if Less
JNGE:Jump if Not Greater or Equal
小于则跳转(有符号数),即 SF≠OF 跳转(注意这里的小于是指我们平时所说的有符号的数的大小,不是看计算机中存的二进制数的大小)
-
JNL、JGE
与上面相反,大于等于则跳转(有符号数),即 SF=OF 跳转
-
JLE、JNG
JLE:Jump if Less or Equal
JNG:Jump if Not Greater
小于等于则跳转(有符号数),即 SF≠OF 或者 ZF=1
-
JNLE、JG
与上面相反,大于则跳转(有符号数),即 SF=OF 并且 ZF=0
| 指令 | 跳转条件 | 英文解释 | 标志位判断依据 |
|---|---|---|---|
| JE, JZ | 结果相等(或结果为0)则跳转 | JE: Jump Equal JZ: Jump Zero |
ZF=1 |
| JNE, JNZ | 结果不相等(或结果不为0)则跳转 | JNE: Jump Not Equal JNZ: Jump Not Zero |
ZF=0 |
| JS | 结果为负数则跳转 | JS: Jump if Sign | SF=1 |
| JNS | 结果为非负数则跳转 | JNS: Jump if Not Sign | SF=0 |
| JP, JPE | 结果低8位中1的个数为偶数则跳转 | JP: Jump if Parity JPE: Jump if Parity Even |
PF=1 |
| JNP, JPO | 结果低8位中1的个数为奇数则跳转 | JNP: Jump No Parity JPO: Jump if Parity Odd |
PF=0 |
| JO | 结果溢出则跳转 | JO: Jump if Overflow | OF=1 |
| JNO | 结果没溢出则跳转 | JNO: Jump if Not Overflow | OF=0 |
| JB, JNAE | 小于则跳转(无符号数) | JB: Jump if Below JNAE: Jump if Not Above or Equal |
CF=1 |
| JNB, JAE | 大于等于则跳转(无符号数) | JNB: Jump if Not Below JAE: Jump if Above or Equal |
CF=0 |
| JBE, JNA | 小于等于则跳转(无符号数) | JBE: Jump if Below or Equal JNA: Jump if Not Above |
CF=1 or ZF=1 |
| JNBE, JA | 大于则跳转(无符号数) | JNBE: Jump if Not Below or Equal JA: Jump if Above |
CF=0 and ZF=0 |
| JL, JNGE | 小于则跳转(有符号数) | JL: Jump if Less JNGE: Jump if Not Greater or Equal |
SF≠OF |
| JNL, JGE | 大于等于则跳转(有符号数) | JNL: Jump if Not Less JGE: Jump if Greater or Equal |
SF=OF |
| JLE, JNG | 小于等于则跳转(有符号数) | JLE: Jump if Less or Equal JNG: Jump if Not Greater |
SF≠OF or ZF=1 |
| JNLE, JG | 大于则跳转(有符号数) | JNLE: Jump if Not Less or Equal JG: Jump if Greater |
SF=OF and ZF=0 |
课后作业
-
CALL 执行时堆栈有什么变化?EIP 有变化吗?
ESP-4,将 call 指令的下一条指令的地址压栈。EIP 变为 call 指令中的那个地址
-
RET 执行时堆栈有什么变化?EIP 有变化吗?
栈顶 +4,栈顶弹出赋值给 EIP
-
使用汇编指令修改标志寄存器中的某个位的值,实现 JCC 的十六种跳转
不允许在 OD 中通过双击的形式修改标志寄存器
要通过汇编指令的执行去影响标志位,能用 CMP 和 TEST 实现的优先考虑
第一组:ZF 标志位(相等/零)
-
JE, JZ(ZF=1)
1
2
3
4
5
6MOV EAX, 0
TEST EAX, EAX
JE ...
- JNE, JNZ(ZF=0)MOV EAX, 0x10
MOV ECX, 0x20
CMP EAX, ECX
JNE …1
2
3
4
5
第二组:SF 标志位(符号/正负)
- JS(SF=1)MOV EAX, 0x80000000
TEST EAX, EAX
JS …1
2
3
- JNS(SF=0)MOV EAX, 0x7FFFFFFF
TEST EAX, EAX
JNS …1
2
3
4
5
6
7
第三组:PF 标志位(奇偶性)
- JP, JPE(PF=1)
需注意:PF 只看最后八位MOV AL, 0x9F
TEST AL, AL
JP …1
2
3
- JNP, JPO(PF=0)MOV AL, 0x7F
TEST AL, AL
JNP …1
2
3
4
5
第四组:OF 标志位(溢出)
- JO(OF=1)MOV EAX, 0x80000000 ;负数
MOV ECX, 0x00000001 ;正数
CMP EAX, ECX ;负-正=正 0x7FFFFFFF
JO …1
2
3
- JNO(OF=0)MOV EAX, 0x00000001
MOV ECX, 0x7FFFFFFF
CMP EAX, ECX ;正+负 永远不会有溢出
JNO …1
2
3
4
5
第五组:无符号数比较 (CF, ZF)
- JB, JNAE(CF=1)MOV EAX, 0x00000001 ;小数
MOV ECX, 0xFFFFFFFF ;大数(无符号看)
CMP EAX, ECX ;小-大 要借位
JB …1
2
3
- JNB, JAE(CF=0)MOV EAX, 0xFFFFFFFF
MOV ECX, 0x00000001
CMP EAX, ECX
JNB …1
2
3
- JBE, JNA(CF=1 or ZF=1)MOV EAX,0x11111111
MOV ECX,0x22222222
CMP EAX, ECX
JBE …1
MOV EAX, 0x88888888
MOV ECX, 0x88888888
CMP EAX, ECX
JBE …1
2
3
- JNBE, JA(CF=0 and ZF=0)MOV EAX, 0x20000000
MOV ECX, 0x10000000
CMP EAX, ECX
JA …1
2
3
4
5
第六组:有符号数比较 (SF, OF, ZF)
- JL, JNGE(OF≠SF)MOV EAX, 0x11111111
MOV ECX, 0x77777777
CMP EAX, ECX ;小正数-大正数=负数,SF=1,但是不溢出,OF=0
JL …1
2
3
- JNL, JGE(OF=SF)MOV EAX, 0x77777777
MOV ECX, 0x11111111
CMP EAX, ECX
JNL …1
2
3
- JLE, JNG(OF≠SF or ZF=1)MOV EAX, 0x11111111
MOV ECX, 0x77777777
CMP EAX, ECX
JLE …1
MOV EAX, 0
TEST EAX, EAX
JLE …1
2
3
- JNLE, JG(OF=SF and ZF=0)MOV EAX, 0x00000001
MOV ECX, 0xFFFFFFFF
CMP EAX, ECX
JG …
-