I'm working on a binary bomb lab and need help understanding how func4 works in phase_4. I understand we can't just check comparison values - we need to grasp how the recursion builds the return value.
Here's what I know:
- Phase_4 takes 2 inputs
- First input must be ≤ 14 (0xe)
- Second input must be 3
- func4 must return eax = 3 for the phase to pass
Here's the assembly:
func4:
endbr64
sub $0x8,%rsp
mov %edx,%ecx
sub %esi,%ecx
shr %ecx
add %esi,%ecx
cmp %edi,%ecx
ja 0x5555555556f9 <func4+32>
mov $0x0,%eax
jb 0x555555555705 <func4+44>
add $0x8,%rsp
ret
lea -0x1(%rcx),%edx
call 0x5555555556d9 <func4>
add %eax,%eax
jmp 0x5555555556f4 <func4+27>
lea 0x1(%rcx),%esi
call 0x5555555556d9 <func4>
lea 0x1(%rax,%rax,1),%eax
jmp 0x5555555556f4 <func4+27>
Dump of assembler code for function phase_4:
=> 0x0000555555555713 <+0>: sub $0x18,%rsp
0x0000555555555717 <+4>: lea 0x8(%rsp),%rcx
0x0000555555555720 <+13>: lea 0xc(%rsp),%rdx
0x0000555555555725 <+18>: lea 0x1c7a(%rip),%rsi # 0x5555555573a6
0x000055555555572c <+25>: mov $0x0,%eax
0x0000555555555731 <+30>: call 0x5555555552e0 <__isoc99_sscanf@plt>
0x0000555555555736 <+35>: cmp $0x2,%eax
0x0000555555555739 <+38>: jne 0x555555555742 <phase_4+47>
0x000055555555573b <+40>: cmpl $0xe,0xc(%rsp)
0x0000555555555740 <+45>: jbe 0x555555555747 <phase_4+52>
0x0000555555555742 <+47>: call 0x555555555c42 <explode_bomb>
0x0000555555555747 <+52>: mov $0xe,%edx
0x000055555555574c <+57>: mov $0x0,%esi
0x0000555555555751 <+62>: mov 0xc(%rsp),%edi
0x0000555555555755 <+66>: call 0x5555555556d9 <func4>
0x000055555555575a <+71>: cmp $0x3,%eax
0x000055555555575d <+74>: jne 0x555555555766 <phase_4+83>
0x000055555555575f <+76>: cmpl $0x3,0x8(%rsp)
0x0000555555555764 <+81>: je 0x55555555576b <phase_4+88>
0x0000555555555766 <+83>: call 0x555555555c42 <explode_bomb>
0x000055555555576b <+88>: add $0x18,%rsp
0x000055555555576f <+92>: ret
What I've figured out:
- It's doing a binary search-style recursion
- Above branch doubles eax (add %eax,%eax)
- Below branch doubles eax and adds 1 (lea 0x1(%rax,%rax,1),%eax)
- Base case returns 0
I'm trying to understand:
- How do the recursive calls build up eax to get 3?
- What input value would force the right sequence of above/below branches?
I've been tracing through GDB but could use help understanding the path needed to build eax = 3 through the recursive returns.
Thanks in advance!