C/C++ 反汇编:流程控制与循环结构

反汇编即把目标二进制机器码转为汇编代码的过程,该技术常用于软件破解、外挂技术、病毒分析、逆向工程、软件汉化等领域,学习和理解反汇编对软件调试、系统漏洞挖掘、内核原理及理解高级语言代码都有相当大的帮助,软件一切神秘的运行机制全在反汇编代码里面。

IF-单条件分支语句: 单分支结构配合and与or实现的验证.

#include <stdio.h>

int main(int argc, char* argv[])
{
	int x = 10, y = 20, z = 30;
	if (x >= y)
	{
		printf("x >=y");
	}
	else if (z >= x && z >= y)
	{
		printf("z>=x and z>=y");
	}
	return 0;
}
004113DE | C745 F8 0A000000         | mov dword ptr ss:[ebp-0x8],0xA              | x = 10
004113E5 | C745 EC 14000000         | mov dword ptr ss:[ebp-0x14],0x14            | y = 20
004113EC | C745 E0 1E000000         | mov dword ptr ss:[ebp-0x20],0x1E            | z = 30
004113F3 | 8B45 F8                  | mov eax,dword ptr ss:[ebp-0x8]              | eax = 10
004113F6 | 3B45 EC                  | cmp eax,dword ptr ss:[ebp-0x14]             | cmp 10,20 => 10-20
004113F9 | 7C 19                    | jl 0x411414                                 | 上方表达式10小于20则跳 (第一个表达式)
004113FB | 8BF4                     | mov esi,esp                                 | main.c:8, esi:__enc$textbss$end+109
004113FD | 68 58584100              | push consoleapplication1.415858             | 415858:"x >=y"
00411402 | FF15 14914100            | call dword ptr ds:[<&printf>]               |
00411408 | 83C4 04                  | add esp,0x4                                 |
0041140B | 3BF4                     | cmp esi,esp                                 | esi:__enc$textbss$end+109
0041140D | E8 24FDFFFF              | call 0x411136                               |
00411412 | EB 27                    | jmp 0x41143B                                |
00411414 | 8B45 E0                  | mov eax,dword ptr ss:[ebp-0x20]             | eax = 30
00411417 | 3B45 F8                  | cmp eax,dword ptr ss:[ebp-0x8]              | cmp 30,10 => 30-10
0041141A | 7C 1F                    | jl 0x41143B                                 | 上方表达式 30>10 则jl不跳 (第二个表达式)
0041141C | 8B45 E0                  | mov eax,dword ptr ss:[ebp-0x20]             | eax = 30
0041141F | 3B45 EC                  | cmp eax,dword ptr ss:[ebp-0x14]             | cmp 30,20 => 30>20
00411422 | 7C 17                    | jl 0x41143B                                 | 上方表达式 30>20 则jl不跳 (第二个表达式)
00411424 | 8BF4                     | mov esi,esp                                 | main.c:12, esi:__enc$textbss$end+109
00411426 | 68 60584100              | push consoleapplication1.415860             | 415860:"z>=x and z>=y"
0041142B | FF15 14914100            | call dword ptr ds:[<&printf>]               | 最后打印输出字符串
00411431 | 83C4 04                  | add esp,0x4                                 |

if (z >= x && z >= y) 语句的表现形式

C/C++ 反汇编:流程控制与循环结构

if (z >= x || z >= y) 稍微改变成或者,再来观察程序流程,两个结构对比,然后总结经验,或者与并且两个语句在实现上的异同点。

C/C++ 反汇编:流程控制与循环结构

如果将代码编译为 Release 版本,你会发现if语句被优化没了,只保留了一个打印结果,这个优化还是很牛b的,整个结构都被重定义了。编译器认为你的判断没有任何意义,所以直接就给你干掉了,只保留了一个输出结果,这个输出结果是一定会被执行的,是一个定死的。

C/C++ 反汇编:流程控制与循环结构

IF-嵌套条件分支:

#include <stdio.h>

