我怎样才能解决二进制炸弹实验室第 6 阶段的问题?
How can I solve the binary bomblab phase 6?
这是我的phase_6反汇编代码请帮我解决这个问题。我知道答案应该是1到6之间的数字。
0x000055555555553e <+0>: push %r13
0x0000555555555540 <+2>: push %r12
0x0000555555555542 <+4>: push %rbp
0x0000555555555543 <+5>: push %rbx
0x0000555555555544 <+6>: sub [=10=]x68,%rsp
0x0000555555555548 <+10>: mov %fs:0x28,%rax
0x0000555555555551 <+19>: mov %rax,0x58(%rsp)
0x0000555555555556 <+24>: xor %eax,%eax
0x0000555555555558 <+26>: mov %rsp,%r12
0x000055555555555b <+29>: mov %r12,%rsi
0x000055555555555e <+32>: callq 0x5555555558c8 <read_six_numbers>
0x0000555555555563 <+37>: mov [=10=]x0,%r13d
0x0000555555555569 <+43>: jmp 0x555555555590 <phase_6+82>
0x000055555555556b <+45>: callq 0x5555555558a2 <explode_bomb>
0x0000555555555570 <+50>: jmp 0x55555555559f <phase_6+97>
0x0000555555555572 <+52>: add [=10=]x1,%ebx
0x0000555555555575 <+55>: cmp [=10=]x5,%ebx
0x0000555555555578 <+58>: jg 0x55555555558c <phase_6+78>
0x000055555555557a <+60>: movslq %ebx,%rax
0x000055555555557d <+63>: mov (%rsp,%rax,4),%eax
0x0000555555555580 <+66>: cmp %eax,0x0(%rbp)
0x0000555555555583 <+69>: jne 0x555555555572 <phase_6+52>
0x0000555555555585 <+71>: callq 0x5555555558a2 <explode_bomb>
0x000055555555558a <+76>: jmp 0x555555555572 <phase_6+52>
0x000055555555558c <+78>: add [=10=]x4,%r12
0x0000555555555590 <+82>: mov %r12,%rbp
0x0000555555555593 <+85>: mov (%r12),%eax
--Type <RET> for more, q to quit, c to continue without paging--c
0x0000555555555597 <+89>: sub [=10=]x1,%eax
0x000055555555559a <+92>: cmp [=10=]x5,%eax
0x000055555555559d <+95>: ja 0x55555555556b <phase_6+45>
0x000055555555559f <+97>: add [=10=]x1,%r13d
0x00005555555555a3 <+101>: cmp [=10=]x6,%r13d
0x00005555555555a7 <+105>: je 0x5555555555de <phase_6+160>
0x00005555555555a9 <+107>: mov %r13d,%ebx
0x00005555555555ac <+110>: jmp 0x55555555557a <phase_6+60>
0x00005555555555ae <+112>: mov 0x8(%rdx),%rdx
0x00005555555555b2 <+116>: add [=10=]x1,%eax
0x00005555555555b5 <+119>: cmp %ecx,%eax
0x00005555555555b7 <+121>: jne 0x5555555555ae <phase_6+112>
0x00005555555555b9 <+123>: mov %rdx,0x20(%rsp,%rsi,8)
0x00005555555555be <+128>: add [=10=]x1,%rsi
0x00005555555555c2 <+132>: cmp [=10=]x6,%rsi
0x00005555555555c6 <+136>: je 0x5555555555e5 <phase_6+167>
0x00005555555555c8 <+138>: mov (%rsp,%rsi,4),%ecx
0x00005555555555cb <+141>: mov [=10=]x1,%eax
0x00005555555555d0 <+146>: lea 0x202c39(%rip),%rdx # 0x555555758210 <node1>
0x00005555555555d7 <+153>: cmp [=10=]x1,%ecx
0x00005555555555da <+156>: jg 0x5555555555ae <phase_6+112>
0x00005555555555dc <+158>: jmp 0x5555555555b9 <phase_6+123>
0x00005555555555de <+160>: mov [=10=]x0,%esi
0x00005555555555e3 <+165>: jmp 0x5555555555c8 <phase_6+138>
0x00005555555555e5 <+167>: mov 0x20(%rsp),%rbx
0x00005555555555ea <+172>: mov 0x28(%rsp),%rax
0x00005555555555ef <+177>: mov %rax,0x8(%rbx)
0x00005555555555f3 <+181>: mov 0x30(%rsp),%rdx
0x00005555555555f8 <+186>: mov %rdx,0x8(%rax)
0x00005555555555fc <+190>: mov 0x38(%rsp),%rax
0x0000555555555601 <+195>: mov %rax,0x8(%rdx)
0x0000555555555605 <+199>: mov 0x40(%rsp),%rdx
0x000055555555560a <+204>: mov %rdx,0x8(%rax)
0x000055555555560e <+208>: mov 0x48(%rsp),%rax
0x0000555555555613 <+213>: mov %rax,0x8(%rdx)
0x0000555555555617 <+217>: movq [=10=]x0,0x8(%rax)
0x000055555555561f <+225>: mov [=10=]x5,%ebp
0x0000555555555624 <+230>: jmp 0x55555555562f <phase_6+241>
0x0000555555555626 <+232>: mov 0x8(%rbx),%rbx
0x000055555555562a <+236>: sub [=10=]x1,%ebp
0x000055555555562d <+239>: je 0x555555555640 <phase_6+258>
0x000055555555562f <+241>: mov 0x8(%rbx),%rax
0x0000555555555633 <+245>: mov (%rax),%eax
0x0000555555555635 <+247>: cmp %eax,(%rbx)
0x0000555555555637 <+249>: jle 0x555555555626 <phase_6+232>
0x0000555555555639 <+251>: callq 0x5555555558a2 <explode_bomb>
0x000055555555563e <+256>: jmp 0x555555555626 <phase_6+232>
0x0000555555555640 <+258>: mov 0x58(%rsp),%rax
0x0000555555555645 <+263>: xor %fs:0x28,%rax
0x000055555555564e <+272>: jne 0x55555555565b <phase_6+285>
0x0000555555555650 <+274>: add [=10=]x68,%rsp
0x0000555555555654 <+278>: pop %rbx
0x0000555555555655 <+279>: pop %rbp
0x0000555555555656 <+280>: pop %r12
0x0000555555555658 <+282>: pop %r13
0x000055555555565a <+284>: retq
0x000055555555565b <+285>: callq 0x555555554e50 <__stack_chk_fail@plt>
我已经工作了好几天了。我解决了 phase_1 ğhase_2、phase_3 等等,就是 phase_6。我知道答案应该是 1-6 之间的数字。但是我找不到答案。请帮我解决这个问题。
TL;DR - 将其转换为 C 语言,对其进行调试或优化直至可读。
如果你不喜欢 C,你可以把它转换成流程图,或者任何其他支持 goto 和灵活指针操作的语言。
转换为 C:
第一步是识别基本代码块;这是指令的运行,无需分支进出即可执行。我喜欢 C,所以我会将反汇编代码 c+p 到编辑器中,并查找每条跳转指令;喜欢 0x000055555555558a <+76>: jmp 0x555555555572 <phase_6+52>
。我会将其更改为:
0x000055555555558a <+76>: jmp 0x555555555572 <phase_6+52>
*/
goto L_572;
那我就找到对应的指令 0x0000555555555572 <+52>: add [=15=]x1,%ebx
改成:
L_572:
/*
0x0000555555555572 <+52>: add [=11=]x1,%ebx
一旦你完成了这个,加上为序言和结语添加了一些额外的东西,你应该有一个初步的近似它被分成块。
接下来,细化条件分支周围的区域——一般来说,如果它们向后跳转,它们就是循环;转发它们是 if 或循环测试。
现在开始将代码翻译成更容易理解的东西;像C。
从序言中找出局部变量是什么:
void f(long rdi) {
struct localvars {
union {
long l[13];
int w[26];
/* ... */
};
} sp; /* because the stack pointer points here... */
sp.l[10] = ((long *)tls())[5]; /* peculiar... */
/* create some fake C variables for some registers: */
long rax, rdx, rsi, rbp, r12, r13, ... ;
r12 = &sp;
/*
0x0000555555555544 <+6>: sub [=12=]x68,%rsp
0x0000555555555548 <+10>: mov %fs:0x28,%rax
0x0000555555555551 <+19>: mov %rax,0x58(%rsp)
0x0000555555555556 <+24>: xor %eax,%eax
0x0000555555555558 <+26>: mov %rsp,%r12
*/
在每个标签处,然后检查代码,并将其转换为伪高级语言。同样,插入等效的 C 代码:
read_six_numbers(rdi, r12);
r13 = 0;
goto L_590;
/*
0x000055555555555b <+29>: mov %r12,%rsi
0x000055555555555e <+32>: callq 0x5555555558c8 <read_six_numbers>
0x0000555555555563 <+37>: mov [=13=]x0,%r13d
0x0000555555555569 <+43>: jmp 0x555555555590 <phase_6+82>
*/
L_56b:
并继续此过程,直到将程序集转换为等效的 C 函数。此时,您应该能够将作业中的输入输入到 C 函数中,并观察它的行为与示例函数类似。
在不过早地优化或生成花哨的结构的情况下进行这一步很重要;一旦你有了一个有效的翻译,就有时间了。如果你做的东西没有用,你所做的就是做更多的工作!
一旦达到这一点,您可以优化程序直到它变得可读,或者在调试器中单步执行它以观察它的作用。
这是我的phase_6反汇编代码请帮我解决这个问题。我知道答案应该是1到6之间的数字。
0x000055555555553e <+0>: push %r13
0x0000555555555540 <+2>: push %r12
0x0000555555555542 <+4>: push %rbp
0x0000555555555543 <+5>: push %rbx
0x0000555555555544 <+6>: sub [=10=]x68,%rsp
0x0000555555555548 <+10>: mov %fs:0x28,%rax
0x0000555555555551 <+19>: mov %rax,0x58(%rsp)
0x0000555555555556 <+24>: xor %eax,%eax
0x0000555555555558 <+26>: mov %rsp,%r12
0x000055555555555b <+29>: mov %r12,%rsi
0x000055555555555e <+32>: callq 0x5555555558c8 <read_six_numbers>
0x0000555555555563 <+37>: mov [=10=]x0,%r13d
0x0000555555555569 <+43>: jmp 0x555555555590 <phase_6+82>
0x000055555555556b <+45>: callq 0x5555555558a2 <explode_bomb>
0x0000555555555570 <+50>: jmp 0x55555555559f <phase_6+97>
0x0000555555555572 <+52>: add [=10=]x1,%ebx
0x0000555555555575 <+55>: cmp [=10=]x5,%ebx
0x0000555555555578 <+58>: jg 0x55555555558c <phase_6+78>
0x000055555555557a <+60>: movslq %ebx,%rax
0x000055555555557d <+63>: mov (%rsp,%rax,4),%eax
0x0000555555555580 <+66>: cmp %eax,0x0(%rbp)
0x0000555555555583 <+69>: jne 0x555555555572 <phase_6+52>
0x0000555555555585 <+71>: callq 0x5555555558a2 <explode_bomb>
0x000055555555558a <+76>: jmp 0x555555555572 <phase_6+52>
0x000055555555558c <+78>: add [=10=]x4,%r12
0x0000555555555590 <+82>: mov %r12,%rbp
0x0000555555555593 <+85>: mov (%r12),%eax
--Type <RET> for more, q to quit, c to continue without paging--c
0x0000555555555597 <+89>: sub [=10=]x1,%eax
0x000055555555559a <+92>: cmp [=10=]x5,%eax
0x000055555555559d <+95>: ja 0x55555555556b <phase_6+45>
0x000055555555559f <+97>: add [=10=]x1,%r13d
0x00005555555555a3 <+101>: cmp [=10=]x6,%r13d
0x00005555555555a7 <+105>: je 0x5555555555de <phase_6+160>
0x00005555555555a9 <+107>: mov %r13d,%ebx
0x00005555555555ac <+110>: jmp 0x55555555557a <phase_6+60>
0x00005555555555ae <+112>: mov 0x8(%rdx),%rdx
0x00005555555555b2 <+116>: add [=10=]x1,%eax
0x00005555555555b5 <+119>: cmp %ecx,%eax
0x00005555555555b7 <+121>: jne 0x5555555555ae <phase_6+112>
0x00005555555555b9 <+123>: mov %rdx,0x20(%rsp,%rsi,8)
0x00005555555555be <+128>: add [=10=]x1,%rsi
0x00005555555555c2 <+132>: cmp [=10=]x6,%rsi
0x00005555555555c6 <+136>: je 0x5555555555e5 <phase_6+167>
0x00005555555555c8 <+138>: mov (%rsp,%rsi,4),%ecx
0x00005555555555cb <+141>: mov [=10=]x1,%eax
0x00005555555555d0 <+146>: lea 0x202c39(%rip),%rdx # 0x555555758210 <node1>
0x00005555555555d7 <+153>: cmp [=10=]x1,%ecx
0x00005555555555da <+156>: jg 0x5555555555ae <phase_6+112>
0x00005555555555dc <+158>: jmp 0x5555555555b9 <phase_6+123>
0x00005555555555de <+160>: mov [=10=]x0,%esi
0x00005555555555e3 <+165>: jmp 0x5555555555c8 <phase_6+138>
0x00005555555555e5 <+167>: mov 0x20(%rsp),%rbx
0x00005555555555ea <+172>: mov 0x28(%rsp),%rax
0x00005555555555ef <+177>: mov %rax,0x8(%rbx)
0x00005555555555f3 <+181>: mov 0x30(%rsp),%rdx
0x00005555555555f8 <+186>: mov %rdx,0x8(%rax)
0x00005555555555fc <+190>: mov 0x38(%rsp),%rax
0x0000555555555601 <+195>: mov %rax,0x8(%rdx)
0x0000555555555605 <+199>: mov 0x40(%rsp),%rdx
0x000055555555560a <+204>: mov %rdx,0x8(%rax)
0x000055555555560e <+208>: mov 0x48(%rsp),%rax
0x0000555555555613 <+213>: mov %rax,0x8(%rdx)
0x0000555555555617 <+217>: movq [=10=]x0,0x8(%rax)
0x000055555555561f <+225>: mov [=10=]x5,%ebp
0x0000555555555624 <+230>: jmp 0x55555555562f <phase_6+241>
0x0000555555555626 <+232>: mov 0x8(%rbx),%rbx
0x000055555555562a <+236>: sub [=10=]x1,%ebp
0x000055555555562d <+239>: je 0x555555555640 <phase_6+258>
0x000055555555562f <+241>: mov 0x8(%rbx),%rax
0x0000555555555633 <+245>: mov (%rax),%eax
0x0000555555555635 <+247>: cmp %eax,(%rbx)
0x0000555555555637 <+249>: jle 0x555555555626 <phase_6+232>
0x0000555555555639 <+251>: callq 0x5555555558a2 <explode_bomb>
0x000055555555563e <+256>: jmp 0x555555555626 <phase_6+232>
0x0000555555555640 <+258>: mov 0x58(%rsp),%rax
0x0000555555555645 <+263>: xor %fs:0x28,%rax
0x000055555555564e <+272>: jne 0x55555555565b <phase_6+285>
0x0000555555555650 <+274>: add [=10=]x68,%rsp
0x0000555555555654 <+278>: pop %rbx
0x0000555555555655 <+279>: pop %rbp
0x0000555555555656 <+280>: pop %r12
0x0000555555555658 <+282>: pop %r13
0x000055555555565a <+284>: retq
0x000055555555565b <+285>: callq 0x555555554e50 <__stack_chk_fail@plt>
我已经工作了好几天了。我解决了 phase_1 ğhase_2、phase_3 等等,就是 phase_6。我知道答案应该是 1-6 之间的数字。但是我找不到答案。请帮我解决这个问题。
TL;DR - 将其转换为 C 语言,对其进行调试或优化直至可读。 如果你不喜欢 C,你可以把它转换成流程图,或者任何其他支持 goto 和灵活指针操作的语言。
转换为 C:
第一步是识别基本代码块;这是指令的运行,无需分支进出即可执行。我喜欢 C,所以我会将反汇编代码 c+p 到编辑器中,并查找每条跳转指令;喜欢 0x000055555555558a <+76>: jmp 0x555555555572 <phase_6+52>
。我会将其更改为:
0x000055555555558a <+76>: jmp 0x555555555572 <phase_6+52>
*/
goto L_572;
那我就找到对应的指令 0x0000555555555572 <+52>: add [=15=]x1,%ebx
改成:
L_572:
/*
0x0000555555555572 <+52>: add [=11=]x1,%ebx
一旦你完成了这个,加上为序言和结语添加了一些额外的东西,你应该有一个初步的近似它被分成块。
接下来,细化条件分支周围的区域——一般来说,如果它们向后跳转,它们就是循环;转发它们是 if 或循环测试。
现在开始将代码翻译成更容易理解的东西;像C。 从序言中找出局部变量是什么:
void f(long rdi) {
struct localvars {
union {
long l[13];
int w[26];
/* ... */
};
} sp; /* because the stack pointer points here... */
sp.l[10] = ((long *)tls())[5]; /* peculiar... */
/* create some fake C variables for some registers: */
long rax, rdx, rsi, rbp, r12, r13, ... ;
r12 = &sp;
/*
0x0000555555555544 <+6>: sub [=12=]x68,%rsp
0x0000555555555548 <+10>: mov %fs:0x28,%rax
0x0000555555555551 <+19>: mov %rax,0x58(%rsp)
0x0000555555555556 <+24>: xor %eax,%eax
0x0000555555555558 <+26>: mov %rsp,%r12
*/
在每个标签处,然后检查代码,并将其转换为伪高级语言。同样,插入等效的 C 代码:
read_six_numbers(rdi, r12);
r13 = 0;
goto L_590;
/*
0x000055555555555b <+29>: mov %r12,%rsi
0x000055555555555e <+32>: callq 0x5555555558c8 <read_six_numbers>
0x0000555555555563 <+37>: mov [=13=]x0,%r13d
0x0000555555555569 <+43>: jmp 0x555555555590 <phase_6+82>
*/
L_56b:
并继续此过程,直到将程序集转换为等效的 C 函数。此时,您应该能够将作业中的输入输入到 C 函数中,并观察它的行为与示例函数类似。 在不过早地优化或生成花哨的结构的情况下进行这一步很重要;一旦你有了一个有效的翻译,就有时间了。如果你做的东西没有用,你所做的就是做更多的工作!
一旦达到这一点,您可以优化程序直到它变得可读,或者在调试器中单步执行它以观察它的作用。