Win32反汇编(三)深层次的了解各种转移指令:IF语句有符号与无符号跳转

前言

作者:浪子花梦,一个有趣的程序员 ~
此系列文章都是一些基础的文章,每篇文章都通过几个小例子快速的了解 Win32反汇编与OD的使用,在此作个笔记
如若对您有帮助,记得三连哟 ~


前文链接

Win32反汇编(一) 初步探索Win32反汇编 与 Ollydbg的简单使用
Win32反汇编(二)几种常见的指令反汇编详解:EAX、MOVSX与MOVZX、LEA、SUB、CMP与转移指令


文章目录

此文章涉及的指令比较多,多动手才能熟悉这些东西, ^ _ ^


在这里插入图片描述

不开玩笑了,直接开讲 . . .

JMP 与 goto

jmp 是无条件跳转指令,不会影响标志位,对应着 C/C++ 中的 goto语句,我们来演示一下 jmp与goto的用法,观察如下的 cpp代码,上面使用 goto语句进行跳转,下面嵌入一行汇编指令,造成了死循环,他们的本身是一样,代码如下所示:

// jmp 演示

#include <cstdio>

int main() {

	printf("start\n");

	goto end;
	printf("langzi\n");
	printf("huameng\n");

end:
	printf("end!!!\n");


	// 循环打印
loopShow:
	printf("while!\n");
	__asm jmp loopShow
	 
	return 0;
}

使用 OD进行调试观察如下所示:
在这里插入图片描述
至于上面为什么有两个 jmp,这就是 od的翻译问题了,我们不作太多的了解,程序的执行流程如下所示:
在这里插入图片描述
第二个跳转到上面的指令,所以一直在跳转,实现了死循环,我们可以显示的改变指令的内容,如下所示:
在这里插入图片描述
使其跳转到跳转指令的下一条指令,暴力破解的原理 . . .

.
.


在上篇文章中我们学习了 je、jne指令,分别是==转移 和 != 转移,下面我们来学习一下 >、<、>=、<=,这些操作分为有符号的转移和无符号的转移 . . .

有符号:JL JNGE、JLE JNE(小于、小于等于)跳转指令

1)JL JNGE 小于跳转指令:
指令对应的翻译为:
JL:Jump if less
JNGE:Jump if not greater or equal
这两个指令的本质是一样的,OD一般会翻译成 JL,可以手动改变指令 . . .

cpp 程序代码如下所示:

#include <cstdio>

int main() {
	int a = 0x11;
	int b = 0x33;
	
	// a < b  跳转
	if (a >= b) {
		printf("do a >= b\n");
	}
	printf("do a < b\n");

	__asm {
		mov eax, b
		cmp a, eax
		jl end				// a < b  跳转
	}

	printf("a >= b!!!\n");
end:
	printf("a < b!!!\n");

	  
	return 0;
}

上面是用CPP的 if语句,下面是嵌入汇编指令,它们演示的都是一个意思,只有当 a < b时才发生跳转,OD 调试动图如下所示:
在这里插入图片描述
标志位计算:SF=1 时跳转
.
2)JLE JNE 小于等于跳转指令:
这两个指令的意思是一样的,都表示着小于等于时跳转,使用方式与上面的小于跳转指令相似,代码如下所示:

#include <cstdio>

int main() {
	int a = 0x11;
	int b = 0x33;
 

	if (a > b) {
		printf("do a > b\n");
	}
	printf("do a <= b\n");

	__asm {
		mov eax, b
		cmp a, eax
		jle end				// a <= b  跳转
	}

	printf("a > b!!!\n");
end:
	printf("a <= b!!!\n");
	 
	return 0;
}

OD调试如下所示,发现指令已经由原来的 jl 变成了jle了:
在这里插入图片描述
标志位计算:SF=1 || SF != OF 时跳转 . . .
.
.


有符号:JG JNLE、JGE JNL(大于、大于等于)跳转指令

1)JG JNLE 大于跳转指令:
指令对应的翻译为:
JG:Jump if Greater
JNLE:Jump if not Less or Equal
这两个指令的本质是一样的,OD一般会翻译成 JG,可以手动改变指令 . . .

cpp 程序代码如下所示:

#include <cstdio>

int main() {
	int a = 0x55;
	int b = 0x33;
	
	// a > b  跳转
	if (a <= b) {
		printf("do a <= b\n");
	}
	printf("do a > b\n");

	__asm {
		mov eax, b
		cmp a, eax
		jg end				// a > b  跳转
	}

	printf("a <= b!!!\n");
end:
	printf("a > b!!!\n");

	 
	return 0;
}