int main(int argc, char* argv[])
{
	int x = 10, y = 20, z = 30;
	if (x >= y || z >= x)
	{
		if (x <= z)
		{
			printf("x >=y or z>=x and x<=z");
		}
		else
		{
			printf("x >=y or z>=x and x>=z");
		}
	}
	return 0;
}
004113DE | C745 F8 0A000000         | mov dword ptr ss:[ebp-0x8],0xA              | 0xA = 10
004113E5 | C745 EC 14000000         | mov dword ptr ss:[ebp-0x14],0x14            | 0x14 = 20
004113EC | C745 E0 1E000000         | mov dword ptr ss:[ebp-0x20],0x1E            | 0x1E = 30
004113F3 | 8B45 F8                  | mov eax,dword ptr ss:[ebp-0x8]              | eax = 10
004113F6 | 3B45 EC                  | cmp eax,dword ptr ss:[ebp-0x14]             | cmp eax,20 => 10-20
004113F9 | 7D 08                    | jge 0x411403                                | 比较不成立,则不跳
004113FB | 8B45 E0                  | mov eax,dword ptr ss:[ebp-0x20]             | eax = 30
004113FE | 3B45 F8                  | cmp eax,dword ptr ss:[ebp-0x8]              | cpm eax,10 => 30-10
00411401 | 7C 38                    | jl 0x41143B                                 | 比较不成立,则不跳
00411403 | 8B45 F8                  | mov eax,dword ptr ss:[ebp-0x8]              | eax = 10
00411406 | 3B45 E0                  | cmp eax,dword ptr ss:[ebp-0x20]             | cpm eax,30 => 10-30
00411409 | 7F 19                    | jg 0x411424                                 | 10不大于30则不跳
0041140B | 8BF4                     | mov esi,esp                                 | main.c:10
0041140D | 68 58584100              | push consoleapplication1.415858             | 415858:"x >=y or z>=x and x<=z"
00411412 | FF15 14914100            | call dword ptr ds:[<&printf>]               | 打印出结果
00411418 | 83C4 04                  | add esp,0x4                                 |

C/C++ 反汇编:流程控制与循环结构

WHILE-循环: x++ 是jge来操控,++x是jg

#include <stdio.h>

int main(int argc, char* argv[])
{
	int x = 0;
	while (x <= 10)
	{
		printf("打印: %dn", x);
		x++;
	}
	return 0;
}
004113DE | C745 F8 00000000         | mov dword ptr ss:[ebp-0x8],0x0              | 0
004113E5 | 837D F8 0A               | cmp dword ptr ss:[ebp-0x8],0xA              | cmp 0,10 =>
004113E9 | 7F 26                    | jg 0x411411                                 | 0不大于10,则不跳
004113EB | 8BF4                     | mov esi,esp                                 | main.c:8
004113ED | 8B45 F8                  | mov eax,dword ptr ss:[ebp-0x8]              | eax = 0
004113F0 | 50                       | push eax                                    |
004113F1 | 68 58584100              | push consoleapplication1.415858             | 415858:"打印: %dn"
004113F6 | FF15 14914100            | call dword ptr ds:[<&printf>]               | 每次循环打印
004113FC | 83C4 08                  | add esp,0x8                                 |
004113FF | 3BF4                     | cmp esi,esp                                 |
00411401 | E8 30FDFFFF              | call 0x411136                               | 微软堆栈检测器
00411406 | 8B45 F8                  | mov eax,dword ptr ss:[ebp-0x8]              | 取出eax里面的值
00411409 | 83C0 01                  | add eax,0x1                                 | 每次递增1
0041140C | 8945 F8                  | mov dword ptr ss:[ebp-0x8],eax              |
0041140F | EB D4                    | jmp 0x4113E5                                | main.c:10
00411411 | 33C0                     | xor eax,eax                                 | main.c:11

C/C++ 反汇编:流程控制与循环结构

在此基础上稍微增加难度,在while循环内部判断x是否能被2整除.

#include <stdio.h>

