JZ/JE指令:根据Z标志位进行跳转
JZ和JE相同(shark恒老师说的,我就记录下,但是他也说过不是完全相同)
1、直接定位到一个存在je跳转的地址,然后发现是存在跳转的,如图
上图的Z标志位为1,所以会进行跳转,但是如果修改Z标志位为0则不会,如图
同时JE和JZ也相同
JNZ/JNE指令:根据Z标志位进行跳转
同样是根据Z标志位进行跳转,但是是相反的,当Z标志位为0的时候进行跳转,当Z标志位为1的时候不跳转
1、修改当前地址的汇编指令为cmp eax,ecx
,然后下个地址再修改为jnz 0040101D
2、修改eax的寄存器的值为00000001,ecx的寄存器的值为00000000
3、单步步过
cmp计算的结果不为0,所以Z标志位同样不为1,所以JNZ/JEZ会进行跳转,因为跟JE/JZ是相反判断的
JMP指令:无条件跳转,不会受标志位的影响
JS和JNS指令:根据S标志位进行判断是否跳转
JS和JNS都是根据S标志位进行判断的,只是是否跳转是判断相反S标志位
1、修改当前地址的汇编指令为cmp eax,ecx
,然后下个地址再修改为js 0040101D
2、修改eax的寄存器的值为00000001,ecx的寄存器的值为00000000
3、单步步过
发现S标志位为0,不会进行跳转,原因十六进制00000001减去十六进制00000000,结果是个正数所以S标志位为0,而JS是当S标志位为0的时候不跳转,当S标志位为1的时候进行跳转
JNS就是反一下,当S标志位为0的时候跳转,为1的时候不跳转
JP和JPZ指令:根据P标志位进行判断是否跳转
JP和JNP都是根据S标志位进行判断的,只是是否跳转是判断相反P标志位
这里需要记录下JP和JPE是相同的,JNP和JPO是相同的
1、修改当前地址的汇编指令为cmp eax,ecx
,然后下个地址再修改为jp 0040101D
2、修改eax的寄存器的值为00000001,ecx的寄存器的值为00000000
3、单步步过
发现不会进行跳转,原因是P标志位是奇偶标志位,根据二进制数中的1的个数进行判断的,cmp eax ecx
结果是00000001,转换为二进制那么就是0001,1的个数为奇数那么P标志位就为0,那么也就不跳转了
JNP就是反一下,当P标志位为0的时候跳转,为1的时候不跳转
JO和JNO指令:根据O标志位进行判断
1、修改当前地址的汇编指令为add eax,ecx
,然后下个地址再修改为jo 0040101D
2、修改eax的寄存器的值为7FFFFFF,ecx的寄存器的值为00000001
3、单步步过
O标志位当溢出的时候7FFFFFFF + 0x1 为 80000000 变成有符号位的最小整数,自然O标志位为1,JO指令当O标志位为1的时候则进行跳转
JB和JNB指令:当cmp指令第一个操作数小于第二个操作数的时候则进行跳转
1、修改当前地址的汇编指令为cmp eax,ecx
,然后下个地址再修改为jb 0040101D
2、修改eax的寄存器的值为00000000,ecx的寄存器的值为00000001
3、单步步过
原因是eax小于ecx,C标志位为1,所以进行跳转
JBE和JNBE指令:当cmp指令第一个操作数小于或等于第二个操作数的时候则进行跳转,并且受标志位C和Z的影响
JNBE则相反,JNBE跟JA相同
JL指令:根据S标志位进行判断是否跳转,并且计算的是有符号位之间的运算
1、修改当前地址的汇编指令为cmp eax,ecx
,然后下个地址再修改为jl 0040101D
2、修改eax的寄存器的值为00000000,ecx的寄存器的值为00000001
3、单步步过
发现S标志位为1,因为cmp指令 结果为十进制0-1 为 -1,是一个负数 所以S标志位为1
可以再把eax修改为FFFFFFF6,那么十进制就为-10,然后重新定位EIP,再进行单步步过
可以发现S标志位没变化,还是为1,那么也可以证实了计算的是有符号位之间的运算
JL和JB指令之间的区别:http://bbs3.driverdevelop.com/read.php?tid=106427