zoukankan      html  css  js  c++  java
  • 逆向知识第八讲,if语句在汇编中表达的方式

    一丶if else的最简单情况还原(无分支情况)

    高级代码:

    #include "stdafx.h"
    
    int main(int argc, char* argv[])
    {
        unsigned int nNumber = 0;
        scanf("%ud",&nNumber);
    
        if(argc == 0)
        {
            nNumber = 0;                //第一种情况下无分支
        }
        else
        {
            nNumber = -1;
        }
    
        return nNumber;
    }

    总共两种情况,我们看下Release中怎么优化的把(注意,优化方式选择O2,速度优先)

    汇编代码:

    可以看到我们熟悉的代码了.也就是昨天的三目运算.

    总共三行汇编代码.

    还原套路一样,还是 代入大于0 小于0 还有==0,看看最终结果是什么.

    鉴于昨天还原过代码了,这里这届代入,还原出高级代码.

    argc > 0的情况下
    if(argc > 0) eax = -1
    argc < 0的情况下
    if(argc < 0) eax =-1
    argc == 0的情况下
    if(argc == 0) eax = 0

    综合三种情况,可以得出具体的条件了.  其中 ><这样写是在高级语言中不能这样写的,

    所以得出的还原代码为

    if(argc == 0) eax =0 
    else eax == -1

     二丶if else 的第二种情况(减少分支)

    高级代码:

    #include "stdafx.h"
    
    int main(int argc, char* argv[])
    {
        unsigned int nNumber = 0;
        scanf("%ud",&nNumber);
    
        if(argc == nNumber)
        {
            printf("%d",nNumber / 8);
        }
        else
        {
            printf("%d",nNumber / 5);
        }
    
        return nNumber;
    }

    对应汇编代码:

    这个主要涉及找上下界问题

    1.地址:  1018 101C 分别保存了局部变量的值

    2.地址:  1023  比较了argc和局部变量Var4的值

    3.地址:  1025  jnz跳转,因为1023地址的比较会影响标志位 由此判定, argc和var4比较,jnz(不相等)但因为汇编中是反条件,所以是相等的情况下

    4.因为jnz是一个地址,所以这个地址是一个下界,那么jnz上面的比较代码则是上界,在其内部,我们还原为if语句块(先不用管里面具体干啥)

    还原if语句块

    if(argc == var4) printf("%d",var4 / 8);

    还原else语句块

    else  printf("%d",var4 / 5);

    在下方我们发现了相同的汇编代码,也就是把retn放到上面去了,这个主要是为了减少分支.

    三丶if else 第第三种形式,代码外提的情况

    代码外提的情况下,主要在优化方式的选择上,我们知道 o2(优化方式是速度优先)  现在我们改成o1(也就是体积优先了)

    这个时候就会出现代码外提.

    高级代码:

    #include "stdafx.h"
    
    int main(int argc, char* argv[])
    {
        unsigned int nNumber = 0;
        scanf("%ud",&nNumber);
    
        if(argc == nNumber)
        {
            printf("Hello");
        }
        else 
        {
            printf("World");
        }
        
        return nNumber;
    }

    切换为o1

    protect -> setting即可.

    对应汇编代码:

    首先,找if else的时候,先确定上下界

    地址: 101A位置   寻得了 if的上界

    地址: 101E位置  寻得了 if的下界

    注意: 中间划掉了两个指令,这两个指令是流水线优化,平栈的指令.所以没有帮助,划掉

    地址: 1025位置,其指令跳转的地址是一个增量,那么则确定是else的下界

    地址:  1027位置 寻得了else的上界

    其实简单来说,第一个跳转位置,跳转到哪里的一块区域,是一个if的语句块而跳转的位置则是else语句块的上界,其上面固定一个jmp(注意其地址跳转是一个增量)那么跳转的地址是else的下界

    重点代码外提:

    我们可以看到 我们的if语句块中 push了一个 hello,我们的else语句块中,push了一个 word

    那么除了if else 直接调用的printf,这样也是可以的.因为参数是一样的.平栈都是相等的.所以可以提到外面来打印输出.

     四丶多分支if elseif  .... else的还原

    这个其实很简单了.如果是多分支,则寻找上界下界即可.

    因为编译器做的东西很多了.

    高级代码:

    #include "stdafx.h"
    
    int main(int argc, char* argv[])
    {
      unsigned int nVar_4 = 5;
      scanf("%d", &nVar_4);
    
      // argc == 0 ? 0 : -1
      if (argc == 0)
      {
        printf("argc == 0
    ");
      }
      else if(argc == 1)
      {
        printf("argc == 1
    ");
      }
      else if(argc == 2)
      {
        printf("argc == 2
    ");
      }
      else if(argc == 3)
      {
        printf("argc == 3
    ");
      }
      else
      {
        printf("else
    ");
      }
      
      printf("haha
    ");
      printf("haha
    ");
      printf("haha
    ");
      printf("haha
    ");
      printf("haha
    ");
        return nVar_4;
    }

    对应汇编代码:

    看到这种,直接判断为 if else if else if else这种语句,然后寻找上下界即可.

    转载于:

    作者:IBinary
    出处:http://www.cnblogs.com/iBinary/

  • 相关阅读:
    LoaRunner性能测试系统学习教程:日志文件分析(8)
    LoaRunner性能测试系统学习教程:MPM相关参数(7)
    LoaRunner性能测试系统学习教程:MPM调优(6)
    响应器
    分页器
    权限组件、频率组件
    drf视图组件、认证组件
    drf序列化组件
    RESTful
    IO操作、PIL使用、Django的admin操作
  • 原文地址:https://www.cnblogs.com/gd-luojialin/p/11219813.html
Copyright © 2011-2022 走看看