int main(int argc, char* argv[])
{
	int x = 0;
	while (x <= 10)
	{
		printf("这是第: %d 次循环 n", x+1);
		if (x % 2 == 0)
			printf("--> %d 次循环符合条件n", x+1);
		x++;
	}
	return 0;
}
004113DE | C745 F8 00000000         | mov dword ptr ss:[ebp-0x8],0x0            | 0
004113E5 | 837D F8 0A               | cmp dword ptr ss:[ebp-0x8],0xA            | cmp 0,0xA => 循环10次
004113E9 | 7F 5A                    | jg 0x411445                               | 0大于10则跳到结束
004113EB | 8B45 F8                  | mov eax,dword ptr ss:[ebp-0x8]            | 取出循环计数
004113EE | 83C0 01                  | add eax,0x1                               | 在此基础上+1
004113F1 | 8BF4                     | mov esi,esp                               |
004113F3 | 50                       | push eax                                  | 压入堆栈
004113F4 | 68 58584100              | push consoleapplication1.415858           | 415858:"这是第: %d 次循环 n"
004113F9 | FF15 14914100            | call dword ptr ds:[<&printf>]             | 输出结果
004113FF | 83C4 08                  | add esp,0x8                               | 堆栈恢复
00411402 | 3BF4                     | cmp esi,esp                               |
00411404 | E8 2DFDFFFF              | call 0x411136                             |
00411409 | 8B45 F8                  | mov eax,dword ptr ss:[ebp-0x8]            | main.c:9
0041140C | 25 01000080              | and eax,0x80000001                        | 取出循环计数,并验证是否%2=0
00411411 | 79 05                    | jns 0x411418                              |
00411413 | 48                       | dec eax                                   |
00411414 | 83C8 FE                  | or eax,0xFFFFFFFE                         |
00411417 | 40                       | inc eax                                   |
00411418 | 85C0                     | test eax,eax                              | 比较eax是否为0
0041141A | 75 1E                    | jne 0x41143A                              |
0041141C | 8B45 F8                  | mov eax,dword ptr ss:[ebp-0x8]            | main.c:10
0041141F | 83C0 01                  | add eax,0x1                               |
00411422 | 8BF4                     | mov esi,esp                               |
00411424 | 50                       | push eax                                  |
00411425 | 68 70584100              | push consoleapplication1.415870           | 415870:"--> %d 次循环符合条件n"
0041142A | FF15 14914100            | call dword ptr ds:[<&printf>]             |
00411430 | 83C4 08                  | add esp,0x8                               |
00411433 | 3BF4                     | cmp esi,esp                               |
00411435 | E8 FCFCFFFF              | call 0x411136                             |
0041143A | 8B45 F8                  | mov eax,dword ptr ss:[ebp-0x8]            | main.c:11
0041143D | 83C0 01                  | add eax,0x1                               |
00411440 | 8945 F8                  | mov dword ptr ss:[ebp-0x8],eax            |
00411443 | EB A0                    | jmp 0x4113E5                              | main.c:12
00411445 | 33C0                     | xor eax,eax                               | main.c:13

C/C++ 反汇编:流程控制与循环结构

继续修改源代码,增加双层循环,实现嵌套wihle循环.

#include <stdio.h>

int main(int argc, char* argv[])
{
	int x = 0, y = 0, z =0 ;
	while (x <= 10)
	{
		while (y <= 5)
		{
			z = x + y;
			if (z %2==0)
				printf("外层循环: %d 内层循环: %d n", x, y);
			y = y + 1;
		}
		x = x + 1;
	}
	return 0;
}
004113DE | C745 F8 00000000         | mov dword ptr ss:[ebp-0x8],0x0            | x
004113E5 | C745 EC 00000000         | mov dword ptr ss:[ebp-0x14],0x0           | y
004113EC | C745 E0 00000000         | mov dword ptr ss:[ebp-0x20],0x0           | z
004113F3 | 837D F8 0A               | cmp dword ptr ss:[ebp-0x8],0xA            | 定义外层循环,总共循环10次
004113F7 | 7F 57                    | jg 0x411450                               |
004113F9 | 837D EC 05               | cmp dword ptr ss:[ebp-0x14],0x5           | 定义内存循环,总共循环5次
004113FD | 7F 46                    | jg 0x411445                               |
004113FF | 8B45 F8                  | mov eax,dword ptr ss:[ebp-0x8]            | eax = x
00411402 | 0345 EC                  | add eax,dword ptr ss:[ebp-0x14]           | add x,y
00411405 | 8945 E0                  | mov dword ptr ss:[ebp-0x20],eax           | mov z = x+y
00411408 | 8B45 E0                  | mov eax,dword ptr ss:[ebp-0x20]           | main.c:11
0041140B | 25 01000080              | and eax,0x80000001                        | 取出z的值
00411410 | 79 05                    | jns 0x411417                              |
00411412 | 48                       | dec eax                                   |
00411413 | 83C8 FE                  | or eax,0xFFFFFFFE                         |
00411416 | 40                       | inc eax                                   |
00411417 | 85C0                     | test eax,eax                              | 取出z的值,判断是否%2==0
00411419 | 75 1F                    | jne 0x41143A                              |
0041141B | 8BF4                     | mov esi,esp                               | main.c:12
0041141D | 8B45 EC                  | mov eax,dword ptr ss:[ebp-0x14]           |
00411420 | 50                       | push eax                                  |
00411421 | 8B4D F8                  | mov ecx,dword ptr ss:[ebp-0x8]            |
00411424 | 51                       | push ecx                                  |
00411425 | 68 58584100              | push consoleapplication1.415858           | 415858:"外层循环: %d 内层循环: %d n"
0041142A | FF15 14914100            | call dword ptr ds:[<&printf>]             |
00411430 | 83C4 0C                  | add esp,0xC                               |
00411433 | 3BF4                     | cmp esi,esp                               |
00411435 | E8 FCFCFFFF              | call 0x411136                             |
0041143A | 8B45 EC                  | mov eax,dword ptr ss:[ebp-0x14]           | main.c:13
0041143D | 83C0 01                  | add eax,0x1                               |
00411440 | 8945 EC                  | mov dword ptr ss:[ebp-0x14],eax           |
00411443 | EB B4                    | jmp 0x4113F9                              | 无条件跳转到内层循环
00411445 | 8B45 F8                  | mov eax,dword ptr ss:[ebp-0x8]            | main.c:15
00411448 | 83C0 01                  | add eax,0x1                               |
0041144B | 8945 F8                  | mov dword ptr ss:[ebp-0x8],eax            |
0041144E | EB A3                    | jmp 0x4113F3                              | 无条件跳转到外层循环
00411450 | 33C0                     | xor eax,eax                               | main.c:17

