知识点:
switch case生成的汇编框架
逆向汇编代码还原成C++代码
一、了解switch case结构
1、普通情况
00401011 |. 83C4 04 ADD ESP,4
00401014 |. C745 FC 20000>MOV DWORD PTR SS:[EBP-4],20 ; a=20;
0040101B |. 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4]
0040101E |. 8945 F8 MOV DWORD PTR SS:[EBP-8],EAX ; switch (a)
00401021 |. 837D F8 03 CMP DWORD PTR SS:[EBP-8],3 ; case 3:
00401025 |. 74 0E JE SHORT switchCa.00401035
00401027 |. 837D F8 04 CMP DWORD PTR SS:[EBP-8],4 ; case 4:
0040102B |. 74 28 JE SHORT switchCa.00401055
0040102D |. 837D F8 05 CMP DWORD PTR SS:[EBP-8],5 ; case 5:
00401031 |. 74 12 JE SHORT switchCa.00401045
00401033 |. EB 30 JMP SHORT switchCa.00401065 ; default:
2、跳转表
00401014 |. C745 FC 20000>MOV DWORD PTR SS:[EBP-4],20 ; a=20;
0040101B |. 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4]
0040101E |. 8945 F8 MOV DWORD PTR SS:[EBP-8],EAX ; b=a
00401021 |. 8B4D F8 MOV ECX,DWORD PTR SS:[EBP-8] ; b==1
00401024 |. 83E9 03 SUB ECX,3 ; a-0x3=跳转表数组大小
00401027 |. 894D F8 MOV DWORD PTR SS:[EBP-8],ECX
0040102A |. 837D F8 0E CMP DWORD PTR SS:[EBP-8],0E ; 0E=case最大常量-case最小常量
0040102E |. 77 61 JA SHORT switchCa.00401091 ; default:
00401030 |. 8B55 F8 MOV EDX,DWORD PTR SS:[EBP-8]
00401033 |. 0FB682 CC1040>MOVZX EAX,BYTE PTR DS:[EDX+4010CC] ; 跳转表的索引数组
0040103A |> FF2485 B41040>JMP DWORD PTR DS:[EAX*4+4010B4] ; /跳转表
知识点:
入口函数main的定位
逆向汇编代码还原成C++代码
索引表数组
跳转表
一、索引表及跳转表分析
1、确定case常量
18,20,28,32
2、确定case常量顺序 (可以根据 跳转表 调整也可以)
000210AC 00021063 30.00021063 18
000210B0 00021053 30.00021053 20
000210B4 00021048 30.00021048 28
000210B8 00021089 30.00021089 32
//调整后 实际上就是按地址大小排序
000210B4 00021048 30.00021048 28
000210B0 00021053 30.00021053 20
000210AC 00021063 30.00021063 18
000210B8 00021089 30.00021089 32
二、还原代码
printf("begin");
int a,b; a=0x16; b=3;
switch(a)
{
case 28:
b=b+a;
break;
case 20:
printf("123");
break;
//18,20,28,32
case 18:
if (b>9)
{
printf("3333");
}else
{
printf("2222");
}
break;
case 32:
printf("321");
//break;
default:
printf("00end");
break;
}
//end