装配x86开关盒混淆

时间:2015-02-06 20:50:49

标签: assembly

在函数switch_case中,我在实现跳转表时遇到问题而不是更简单的L1:,L2:,L3:等

     080483ec <switch_case>:    
     80483ec:           push   %ebp
     80483ed:           mov    %esp,%ebp
     80483ef:           sub    $0x10,%esp  //create stack space
     80483f2:           mov    0x8(%ebp),%eax  //param x
     80483f5:           mov    %eax,-0x4(%ebp)  //x moved into -0x4(%ebp)
     80483f8:           mov    0xc(%ebp),%eax  //param n moved into %eax
     80483fb:           sub    $0x21,%eax   //subtract 21 from n
     80483fe:           cmp    $0x4,%eax    //compare 4 with n
     8048401:           ja     8048420 <switch_case+0x34> // jumping to 804820
     8048403:           mov    0x80484e0(,%eax,4),%eax
     804840a:           jmp    *%eax
     804840c:           subl   $0x2,-0x4(%ebp)
     8048410:           jmp    8048427 <switch_case+0x3b>
     8048412:           addl   $0x2,-0x4(%ebp)
     8048416:           jmp    8048427 <switch_case+0x3b>
     8048418:           shll   $0x3,-0x4(%ebp)
     804841c:           addl   $0x1,-0x4(%ebp)
     8048420:           movl   $0xa,-0x4(%ebp) // default starts here x=10
     8048427:           mov    -0x4(%ebp),%eax // n=x
     804842a:           leave
     804842b:           ret

我的问题是:

我如何知道哪种指示属于哪种情况?

到目前为止我理解(翻译为C):

    int switch_case( int x, int n) 
    { 

    int result = x; 

    switch( n) { 

    case ():
        x-=21; //guessing. dont think so?
            break;
    case ():

            break;
    case ():

            break;
    case ():

            break;

    default:
    x=10;
n=x;

            break;

          }//end 

    return result; 

    } 

我知道一个案例是x + = 2;另一个是x- = 2;另一个可能是x&lt;&lt; 3; x ++; ,但我完全迷失在找到他们去哪里以及比较是什么

1 个答案:

答案 0 :(得分:0)

subtract 21以十六进制开头,所以小数为subtract 33。它也发生在使用跳转表之前。逻辑是:

unsigned tmp = n - 33;
if (tmp > 4) goto default;
goto table[tmp];

这意味着,tmp可能是0 .. 3,这反过来意味着n的范围是33 .. {{1} }。至于代码的位置,您需要查看跳转表。从地址36开始,对于4个案例,您将有4个指针。