C/C++ 反汇编:流程控制与循环结构

这里的打印参数,很有趣,取值并压入两个参数,然后调用的printf.

C/C++ 反汇编:流程控制与循环结构

DO-WHILE条件循环: 与while循环不同,do会先执行循环然后判断,如下代码反编译观察.

#include <stdio.h>

int main(int argc, char* argv[])
{
	int x = 0,y=0;
	do
	{
		printf("外层do-while 循环: %dn", x);
		while (y <= 5)
		{
			printf("内层while 循环: %dn", y);
			y = y + 1;
		}
		x = x + 1;
	} while (x <= 10);
	return 0;
}

如下反汇编代码可以观察到代码结构,C语言在实现while语句与do-while语句的异同点,while语句是先判断然后才会进入循环体,而do-while则是先执行循环体内部的东西,最后补一刀来判断是否满足条件.

004113DE | C745 F8 00000000         | mov dword ptr ss:[ebp-0x8],0x0            | x
004113E5 | C745 EC 00000000         | mov dword ptr ss:[ebp-0x14],0x0           | y
004113EC | 8BF4                     | mov esi,esp                               | main.c:8
004113EE | 8B45 F8                  | mov eax,dword ptr ss:[ebp-0x8]            | mov eax,0
004113F1 | 50                       | push eax                                  |
004113F2 | 68 58584100              | push consoleapplication1.415858           | 415858:"外层do-while 循环: %dn"
004113F7 | FF15 14914100            | call dword ptr ds:[<&printf>]             |
004113FD | 83C4 08                  | add esp,0x8                               |
00411400 | 3BF4                     | cmp esi,esp                               |
00411402 | E8 2FFDFFFF              | call 0x411136                             |
00411407 | 837D EC 05               | cmp dword ptr ss:[ebp-0x14],0x5           | 进入内层循环
0041140B | 7F 26                    | jg 0x411433                               | 直到条件大于5则退出
0041140D | 8BF4                     | mov esi,esp                               | main.c:11
0041140F | 8B45 EC                  | mov eax,dword ptr ss:[ebp-0x14]           |
00411412 | 50                       | push eax                                  |
00411413 | 68 74584100              | push consoleapplication1.415874           | 415874:"内层while 循环: %dn"
00411418 | FF15 14914100            | call dword ptr ds:[<&printf>]             |
0041141E | 83C4 08                  | add esp,0x8                               |
00411421 | 3BF4                     | cmp esi,esp                               |
00411423 | E8 0EFDFFFF              | call 0x411136                             |
00411428 | 8B45 EC                  | mov eax,dword ptr ss:[ebp-0x14]           | main.c:12
0041142B | 83C0 01                  | add eax,0x1                               | 每次递增
0041142E | 8945 EC                  | mov dword ptr ss:[ebp-0x14],eax           |
00411431 | EB D4                    | jmp 0x411407                              | main.c:13
00411433 | 8B45 F8                  | mov eax,dword ptr ss:[ebp-0x8]            | main.c:14
00411436 | 83C0 01                  | add eax,0x1                               |
00411439 | 8945 F8                  | mov dword ptr ss:[ebp-0x8],eax            |
0041143C | 837D F8 0A               | cmp dword ptr ss:[ebp-0x8],0xA            | 外层循环的比较
00411440 | 7E AA                    | jle 0x4113EC                              | 小于则跳转
00411442 | 33C0                     | xor eax,eax                               | main.c:16

