Assembly 组装之谜-二元炸弹

Assembly 组装之谜-二元炸弹,assembly,gdb,Assembly,Gdb,我有以下汇编代码: 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

我有以下汇编代码:

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    
0x08048d36:推送%ebp
0x08048d37:mov%esp,%ebp
0x08048d39:推送%esi
0x08048d3a:推送%ebx
0x08048d3b:子$0x20,%esp
0x08048d3e:lea-0x10(%ebp),%eax
0x08048d41:mov%eax,0xc(%esp)
0x08048445:lea-0xc(%ebp),%eax
0x08048d48:mov%eax,0x8(%esp)
0x08048d4c:movl$0x804a28a,0x4(%esp)
0x08048d54:mov 0x8(%ebp),%eax
0x08048d57:mov%eax,(%esp)
0x08048d5a:呼叫0x8048758
0x08048d5f:cmp$0x1,%eax
0x08048d62:jg 0x8048d69
0x08048d64:调用0x80491a8
0x08048d69:mov-0xc(%ebp),%eax
0x08048d6c:和$0xf,%eax
0x08048d6f:mov%eax,-0xc(%ebp)
0x08048d72:cmp$0xf,%eax
0x08048d75:je 0x8048da0
0x08048d77:mov$0x0,%ecx
0x08048d7c:mov$0x0,%edx
0x08048d81:mov$0x804a1e0,%ebx
0x08048d86:添加$0x1,%edx
0x08048d89:mov(%ebx,%eax,4),%eax
0x08048d8c:添加%eax,%ecx
0x08048d8e:cmp$0xf,%eax
0x08048d91:jne 0x8048d86
0x08048d93:mov%eax,-0xc(%ebp)
0x08048d96:cmp$0xf,%edx
0x08048d99:jne 0x8048da0
0x08048d9b:cmp-0x10(%ebp),%ecx
0x08048d9e:je 0x8048da5
0x08048da0:调用0x80491a8
0x08048da5:添加$0x20,%esp
0x08048da8:弹出%ebx
0x08048da9:弹出%esi
0x08048daa:弹出%ebp
0x080484B: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
(gdb)x/15dw 0x804a1e0
0x804a1e0:102 14 7
0x804a1f0:8121511
0x804a200:0 4 1 13
0x804a210:39 6

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

代码看起来基本上是

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();
}
static int array[15]={10,2,14,7,8,12,15,11,0,4,1,13,3,9,6};
无效相位_5(字符*s){
INTA,b;

如果(sscanf,“%d%d”,&a,&b)您希望gdb命令
x/15dw 0x804a1e0
显示数组的内容(字,而不是字节)。谢谢您的提示。我已经编辑了这个问题。@chrisdd对不起,我是C新手,您能解释更多吗,您实际上如何从上面得到%d%d的值?是(15,115)?我试图理解这个,但仍然不明白。a=15,b=sum(数组[I])?@JPC:
%d%d
是地址0x804a28a处的字符串,并且是根据语句“Scanf期望用户提供两个数字”假设的,因为该内存的内容实际上没有显示。@JPC--解决方案(不会触发炸弹的输入)是导致整个数组循环的a的初始值(这是0..15中唯一不在数组中的数字),b=总和(数组).所以5115是keyhi@chrisdDodd,所以我正试图从代码中找出它。上面。我怎么能不引爆炸弹就得到返回。通过阅读这个..我对C不熟悉,并且尝试阅读这个代码。但是没有完全理解,所以循环了15次,加上C,所以C应该是我的输入b,对吗?但是“a”不能等于0xf,也就是14,这是平均数组[14],从总和中排除?115是总和,115-6?=>所以避免爆炸的输入是15109或%d,%d