逆向-逻辑流控制

逻辑流控制

在个人抽象中执行逻辑有三种-顺序、选择、循环。默认汇编就是从上到下顺序执行,选择用if-else和switch,循环用while、for等。性能

分支语句

if-else

int main(int argc, char const *argv[])
{
    int a=10;
    if (a>10){
         printf("a>10");
     }else{
         printf("a<=10");
     }
    return 0;

int main(int argc, char const *argv[])
{
    int a=10;
    if (a>10){
        printf("a>10");
    }else if(a<2){
        printf("a<2");
    }else{
        printf("2<=a<=10");
    }
    return 0;
}

从上面两个二分支和三分支能够看出:测试

  1. 开始标志就是cmp,jcc 这两条标志语句,表明条件判断。
  2. 直接跳转的jmp表明执行的是它上面的分支。
  3. 每一个分支内jmp跳的地址是同样的都是else{};这条语句以后的位置。
  4. 巧妙的运用了顺序结构

switch

int main(int argc, char const *argv[])
{
    int a=11;
    switch (a)
    {
    case 10:
        printf("a=10");
        break;
    case 11:
        printf("a=11");
        break;
    case 12:
        printf("a=12");
        break;  
    case 13:
        printf("a=13");c
        break;  
    case 14:
        printf("a=14");
        break;  
    default:
        printf("!!");
    }
    return 0;
}

特征

  1. 当switch分支小的时候(视不一样编译器实现,visual studio 为3个(包含)如下)返回百年结构和if-else结构相同,可是当分支测试的常量连续而且有必定数目,就会根据一个表保存要跳转的地址。
  2. 若是不是从0开始编译器会减去测试常量这个连续序列的最小值,直接获得偏移地址,加上基址便可到要跳转的分支。

总结

从分支语句中咱们能够总结一些特征,测试条件用cmp、fcmp等指令,下面紧跟着jcc指令。jmp表明这个分支执行完了,通常跳出这个分支检测结构,而上面的cmp;jcc连着用的话通常指紧跟着的分支的否认,通常会跳到最后一个分支。switch在大量、连续的分支测试比if-else性能高。3d

循环

for (a=0;a<10;a++){
        sum=sum+a;
    }
80483ef:       c7 45 f8 00 00 00 00    mov    DWORD PTR [ebp-0x8],0x0
 80483f6:       eb 0a                   jmp    8048402 <main+0x27>
        sum=sum+a;
 80483f8:       8b 45 f8                mov    eax,DWORD PTR [ebp-0x8]
 80483fb:       01 45 fc                add    DWORD PTR [ebp-0x4],eax
    for (a=0;a<10;a++){
 80483fe:       83 45 f8 01             add    DWORD PTR [ebp-0x8],0x1
 8048402:       83 7d f8 09             cmp    DWORD PTR [ebp-0x8],0x9
 8048406:       7e f0                   jle    80483f8 <main+0x1d>
初始化
a=0
mov    DWORD PTR [ebp-0x8],0x0
条件判断,能够看到cmp;jcc;判断
cmp    DWORD PTR [ebp-0x8],0x9
jle    80483f8 <main+0x1d>
控制变量变化
DWORD PTR [ebp-0x8],0x1
从上到下执行,首先初始化变量,接着直接jmp到cmp判断循环变量,向上跳到循环体

break和continue

for (a=0;a<10;a++){
        if (a == 6){
            continue;
        }
        if (a == 7){
            break;
        }
        sum=sum+a;
    }
80483ef:       c7 45 f8 00 00 00 00    mov    DWORD PTR [ebp-0x8],0x0
80483f6:       eb 19                   jmp    8048411 <main+0x36>
80483f8:       83 7d f8 06             cmp    DWORD PTR [ebp-0x8],0x6
80483fc:       74 0e                   je     804840c <main+0x31>
80483fe:       83 7d f8 07             cmp    DWORD PTR [ebp-0x8],0x7
8048402:       74 15                   je     8048419 <main+0x3e>
8048404:       8b 45 f8                mov    eax,DWORD PTR [ebp-0x8]
8048407:       01 45 fc                add    DWORD PTR [ebp-0x4],eax
804840a:       eb 01                   jmp    804840d <main+0x32>
804840c:       90                      nop
804840d:       83 45 f8 01             add    DWORD PTR [ebp-0x8],0x1
8048411:       83 7d f8 09             cmp    DWORD PTR [ebp-0x8],0x9
8048415:       7e e1                   jle    80483f8 <main+0x1d>
8048417:       eb 01                   jmp    804841a <main+0x3f>
8048419:       90                      nop
804841a:       b8 00 00 00 00          mov    eax,0x0
804841f:       c9                      leave
8048420:       c3                      ret

break跳出循环jmp 804840dcode

continue跳到循环变量控制也就是a++;add DWORD PTR [ebp-0x8],0x1blog

总结

for循环典型特征jmp指令,循环体,条件控制和判断。jmp跳条件控制和判断,而后回调循环体。编译器

相关文章
相关标签/搜索