C/C++ 反汇编:流程控制与循环结构

FOR-条件循环:

#include <stdio.h>

int main(int argc, char* argv[])
{
	int x;
	for (x = 0; x <= 10; x++)
	{
		printf("循环计数: %dn", x);
	}
	return 0;
}
004113DE | C745 F8 00000000         | mov dword ptr ss:[ebp-0x8],0x0            | 初始化 x=0
004113E5 | EB 09                    | jmp 0x4113F0                              | 跳转到比较语句处
004113E7 | 8B45 F8                  | mov eax,dword ptr ss:[ebp-0x8]            |
004113EA | 83C0 01                  | add eax,0x1                               | 每次递增x++
004113ED | 8945 F8                  | mov dword ptr ss:[ebp-0x8],eax            |
004113F0 | 837D F8 0A               | cmp dword ptr ss:[ebp-0x8],0xA            | 判断x是否为10 x<=10
004113F4 | 7F 1D                    | jg 0x411413                               | 大于则跳转到结束
004113F6 | 8BF4                     | mov esi,esp                               | main.c:8, esi:__enc$textbss$end+109
004113F8 | 8B45 F8                  | mov eax,dword ptr ss:[ebp-0x8]            |
004113FB | 50                       | push eax                                  | 压入当前循环次数,并打印
004113FC | 68 58584100              | push consoleapplication1.415858           | 415858:"循环计数: %dn"
00411401 | FF15 14914100            | call dword ptr ds:[<&printf>]             |
00411407 | 83C4 08                  | add esp,0x8                               |
0041140A | 3BF4                     | cmp esi,esp                               | esi:__enc$textbss$end+109
0041140C | E8 25FDFFFF              | call 0x411136                             |
00411411 | EB D4                    | jmp 0x4113E7                              | 跳转到递增语句处
00411413 | 33C0                     | xor eax,eax                               | main.c:10

C/C++ 反汇编:流程控制与循环结构

接着实现多分支for循环,也就是循环内部嵌套循环,接下来通过一个9x9口诀表分析,观察汇编代码变化.

#include <stdio.h>

