【问题标题】:Assembly puzzle - binary bomb组装拼图-二元炸弹
【发布时间】:2014-02-11 04:00:16
【问题描述】:

我有以下汇编代码:

0x08048d36 <+0>:     push   %ebp
0x08048d37 <+1>:     mov    %esp,%ebp
0x08048d39 <+3>:     push   %esi
0x08048d3a <+4>:     push   %ebx
0x08048d3b <+5>:     sub    $0x20,%esp
0x08048d3e <+8>:     lea    -0x10(%ebp),%eax
0x08048d41 <+11>:    mov    %eax,0xc(%esp)
0x08048d45 <+15>:    lea    -0xc(%ebp),%eax
0x08048d48 <+18>:    mov    %eax,0x8(%esp)
0x08048d4c <+22>:    movl   $0x804a28a,0x4(%esp)
0x08048d54 <+30>:    mov    0x8(%ebp),%eax
0x08048d57 <+33>:    mov    %eax,(%esp)
0x08048d5a <+36>:    call   0x8048758 <__isoc99_sscanf@plt>
0x08048d5f <+41>:    cmp    $0x1,%eax
0x08048d62 <+44>:    jg     0x8048d69 <phase_5+51>
0x08048d64 <+46>:    call   0x80491a8 <explode_bomb>
0x08048d69 <+51>:    mov    -0xc(%ebp),%eax
0x08048d6c <+54>:    and    $0xf,%eax
0x08048d6f <+57>:    mov    %eax,-0xc(%ebp)
0x08048d72 <+60>:    cmp    $0xf,%eax
0x08048d75 <+63>:    je     0x8048da0 <phase_5+106>
0x08048d77 <+65>:    mov    $0x0,%ecx
0x08048d7c <+70>:    mov    $0x0,%edx
0x08048d81 <+75>:    mov    $0x804a1e0,%ebx
0x08048d86 <+80>:    add    $0x1,%edx
0x08048d89 <+83>:    mov    (%ebx,%eax,4),%eax
0x08048d8c <+86>:    add    %eax,%ecx
0x08048d8e <+88>:    cmp    $0xf,%eax
0x08048d91 <+91>:    jne    0x8048d86 <phase_5+80>
0x08048d93 <+93>:    mov    %eax,-0xc(%ebp)
0x08048d96 <+96>:    cmp    $0xf,%edx
0x08048d99 <+99>:    jne    0x8048da0 <phase_5+106>
0x08048d9b <+101>:   cmp    -0x10(%ebp),%ecx
0x08048d9e <+104>:   je     0x8048da5 <phase_5+111>
0x08048da0 <+106>:   call   0x80491a8 <explode_bomb>
0x08048da5 <+111>:   add    $0x20,%esp
0x08048da8 <+114>:   pop    %ebx
0x08048da9 <+115>:   pop    %esi
0x08048daa <+116>:   pop    %ebp
0x08048dab <+117>:   ret    

Scanf 期望用户提供两个数字。 行中引用的地址 $0x804a1e0 似乎引用了一个数组。当我获取该数组的值时,我得到:

(gdb) x/15dw 0x804a1e0
0x804a1e0 <array.2985>: 10      2       14      7
0x804a1f0 <array.2985+16>:      8       12      15      11
0x804a200 <array.2985+32>:      0       4       1       13
0x804a210 <array.2985+48>:      3       9       6

我不知道我应该如何处理这些信息。我知道这个汇编代码中有一个循环,它会一直回到 行,直到 $eax 保持值 15,但我不知道这个函数需要什么代码才能成功退出。

【问题讨论】:

  • 您希望 gdb 命令 x /15dw 0x804a1e0 显示数组的内容(字,而不是字节)。
  • 感谢您的提示。我已经编辑了问题。

标签: assembly gdb


【解决方案1】:

代码看起来基本上是这样的

static int array[15] = { 10, 2, 14, 7, 8, 12, 15, 11, 0, 4, 1, 13, 3, 9, 6 };
void phase_5(char *s) {
    int a, b;
    if (sscanf(s, "%d%d", &a, &b) <= 1)
        explode_bomb();
    a &= 0xf;
    if (a != 0xf) {
        int c = 0, d = 0;
        do {
            d++;
            a = array[a];
            c += a;
        } while (a != 0xf);
        if (d == 15 && c == b) return;
    }
    explode_bomb();
}

【讨论】:

  • @ChrisDodd 对不起,我是 C 新手,你能解释一下吗,你是如何从上面得到 %d %d 的值的?是 (15, 115) 吗?我正在尝试遵循这一点,但仍然不明白。 a=15 , b= sum( 数组[i] ) ?
  • @JPC: "%d%d" 是地址 0x804a28a 处的字符串,并从语句“Scanf 期望用户提供两个数字”中假定,因为该内存的内容实际上并未显示。
  • @JPC -- “解决方案”(不触发炸弹的输入)是 a 的初始值,它导致循环遍历整个数组(这是 0.. 中唯一的数字) 15 不存在于数组中),并且 b = sum(array)。所以 5 115 是关键
  • 嗨@ChrisDodd,所以我试图从代码中弄清楚。多于。我怎么能在不引爆炸弹的情况下返回。从阅读这个..我是C新手并试图阅读这段代码。但不太明白,所以循环了 15 次,加起来 c ,因此 c 应该是我的输入 b ,对吗?但是 "a" 不能等于 0xf ,即 14 ,那么这意味着 array[14] 是否从总和中排除? 115 是总和,115 - 6 ? => 所以避免炸弹的输入将是 15,109 或 %d,%d
猜你喜欢
  • 1970-01-01
  • 2013-11-07
  • 2016-08-13
  • 2016-09-05
  • 2017-04-18
  • 2020-06-04
  • 2018-04-02
  • 2017-03-26
相关资源
最近更新 更多