学习 2017 年 9 月 28 日

Switch反汇编

记录Switch在反汇编中的四种表现形式

Switch在反汇编中有四种表现形式

  • 第一种当case个数小于三个时,同if…else语句,je跳转到代码位置执行

    Switch(3)
    {
      case 1:
        printf("1");
        break;
      case 2:
        printf("2");
        break;
      case 3:
        printf("3");
        break;
      default:
        printf("ERR");
    }
  • 第二种当case中的数大多为连续值时,编译器会生成一张大表,表中存储了每个case对应的代码地址,然后通过JMP [eax*4+基址]跳转到相应代码([eax*4+基址]为大表中存储的每个case对应的代码地址),case中不存在的那个几个连续值对应的代码位置为default代码地址。

    Switch(3)
    {
      case 1:
        printf("1");
        break;
      case 2:
        printf("2");
        break;
      case 3:
        printf("3");
        break;
      /* case 4的位置在大表中存储的为default代码地址
      case 4:
        printf("4");
        break;
      */
      case 5:
        printf("5");
        break;
      case 6:
        printf("6");
        break;
      case 7:
        printf("7");
        break;
      case 8:
        printf("8");
        break;
      default:
        printf("ERR");
    }
  • 第三种当case中的数为不是连续值时,且最大最小值之差不超过255时,编译器会生成一张小表,一张大表;大表中仅存储每个case对应的代码地址(与第二种区别在于不会存储case中不存在的那些值),而小表则存储连续的值,每个值对应的为大表的下标。

    Switch(3)
    {
      case 1:
        printf("1");
        break;
      case 2:
        printf("2");
        break;
      case 3:
        printf("3");
        break;
      case 4:
        printf("4");
        break;
      case 5:
        printf("5");
        break;
      case 60:
        printf("60");
        break;
      case 70:
        printf("70");
        break;
      case 80:
        printf("80");
        break;
      default:
        printf("ERR");
    }
  • 第四种case中的数为不是连续值时,且最大最小值之差超过255时,表现形式类似第一种,但是通过二叉树进行跳转

    Switch(300)
    {
      case 100:
        printf("100");
        break;
      case 200:
        printf("200");
        break;
      case 300:
        printf("300");
        break;
      case 4000:
        printf("4000");
        break;
      case 5000:
        printf("5000");
        break;
      case 6000:
        printf("6000");
        break;
      case 7000:
        printf("7000");
        break;
      case 8000:
        printf("8000");
        break;
      default:
        printf("ERR");
    }