int main(int argc, char* argv[])
{
	int x,y;

	for (x = 1; x <= 9; x++)
	{
		for (y = 1; y <= x; y++)
		{
			printf("%d*%d=%dt", y, x, x*y);
		}
		printf("n");
	}
	system("pause");
	return 0;
}
004113DE | C745 F8 01000000         | mov dword ptr ss:[ebp-0x8],0x1            | x = 1
004113E5 | EB 09                    | jmp 0x4113F0                              |
004113E7 | 8B45 F8                  | mov eax,dword ptr ss:[ebp-0x8]            |
004113EA | 83C0 01                  | add eax,0x1                               | 外层循环计数器
004113ED | 8945 F8                  | mov dword ptr ss:[ebp-0x8],eax            |
004113F0 | 837D F8 09               | cmp dword ptr ss:[ebp-0x8],0x9            | 比较外层循环x是否大于9
004113F4 | 7F 5C                    | jg 0x411452                               |
004113F6 | C745 EC 01000000         | mov dword ptr ss:[ebp-0x14],0x1           | y = 1
004113FD | EB 09                    | jmp 0x411408                              |
004113FF | 8B45 EC                  | mov eax,dword ptr ss:[ebp-0x14]           |
00411402 | 83C0 01                  | add eax,0x1                               | 内层循环计数器递增
00411405 | 8945 EC                  | mov dword ptr ss:[ebp-0x14],eax           |
00411408 | 8B45 EC                  | mov eax,dword ptr ss:[ebp-0x14]           | y
0041140B | 3B45 F8                  | cmp eax,dword ptr ss:[ebp-0x8]            | cmp y,x
0041140E | 7F 29                    | jg 0x411439                               | 大于则跳
00411410 | 8B45 F8                  | mov eax,dword ptr ss:[ebp-0x8]            | main.c:11
00411413 | 0FAF45 EC                | imul eax,dword ptr ss:[ebp-0x14]          |
00411417 | 8BF4                     | mov esi,esp                               |
00411419 | 50                       | push eax                                  |
0041141A | 8B4D F8                  | mov ecx,dword ptr ss:[ebp-0x8]            |
0041141D | 51                       | push ecx                                  |
0041141E | 8B55 EC                  | mov edx,dword ptr ss:[ebp-0x14]           |
00411421 | 52                       | push edx                                  |
00411422 | 68 58584100              | push consoleapplication1.415858           | 415858:"%d*%d=%dt"
00411427 | FF15 18914100            | call dword ptr ds:[<&printf>]             | 输出三个参数
0041142D | 83C4 10                  | add esp,0x10                              |
00411430 | 3BF4                     | cmp esi,esp                               |
00411432 | E8 04FDFFFF              | call 0x41113B                             |
00411437 | EB C6                    | jmp 0x4113FF                              | main.c:12
00411439 | 8BF4                     | mov esi,esp                               | main.c:13
0041143B | 68 64584100              | push consoleapplication1.415864           | 415864:L"n"
00411440 | FF15 18914100            | call dword ptr ds:[<&printf>]             | 外层循环增加换行
00411446 | 83C4 04                  | add esp,0x4                               |
00411449 | 3BF4                     | cmp esi,esp                               |
0041144B | E8 EBFCFFFF              | call 0x41113B                             |
00411450 | EB 95                    | jmp 0x4113E7                              | main.c:14
00411452 | 68 68584100              | push consoleapplication1.415868           | main.c:15, 415868:"pause"==L"慰獵e"
00411457 | E8 49FCFFFF              | call 0x4110A5                             |
0041145C | 83C4 04                  | add esp,0x4                               |

x64dbg 摘要

C/C++ 反汇编:流程控制与循环结构

iDA 摘要

C/C++ 反汇编:流程控制与循环结构

SWITCH-条件选择结构: 这个结构很有意思,还原它也不是太难,主要是该结构通过查表得到执行哪条语句,只要找到分支所对应的表格就能逆向出不同分支的作用.

#include <stdio.h>

int main(int argc, char* argv[])
{
	int x;
	scanf("%d", &x);
	switch (x)
	{
	case 0:
		printf("case 0"); break;
	case 1:
		printf("case 1"); break;
	case 2:
		printf("case 2"); break;
	case 3:
		printf("case 3"); break;
	default:
		printf("none"); break;
	}
	return 0;
}
004113F9 | 8B45 F8                  | mov eax,dword ptr ss:[ebp-0x8]            | main.c:7
004113FC | 8985 30FFFFFF            | mov dword ptr ss:[ebp-0xD0],eax           | 假设输入的是1
00411402 | 83BD 30FFFFFF 03         | cmp dword ptr ss:[ebp-0xD0],0x3           | cmp 1,3
00411409 | 77 71                    | ja 0x41147C                               | 高于则跳,跳到default
0041140B | 8B8D 30FFFFFF            | mov ecx,dword ptr ss:[ebp-0xD0]           | ecx = 输入的分支数字,此处是1
00411411 | FF248D D4144100          | jmp dword ptr ds:[ecx*4+<>]               | jmp 1*4 + 0x4114D4
00411418 | 8BF4                     | mov esi,esp                               | main.c:10
0041141A | 68 5C584100              | push consoleapplication1.41585C           | 41585C:"case 0"
0041141F | FF15 18914100            | call dword ptr ds:[<&printf>]             |
00411425 | 83C4 04                  | add esp,0x4                               |
00411428 | 3BF4                     | cmp esi,esp                               |
0041142A | E8 0CFDFFFF              | call 0x41113B                             |
0041142F | EB 62                    | jmp 0x411493                              |
00411431 | 8BF4                     | mov esi,esp                               | main.c:12
00411433 | 68 64584100              | push consoleapplication1.415864           | 415864:"case 1"
00411438 | FF15 18914100            | call dword ptr ds:[<&printf>]             |
0041143E | 83C4 04                  | add esp,0x4                               |

