反汇编即把目标二进制机器码转为汇编代码的过程,该技术常用于软件破解、外挂技术、病毒分析、逆向工程、软件汉化等领域,学习和理解反汇编对软件调试、系统漏洞挖掘、内核原理及理解高级语言代码都有相当大的帮助,软件一切神秘的运行机制全在反汇编代码里面。
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) 语句的表现形式
if (z >= x || z >= y) 稍微改变成或者,再来观察程序流程,两个结构对比,然后总结经验,或者与并且两个语句在实现上的异同点。
如果将代码编译为 Release 版本,你会发现if语句被优化没了,只保留了一个打印结果,这个优化还是很牛b的,整个结构都被重定义了。编译器认为你的判断没有任何意义,所以直接就给你干掉了,只保留了一个输出结果,这个输出结果是一定会被执行的,是一个定死的。
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 |
WHILE-循环: x++ 是jge来操控,++x是jg
#include <stdio.h>
int main(int argc, char* argv[])
{
int x = 0;
while (x <= 10)
{
printf("打印: %d\n", 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:"打印: %d\n"
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
在此基础上稍微增加难度,在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
继续修改源代码,增加双层循环,实现嵌套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
这里的打印参数,很有趣,取值并压入两个参数,然后调用的printf.
DO-WHILE条件循环: 与while循环不同,do会先执行循环然后判断,如下代码反编译观察.
#include <stdio.h>
int main(int argc, char* argv[])
{
int x = 0,y=0;
do
{
printf("外层do-while 循环: %d\n", x);
while (y <= 5)
{
printf("内层while 循环: %d\n", 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 循环: %d\n"
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 循环: %d\n"
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
FOR-条件循环:
#include <stdio.h>
int main(int argc, char* argv[])
{
int x;
for (x = 0; x <= 10; x++)
{
printf("循环计数: %d\n", 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:"循环计数: %d\n"
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
接着实现多分支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=%d\t", 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=%d\t"
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 摘要
iDA 摘要
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 |
代码中有三个主分支,一个默认分支,所以这里能看到每个分支所对应的物理地址。
x64dbg 会将其标注为红色。
ida 的分析则更加强大。
异常处理是任何一门编程语言都存在的一个特性,同样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 |