上面是用CPP的 if语句,下面是嵌入汇编指令,它们演示的都是一个意思,只有当 a < b时才发生跳转,OD 调试动图如下所示:
在这里插入图片描述

.
2)JGE JNL 大于等于跳转指令:
这两个指令的意思是一样的,都表示着大于等于时跳转,使用方式与上面的大于跳转指令相似,代码如下所示:

#include <cstdio>

int main() {
	int a = 0x55;
	int b = 0x33;
	 
	if (a < b) {
		printf("do a < b\n");
	}
	printf("do a >= b\n");

	__asm {
		mov eax, b
		cmp a, eax
		jge end				// a >= b  跳转
	}

	printf("a < b!!!\n");
end:
	printf("a >= b!!!\n");
	 
	return 0;
}

OD调试如下所示,发现指令已经由原来的 jg 变成了jge了:
在这里插入图片描述
标志位计算:ZF = 0 && SF = 0F . . .

.
.


无符号:JA JNBE、JNB JAE JNC(大于、大于等于)跳转指令

无符号转移指令和有符号转移指令的使用都是差不多的,只是指令不同而已,下面我们就介绍一下指令,然后快速的使用一下就行 . . .

1)JA JNBE 无符号大于转移指令:
JA:Jump Above(高于)
JNBE:Jump not Below(低于)

cpp 代码如下所示:

#include <cstdio>

int main() {
	unsigned int a = 0x55;
	unsigned int b = 0x33;


	if (a <= b) {
		printf("do a <= b\n");
	}
	printf("do a > b\n");

	__asm {
		mov eax, b
		cmp a, eax
		ja end				// a > b  跳转
	}

	printf("a <= b!!!\n");
end:
	printf("a > b!!!\n");
	 

	return 0;
}

OD 调试动图如下所示:
在这里插入图片描述
标志位计算:CF = 0 && ZF = 0 时跳转 . . .
.
2)JNB JAE JNC无符号大于等于转移指令:
JNB:Jump not Below(不低于)
JAE:Jump above equal(高于等于)
JNC:Jump not carry(没有进位时跳转 CF = 0)

cpp 代码如下所示:

#include <cstdio>

int main() {
	unsigned int a = 0x33;
	unsigned int b = 0x33;


	if (a < b) {
		printf("do a < b\n");
	}
	printf("do a >= b\n");

	__asm {
		mov eax, b
		cmp a, eax
		jnb end				// a >= b  跳转
	}

	printf("a < b!!!\n");
end:
	printf("a >= b!!!\n");
	 

	return 0;
}

这两个数是相同的,下面我们来试试OD调试一下:
在这里插入图片描述
.
.


无符号:JB JNAE JC、 JBE JNA(小于、小于等于)跳转指令

1)JB JNAE JC 无符号小于转移指令:
JB:Jump Below(低于)
JNAE:Jump not Above Equal(不高于等于)
JC:Jump Carry(进位时跳转)CF = 1

cpp 代码如下所示:

#include <cstdio>

int main() {
	unsigned int a = 0x11;
	unsigned int b = 0x33;

	// a < b  跳转
	if (a >= b) {
		printf("do a >= b\n");
	}
	printf("do a < b\n");

	__asm {
		mov eax, b
		cmp a, eax
		jb end				// a < b  跳转
	}

	printf("a >= b!!!\n");
end:
	printf("a < b!!!\n");


	return 0;
}

OD 调试动图如下所示:
在这里插入图片描述
.
2)JBE JNA无符号小于等于转移指令:
JBE:Jump Below Equal(低于等于)
JNA:Jump not above(不高于)

cpp 代码如下所示:

#include <cstdio>

int main() {
	unsigned int a = 0x33;
	unsigned int b = 0x33;

	// a < b  跳转
	if (a > b) {
		printf("do a > b\n");
	}
	printf("do a <= b\n");

	__asm {
		mov eax, b
		cmp a, eax
		jbe end				// a < b  跳转
	}

	printf("a > b!!!\n");
end:
	printf("a <= b!!!\n");


	return 0;
}

这两个数是相同的,下面我们来试试OD调试一下:
在这里插入图片描述
.
.


条件转移指令集合(有符号)

在这里插入图片描述

标志寄存器复习汇总

在这里插入图片描述

.
.


  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值