C/C++ 反汇编:流程控制与循环结构

代码中有三个主分支,一个默认分支,所以这里能看到每个分支所对应的物理地址。

C/C++ 反汇编:流程控制与循环结构

x64dbg 会将其标注为红色。

C/C++ 反汇编:流程控制与循环结构

ida 的分析则更加强大。

C/C++ 反汇编:流程控制与循环结构

分析C++中异常处理

异常处理是任何一门编程语言都存在的一个特性,同样C++也规定了异常处理的写法,但由于C++标准中并没有明确定义异常处理的实现流程,因此导致不同编译器厂商在实现异常处理时各有不同,我们将以VS2013编译器所生成的异常处理代码进行深入分析,其他编译器自行研究吧.

下来手动注册一个异常处理函数

#include <iostream>
#include <Windows.h>

using namespace std;

LONG __stdcall MyException1(_EXCEPTION_POINTERS *Ecptpoints)
{
	printf("发生异常,触发异常处理n");
	return 0;
}

int main(int argc, char* argv[])
{
	SetUnhandledExceptionFilter(MyException1); //设置异常的回调函数
	int *ptr = 0;
	*ptr = 1;
	system("pause");
	return 0;
}
#include <iostream>
#include <Windows.h>

using namespace std;

int main(int argc, char* argv[])
{
	try
	{
		throw -1; //抛出int类型异常
	}
	catch (int e)
	{
		printf("抛出了int类型异常. n");
	}
	catch (float e)
	{
		printf("抛出了float类型异常. n");
	}
	return 0;
}
00415220 | 55                       | push ebp                               | main.cpp:7
00415221 | 8BEC                     | mov ebp,esp                            |
00415223 | 6A FF                    | push 0xFFFFFFFF                        |
00415225 | 68 E0904100              | push <__ehhandler$_main>               | 压入异常回调函数
0041522A | 64:A1 00000000           | mov eax,dword ptr fs:[0]               |
00415230 | 50                       | push eax                               |
00415231 | 64:8925 00000000         | mov dword ptr fs:[0],esp               | 注册异常回调处理函数
00415238 | 51                       | push ecx                               | ecx:"榈K"
00415239 | 81EC E4000000            | sub esp,0xE4                           |
0041523F | 53                       | push ebx                               |
00415240 | 56                       | push esi                               | esi:"榈K"
00415241 | 57                       | push edi                               | edi:"榈K"
00415242 | 8DBD 0CFFFFFF            | lea edi,dword ptr ss:[ebp-0xF4]        |
00415248 | B9 39000000              | mov ecx,0x39                           | ecx:"榈K", 39:'9'
0041524D | B8 CCCCCCCC              | mov eax,0xCCCCCCCC                     |
00415252 | F3:AB                    | rep stosd                              |
00415254 | 8965 F0                  | mov dword ptr ss:[ebp-0x10],esp        |
00415257 | C745 FC 00000000         | mov dword ptr ss:[ebp-0x4],0x0         | 设置异常编号
0041525E | C785 10FFFFFF FFFFFFFF   | mov dword ptr ss:[ebp-0xF0],0xFFFFFFFF | main.cpp:10
00415268 | 68 60E94100              | push <consoleapplication2.__TI1H>      | 压入异常结构
0041526D | 8D85 10FFFFFF            | lea eax,dword ptr ss:[ebp-0xF0]        | 获取异常分配函数地址
00415273 | 50                       | push eax                               |
00415274 | E8 A3BFFFFF              | call 0x41121C                          | 调用异常分配函数
00415279 | 8BF4                     | mov esi,esp                            | main.cpp:14
0041527B | 68 6CCC4100              | push consoleapplication2.41CC6C        | 41CC6C:"抛出了int类型异常. n"
00415280 | FF15 80014200            | call dword ptr ds:[<&printf>]          |
00415286 | 83C4 04                  | add esp,0x4                            |

原文链接: https://www.cnblogs.com/LyShark/p/12715614.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

    C/C++ 反汇编:流程控制与循环结构

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/196100

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月12日 下午7:09
下一篇 2023年2月12日 下午7:09

相关推荐