知识点: 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