【问题标题】:reverse engineering a switch statement in C from x86 assembly从 x86 程序集逆向工程 C 中的 switch 语句
【发布时间】:2017-03-25 08:11:10
【问题描述】:

我必须从汇编中对 C 中的 switch 语句进行逆向工程。当我使用 -S 标志从我编写的 C 中获取汇编代码进行编译时,这是不正确的。关于我做错了什么的任何见解?

提前致谢!

这是程序集

.file "switch_prob-soln.c"
.text
.globl switch_prob
.type switch_prob, @function
switch_prob:
.LFB0:
.cfi_startproc
subq $50, %rsi
cmpq $5, %rsi
ja .L2
jmp *.L7(,%rsi,8)
.section .rodata
.align 8
.align 4
.L7:
.quad .L3
.quad .L2
.quad .L3
.quad .L4
.quad .L5
.quad .L6
.text
.L3:
leaq 0(,%rdi,4), %rax 
ret
.L4:
movq %rdi, %rax
sarq $2, %rax
ret
.L5:
leaq (%rdi,%rdi,2), %rdi
.L6:
imulq %rdi, %rdi
.L2:
leaq 10(%rdi), %rax
ret
.cfi_endproc
.LFE0:
.size switch_prob, .-switch_prob
.ident "GCC: (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3"
.section .note.GNU-stack,"",@progbits

这是我写的 C

  long switch_prob(long x, long n){
    long result = x; 
    switch(n){

      case 50:  
      case 51:
      result + 4; 
      break; 

      case 52:
      result >> 2; 
      break; 

      case 53:
      result + result + 2; 

      merge: 
      result * result
      break;

      default:
      result * 10;
      break;
   }
    return result;
  }

【问题讨论】:

  • 除了long result - x; 没有任何意义,而且您的计算没有任何副作用,您还可以在函数中定义一个函数,它不是 C。
  • "...不正确。" 怎么样?您还没有解释实际问题是什么。
  • 你应该编译你的 C 代码为gcc -Wall -S -O -fverbose-asm 并且你需要改进代码直到你没有收到警告。请注意,result*10;(倒数第 4 行)没有可观察到的副作用,因此很可能会被优化和删除。也许您的意思是 return result * 10;,但这只是猜测。

标签: c x86 reverse-engineering


【解决方案1】:

按照汇编代码的逻辑,我猜是这样的:

int switch_prob(int x, int n) {
    int result = x; 

    switch (n - 50) {

        case 0:  
        case 2:
            result += 4; 
            break; 

        case 3:
            result >>= 2; 
            break; 

        case 4:
            result += 2; 

        case 5: 
            result *= result;
            break;

        default:
            result += 10;
    }

    return result;
}

您可以测试您的解决方案的一种方法是编写如下驱动程序:

test.c

#include <stdio.h>

int switch_prob(int x, int n);


int main() {

    printf("%d\n", switch_prob(1, 54));

    return 0;
}

然后编译汇编代码,如果它与您的系统兼容,则使用您的驱动程序:

gcc -Wall test.c switch_prob-soln.s

然后编辑您的 test.c 文件,将参数更改为 switch_prob() 以查看您的假设是否成立。我猜跳转表告诉我们一些案例:

.quad .L3 # case 0: addition (LEA)
.quad .L2 # default: (no case 1:) addition (LEA)
.quad .L3 # case 2: is case 0: again
.quad .L4 # case 3: right shift (SAR)
.quad .L5 # case 4: addition (LEA)
.quad .L6 # case 5: multiplication (IMUL)

【讨论】:

  • 这很有帮助,谢谢!我一定会试试这个
  • 最后一个问题,我知道 lea 可以用于操作,就像这里一样,但我也读到它本质上是一种将某些内容从一个索引移动到另一个索引的方法,例如在数组中,还是我解释错了? (对不起,我对组装很陌生,从 OO 的逻辑飞跃对我来说很难)。
猜你喜欢
  • 2011-01-17
  • 2015-06-29
  • 1970-01-01
  • 2015-08-15
  • 2012-05-01
  • 2010-10-12
  • 2011-11-19
  • 1970-01-01
  • 2016-09-27
相关资源
最近更新 更多