我是组装新手,正在做这个炸弹实验室,并卡在 0x0000555555555612 <+71>。我的输入是 0 1 1 11 1 11
0x00005555555555cb <+0>: endbr64
0x00005555555555cf <+4>: push %rbp
0x00005555555555d0 <+5>: push %rbx
0x00005555555555d1 <+6>: sub $0x28,%rsp
0x00005555555555d5 <+10>: mov %fs:0x28,%rax
0x00005555555555de <+19>: mov %rax,0x18(%rsp)
0x00005555555555e3 <+24>: xor %eax,%eax
0x00005555555555e5 <+26>: mov %rsp,%rsi
0x00005555555555e8 <+29>: callq 0x555555555bd6 <read_six_numbers>
0x00005555555555ed <+34>: cmpl $0x0,(%rsp)
0x00005555555555f1 <+38>: jne 0x5555555555fa <phase_2+47>
0x00005555555555f3 <+40>: cmpl $0x1,0x4(%rsp)
0x00005555555555f8 <+45>: je 0x5555555555ff <phase_2+52>
0x00005555555555fa <+47>: callq 0x555555555baa <explode_bomb>
0x00005555555555ff <+52>: mov %rsp,%rbx
0x0000555555555602 <+55>: lea 0x10(%rsp),%rbp
0x0000555555555607 <+60>: jmp 0x555555555617 <phase_2+76>
0x0000555555555609 <+62>: callq 0x555555555baa <explode_bomb>
0x000055555555560e <+67>: add $0x4,%rbx
=> 0x0000555555555612 <+71>: cmp %rbp,%rbx
--Type <RET> for more, q to quit, c to continue without paging--c
0x0000555555555615 <+74>: je 0x555555555623 <phase_2+88>
0x0000555555555617 <+76>: mov 0x4(%rbx),%eax
0x000055555555561a <+79>: add (%rbx),%eax
0x000055555555561c <+81>: cmp %eax,0x8(%rbx)
0x000055555555561f <+84>: je 0x55555555560e <phase_2+67>
0x0000555555555621 <+86>: jmp 0x555555555609 <phase_2+62>
0x0000555555555623 <+88>: mov 0x18(%rsp),%rax
0x0000555555555628 <+93>: xor %fs:0x28,%rax
0x0000555555555631 <+102>: jne 0x55555555563a <phase_2+111>
0x0000555555555633 <+104>: add $0x28,%rsp
0x0000555555555637 <+108>: pop %rbx
0x0000555555555638 <+109>: pop %rbp
0x0000555555555639 <+110>: retq
0x000055555555563a <+111>: callq 0x555555555220 <__stack_chk_fail@plt>
根据我的理解,0x0000555555555612<+71>比较%rbx和%rbp,如果相等,它将跳转到0x0000555555555623<+88>。我有 rbx 和 rbp 的检查值。
x/d $rbp 0x7fffffffd100: 1 (gdb) ni 0x0000555555555615 in phase_2 () (gdb) ni 0x0000555555555617 in phase_2 () (gdb) x/d $rbx 0x7fffffffd0f4: 1
看起来 rbp 和 rbx 都等于 1,但是为什么它们不跳到 0x0000555555555623 <+88>。任何解释将不胜感激。
链表解决方案 最后一个炸弹通常是一个链表。你必须输入6个数字1 2 3 4 5 6。你必须弄清楚数字的输入顺序。您需要通过检查寄存器来发现链接列表,当代码在寄存器中有一个节点时,键入 x/80xw $reg。该列表包括记录的节点名称(例如node_1)、值和指针。指针并不重要。必须对值进行排序。通常从最大到最小。那么输入的数字就是节点号。为了。也许递减(递增?)的节点顺序是 1 4 3 5 6 2。通常这是输入,但我见过需要这些数字的补码作为输入的炸弹(通过从 7 中减去数字来补)。输入将是 6 3 4 2 1 5。开始时有很多循环,确保您的输入是六个数字 1 2 3 4 5 6。没有重复。最后一个循环检查顺序。该循环在底部附近将进行条件比较,以确保您输入的节点的值按递增或递减顺序排列。另一个条件跳转为每个比较循环 5 次。您需要找到节点比较并设置断点。勇敢地输入 c 继续到这个断点。代码太多,无法单步执行。
如果您以任何顺序包含数字 1 2 3 4 5 6 (不重复),您将不会在代码的前半部分爆炸炸弹。代码的最后一部分确保数字的顺序正确。检查寄存器也许是 gdb 命令
x/20xw $reg 可以工作
当您找到保存节点的内存时,将会有很多额外的信息,包括
通常当你发现链表node_6丢失时。我通过检查顺序比较中的值发现了node_6。您还可以通过查看链接列表中的指针来发现node_6