I am currently working on defusing a binary bomb and am stuck on phase 5. As far as I could figure out, there is a loop and the index (%edx) needs to be 15 to get through the loop. However, I am stuck at the array which always returns 15 after 6 cycles, therefore leaving the first loop and comparing %edx which only gets to 6, comparing this to 15 and therefore failing.
How do i calculate the value that is needed in order for the cycle to be done 15 times? The array is: 10, 2, 14, 7, 8, 12, 15, 11, 0, 4, 1, 13, 3, 9, 6, 5
0000000000401061 <phase_5>:
401061: 53 push %rbx
401062: 48 83 ec 10 sub $0x10,%rsp
401066: 48 89 fb mov %rdi,%rbx
401069: e8 53 12 00 00 call 4022c1 <phase_init>
40106e: 48 8d 4c 24 08 lea 0x8(%rsp),%rcx
401073: 48 8d 54 24 0c lea 0xc(%rsp),%rdx
401078: be 90 28 40 00 mov $0x402890,%esi
40107d: 48 89 df mov %rbx,%rdi
401080: b8 00 00 00 00 mov $0x0,%eax
401085: e8 36 fa ff ff call 400ac0 <__isoc99_sscanf@plt>
40108a: 83 f8 01 cmp $0x1,%eax
40108d: 7f 05 jg 401094 <phase_5+0x33>
40108f: e8 98 04 00 00 call 40152c <explode_bomb>
401094: 8b 44 24 0c mov 0xc(%rsp),%eax
401098: 83 e0 0f and $0xf,%eax
40109b: 89 44 24 0c mov %eax,0xc(%rsp)
40109f: 83 f8 0f cmp $0xf,%eax
4010a2: 74 30 je 4010d4 <phase_5+0x73>
4010a4: b9 64 00 00 00 mov $0x64,%ecx
4010a9: ba 00 00 00 00 mov $0x0,%edx
4010ae: 83 c2 01 add $0x1,%edx
4010b1: 48 98 cltq
4010b3: 8b 04 85 80 26 40 00 mov 0x402680(,%rax,4),%eax
4010ba: 29 c1 sub %eax,%ecx
4010bc: 83 f8 0f cmp $0xf,%eax
4010bf: 75 ed jne 4010ae <phase_5+0x4d>
4010c1: c7 44 24 0c 0f 00 00 movl $0xf,0xc(%rsp)
4010c8: 00
4010c9: 83 fa 0f cmp $0xf,%edx
4010cc: 75 06 jne 4010d4 <phase_5+0x73>
4010ce: 3b 4c 24 08 cmp 0x8(%rsp),%ecx
4010d2: 74 05 je 4010d9 <phase_5+0x78>
4010d4: e8 53 04 00 00 call 40152c <explode_bomb>
4010d9: 48 83 c4 10 add $0x10,%rsp
4010dd: 5b pop %rbx
4010de: c3 ret
I am sorry if the question seems stupid, but i only recently got into reverse engineering and am quite new to the whole topic. Thank you!
I tried to start behind the array position which would be 15, so I inputted 7 which allowed me to get 12 cycles. I also tried to use the position of 0 in the array which would be 8 (32/4), but without luck.
Full reverse engineering works bottom up.
You start by finding out what each group of instructions does and then you link the reversed operations together.
If the code is short, you can do it all in your head. If the code is not short, it's necessary to annotate the assembly listing.
This is the part that may require being used to compilers' output, in this case, however, I didn't find anything unusual so I'll just present the annotated assembly without further explanations:
The introduction of the variable
nis maybe the only "trick" here. Such a variable is necessary since the compiler reads and writeseaxin the loop body and in the first iterationeaxcontains the value ofvar1.With these comments, it's easy to write an equivalent C program.
Note how similar the generated assembly and the original assembly listing are.
So, two numbers are read. The first is a start index and the second is an integer that we'll call
diff. Basically, we have an array that is a permutation of[0..15]and given the start index the program cycles through this permutation until it found the index 15. Meanwhile it:k(of initial value 100).Finally, if the iteration count is 15 and
kisdiff, the bomb does not explode.How do we find a starting index that cycles 15 times?
Well, we could simply bruteforce it but here's an algorithmic way.
Start from any index i and cycle until you reach 15. Then cycle back until you reach the number at index 15.
So, the array is:
Let's arbitrarily start from index
1, we get the sequence1 2 14 6 15. Now going backward (which index has value 1?) we can add10to the left of 1, then again (which index has value 10) we can add0to the left of 10. The full sequence is5 12 3 7 11 13 9 4 8 0 10 1 2 14 6 15.You should now be able to find the start index and hence the first number to input.
The second number to input is easy to find.