• Status: Solved
• Priority: Medium
• Security: Public
• Views: 7313

# How to start solving phase 4 of binary bomb

Hi. I am a new member on experts-exchange and this is my very first post. So, please forgive me if I'm doing anything wrong. I am currently stuck on phase 4 of a binary bomb assignment. I'm having a hard time figuring out how many inputs are required, and what a good starting point would be to analyze this. I'm really confused as to what is happening in func4. In phase_4, I see that %eax is compared to 0x2. Does this mean that the first value of the input has to be 2? Any help on this will be greatly appreciated. I am using gdb to debug the code.
``````Dump of assembler code for function func4:
0x08048790 <func4+0>:   push   %ebp
0x08048791 <func4+1>:   mov    %esp,%ebp
0x08048793 <func4+3>:   sub    \$0x18,%esp
0x08048796 <func4+6>:   mov    %ebx,-0xc(%ebp)
0x08048799 <func4+9>:   mov    %esi,-0x8(%ebp)
0x0804879c <func4+12>:  mov    %edi,-0x4(%ebp)
0x0804879f <func4+15>:  mov    0x8(%ebp),%esi
0x080487a2 <func4+18>:  mov    0xc(%ebp),%ecx
0x080487a5 <func4+21>:  mov    0x10(%ebp),%edi
0x080487a8 <func4+24>:  mov    %edi,%edx
0x080487aa <func4+26>:  sub    %ecx,%edx
0x080487ac <func4+28>:  mov    %edx,%eax
0x080487ae <func4+30>:  shr    \$0x1f,%eax
0x080487b1 <func4+33>:  add    %edx,%eax
0x080487b3 <func4+35>:  sar    %eax
0x080487b5 <func4+37>:  lea    (%eax,%ecx,1),%ebx
0x080487b8 <func4+40>:  cmp    %esi,%ebx
0x080487ba <func4+42>:  jle    0x80487d3 <func4+67>
0x080487bc <func4+44>:  lea    -0x1(%ebx),%eax
0x080487bf <func4+47>:  mov    %eax,0x8(%esp)
0x080487c3 <func4+51>:  mov    %ecx,0x4(%esp)
0x080487c7 <func4+55>:  mov    %esi,(%esp)
0x080487ca <func4+58>:  call   0x8048790 <func4>
0x080487cf <func4+63>:  add    %eax,%ebx
0x080487d1 <func4+65>:  jmp    0x80487ec <func4+92>
0x080487d3 <func4+67>:  cmp    %esi,%ebx
0x080487d5 <func4+69>:  jge    0x80487ec <func4+92>
0x080487d7 <func4+71>:  mov    %edi,0x8(%esp)
0x080487db <func4+75>:  lea    0x1(%ebx),%eax
0x080487de <func4+78>:  mov    %eax,0x4(%esp)
0x080487e2 <func4+82>:  mov    %esi,(%esp)
0x080487e5 <func4+85>:  call   0x8048790 <func4>
0x080487ea <func4+90>:  add    %eax,%ebx
0x080487ec <func4+92>:  mov    %ebx,%eax
0x080487ee <func4+94>:  mov    -0xc(%ebp),%ebx
0x080487f1 <func4+97>:  mov    -0x8(%ebp),%esi
0x080487f4 <func4+100>: mov    -0x4(%ebp),%edi
0x080487f7 <func4+103>: mov    %ebp,%esp
0x080487f9 <func4+105>: pop    %ebp
0x080487fa <func4+106>: ret
End of assembler dump.
``````
``````Dump of assembler code for function phase_4:
0x08048a81 <phase_4+0>: push   %ebp
0x08048a82 <phase_4+1>: mov    %esp,%ebp
0x08048a84 <phase_4+3>: sub    \$0x28,%esp
0x08048a87 <phase_4+6>: lea    -0x8(%ebp),%eax
0x08048a8a <phase_4+9>: mov    %eax,0xc(%esp)
0x08048a8e <phase_4+13>:        lea    -0x4(%ebp),%eax
0x08048a91 <phase_4+16>:        mov    %eax,0x8(%esp)
0x08048a95 <phase_4+20>:        movl   \$0x804920c,0x4(%esp)
0x08048a9d <phase_4+28>:        mov    0x8(%ebp),%eax
0x08048aa0 <phase_4+31>:        mov    %eax,(%esp)
0x08048aa3 <phase_4+34>:        call   0x8048530 <sscanf@plt>
0x08048aa8 <phase_4+39>:        cmp    \$0x2,%eax
0x08048aab <phase_4+42>:        jne    0x8048ab9 <phase_4+56>
0x08048aad <phase_4+44>:        mov    -0x4(%ebp),%eax
0x08048ab0 <phase_4+47>:        test   %eax,%eax
0x08048ab2 <phase_4+49>:        js     0x8048ab9 <phase_4+56>
0x08048ab4 <phase_4+51>:        cmp    \$0xe,%eax
0x08048ab7 <phase_4+54>:        jle    0x8048abe <phase_4+61>
0x08048ab9 <phase_4+56>:        call   0x8048c98 <explode_bomb>
0x08048abe <phase_4+61>:        movl   \$0xe,0x8(%esp)
0x08048ac6 <phase_4+69>:        movl   \$0x0,0x4(%esp)
0x08048ace <phase_4+77>:        mov    -0x4(%ebp),%eax
0x08048ad1 <phase_4+80>:        mov    %eax,(%esp)
0x08048ad4 <phase_4+83>:        call   0x8048790 <func4>
0x08048ad9 <phase_4+88>:        cmp    \$0x25,%eax
0x08048adc <phase_4+91>:        jne    0x8048ae4 <phase_4+99>
0x08048ade <phase_4+93>:        cmpl   \$0x25,-0x8(%ebp)
0x08048ae2 <phase_4+97>:        je     0x8048ae9 <phase_4+104>
0x08048ae4 <phase_4+99>:        call   0x8048c98 <explode_bomb>
0x08048ae9 <phase_4+104>:       leave
0x08048aea <phase_4+105>:       ret
End of assembler dump.
``````
2
jakepillai
• 6
• 5
3 Solutions

Commented:
>> I'm having a hard time figuring out how many inputs are required, and what a good starting point would be to analyze this.

It's a good idea to comment every instruction, explaining in your own words (or pseudo code) what that instruction does. That'll provide you with a higher-level overview of what's going on.

If you give that a try, and post here how far you get with that, we can work from there.

>> In phase_4, I see that %eax is compared to 0x2. Does this mean that the first value of the input has to be 2?

eax holds the return value of the function that was just called. Comparing eax with 2, means checking whether the function returned 2 or not.
0

Author Commented:
Thank you for the quick response, I have commented phase_4 and func4 and attached it below. Is the function sscanf returning the number of inputs provided? If yes, is it safe to conclude that this phase is looking for two inputs from the user?
``````Dump of assembler code for function func4:
0x08048790 <func4+0>:   push   %ebp
0x08048791 <func4+1>:   mov    %esp,%ebp
0x08048793 <func4+3>:   sub    \$0x18,%esp			//set the stack pointer to esp-0x18
0x08048796 <func4+6>:   mov    %ebx,-0xc(%ebp)		//save ebx to the stack
0x08048799 <func4+9>:   mov    %esi,-0x8(%ebp)		//save esi to the stack
0x0804879c <func4+12>:  mov    %edi,-0x4(%ebp)		//save edi to the stack
0x0804879f <func4+15>:  mov    0x8(%ebp),%esi		//esi = Mem[R[ebp]+0x8]
0x080487a2 <func4+18>:  mov    0xc(%ebp),%ecx       //ecx = Mem[R[ebp]+0xc]
0x080487a5 <func4+21>:  mov    0x10(%ebp),%edi		//edi = Mem[R[ebp]+0xc]. This seems to be the value 14 all the time
0x080487a8 <func4+24>:  mov    %edi,%edx			//esi = edx
0x080487aa <func4+26>:  sub    %ecx,%edx			//edx = edx - ecx
0x080487ac <func4+28>:  mov    %edx,%eax			//eax = edx
0x080487ae <func4+30>:  shr    \$0x1f,%eax			//eax = contents of eax shifted right 31 times
0x080487b1 <func4+33>:  add    %edx,%eax			//eax = eax+edx
0x080487b3 <func4+35>:  sar    %eax					//eax = eax/2
0x080487b5 <func4+37>:  lea    (%eax,%ecx,1),%ebx   //ebx = eax+(1*ecx)
0x080487b8 <func4+40>:  cmp    %esi,%ebx            //check if ebx < esi
0x080487ba <func4+42>:  jle    0x80487d3 <func4+67> //if yes...jump to this loaction
0x080487bc <func4+44>:  lea    -0x1(%ebx),%eax		//eax = ebx-1
0x080487bf <func4+47>:  mov    %eax,0x8(%esp)		//move eax to the stack
0x080487c3 <func4+51>:  mov    %ecx,0x4(%esp)		//move ecx to the stack
0x080487c7 <func4+55>:  mov    %esi,(%esp)			//move esi to the stack
0x080487ca <func4+58>:  call   0x8048790 <func4>	//go back to the beginning of the function
0x080487cf <func4+63>:  add    %eax,%ebx			//ebx = eax + ebx
0x080487d1 <func4+65>:  jmp    0x80487ec <func4+92> //jump to this location
0x080487d3 <func4+67>:  cmp    %esi,%ebx			//compare contents of ebx to contents of esi
0x080487d5 <func4+69>:  jge    0x80487ec <func4+92>	//if ebx >= esi, jump to the address specified
0x080487d7 <func4+71>:  mov    %edi,0x8(%esp)		//save contents of edi on to stack
0x080487db <func4+75>:  lea    0x1(%ebx),%eax		//eax =  ebx+1
0x080487de <func4+78>:  mov    %eax,0x4(%esp)		//save eax to the stack
0x080487e2 <func4+82>:  mov    %esi,(%esp)			//save esi onto the topmost address of the stack so it will be the first to be popped
0x080487e5 <func4+85>:  call   0x8048790 <func4>    //go back to the beginning of the function
0x080487ea <func4+90>:  add    %eax,%ebx			//ebx = eax + ebx
0x080487ec <func4+92>:  mov    %ebx,%eax			//eax =  ebx. eax contains the return value from this function
0x080487ee <func4+94>:  mov    -0xc(%ebp),%ebx		//remaining lines restores the stack and returns back to phase_4 procedure
0x080487f1 <func4+97>:  mov    -0x8(%ebp),%esi
0x080487f4 <func4+100>: mov    -0x4(%ebp),%edi
0x080487f7 <func4+103>: mov    %ebp,%esp
0x080487f9 <func4+105>: pop    %ebp
0x080487fa <func4+106>: ret
``````
``````Dump of assembler code for function phase_4:
0x08048a81 <phase_4+0>: push   %ebp
0x08048a82 <phase_4+1>: mov    %esp,%ebp
0x08048a84 <phase_4+3>: sub    \$0x28,%esp						//set the stack pointer
0x08048a87 <phase_4+6>: lea    -0x8(%ebp),%eax					//eax = ebp - 8
0x08048a8a <phase_4+9>: mov    %eax,0xc(%esp)					//Mem[R[esp]+0xc] = eax = ebp-8
0x08048a8e <phase_4+13>:        lea    -0x4(%ebp),%eax			//eax = ebp - 4
0x08048a91 <phase_4+16>:        mov    %eax,0x8(%esp)      		//Mem[R[esp]+0x8] = eax = ebp -4
0x08048a95 <phase_4+20>:        movl   \$0x804920c,0x4(%esp)		//Mem[R[esp]+0x4] = 0x804920c
0x08048a9d <phase_4+28>:        mov    0x8(%ebp),%eax			//eax = Mem[R[ebp]+0x8]
0x08048aa0 <phase_4+31>:        mov    %eax,(%esp)				//move eax on to the stack
0x08048aa3 <phase_4+34>:        call   0x8048530 <sscanf@plt>	//call sscanf function
0x08048aa8 <phase_4+39>:        cmp    \$0x2,%eax				//check to see if the return value from sscanf is 2
0x08048aab <phase_4+42>:        jne    0x8048ab9 <phase_4+56>	//explode bomb if the return value from sscan is not 2
0x08048aad <phase_4+44>:        mov    -0x4(%ebp),%eax			//eax = Mem[R[ebp]-0x4]
0x08048ab0 <phase_4+47>:        test   %eax,%eax				//performs bitwise AND of eax with eax
0x08048ab2 <phase_4+49>:        js     0x8048ab9 <phase_4+56>	//if the result is negative, explode the bomb
0x08048ab4 <phase_4+51>:        cmp    \$0xe,%eax				//else, compare the value of eax with 14
0x08048ab7 <phase_4+54>:        jle    0x8048abe <phase_4+61>	//continue without exploding the bomb if eax <= 14
0x08048ab9 <phase_4+56>:        call   0x8048c98 <explode_bomb>
0x08048abe <phase_4+61>:        movl   \$0xe,0x8(%esp)			//move the value 14 into Mem[R[esp]+8]
0x08048ac6 <phase_4+69>:        movl   \$0x0,0x4(%esp)			//move the value 0 into Mem[R[esp]+0x4]
0x08048ace <phase_4+77>:        mov    -0x4(%ebp),%eax			//eax = Mem[R[ebp]-0x4]
0x08048ad1 <phase_4+80>:        mov    %eax,(%esp)				//move eax into the stack
0x08048ad4 <phase_4+83>:        call   0x8048790 <func4>        //procedure call to func4
0x08048ad9 <phase_4+88>:        cmp    \$0x25,%eax               //check if return value from func4 is 0x25 or decimal 37
0x08048adc <phase_4+91>:        jne    0x8048ae4 <phase_4+99>   //if not, explode bomb
0x08048ade <phase_4+93>:        cmpl   \$0x25,-0x8(%ebp)			//if yes, compare the value in Mem[R[ebp]-0x8] to 0x25
0x08048ae2 <phase_4+97>:        je     0x8048ae9 <phase_4+104>  //if the values are equal,phase_4 is completed successfully
0x08048ae4 <phase_4+99>:        call   0x8048c98 <explode_bomb> //if not, explode the bomb
0x08048ae9 <phase_4+104>:       leave
0x08048aea <phase_4+105>:       ret
End of assembler dump.
``````
0

Author Commented:
i apologize for the formatting of the code above. It seemed fine in notepad before i attached it here.
0

Commented:
>> Is the function sscanf returning the number of inputs provided?

It is returning the number of tokens (corresponding to a format specifier) it succesfully read from the string.

>> If yes, is it safe to conclude that this phase is looking for two inputs from the user?

Yes.

>> 0x08048a87 <phase_4+6>: lea    -0x8(%ebp),%eax                              //eax = ebp - 8
>> 0x08048a8a <phase_4+9>: mov    %eax,0xc(%esp)                              //Mem[R[esp]+0xc] = eax = ebp-8
>> 0x08048a8e <phase_4+13>:        lea    -0x4(%ebp),%eax                  //eax = ebp - 4
>> 0x08048a91 <phase_4+16>:        mov    %eax,0x8(%esp)                  //Mem[R[esp]+0x8] = eax = ebp -4
>> 0x08048a95 <phase_4+20>:        movl   \$0x804920c,0x4(%esp)            //Mem[R[esp]+0x4] = 0x804920c
>> 0x08048a9d <phase_4+28>:        mov    0x8(%ebp),%eax                  //eax = Mem[R[ebp]+0x8]
>> 0x08048aa0 <phase_4+31>:        mov    %eax,(%esp)                        //move eax on to the stack

That's an accurate low-level description of what the instructions do. In more high-level terms, what these instructions do, is place the 4 arguments for the sscanf function call on the stack. After placing the 4 arguments on the stack, the function can be called :

>> 0x08048aa3 <phase_4+34>:        call   0x8048530 <sscanf@plt>      //call sscanf function

and it's expected to get two tokens from the string, and place them in the memory locations provided as arguments to the sscanf function.

If not, the bomb explodes :

>> 0x08048aa8 <phase_4+39>:        cmp    \$0x2,%eax                        //check to see if the return value from sscanf is 2
>> 0x08048aab <phase_4+42>:        jne    0x8048ab9 <phase_4+56>      //explode bomb if the return value from sscan is not 2

Can you continue from there, and add more high-level comments like I just did ? That's the second stage in analyzing assembly code. Whenever you're not sure about how to interpret something, just ask :)
0

Commented:
Oh, and do you know in which memory locations the two tokens are placed by sscanf ? And do you know what their type is ?
0

Commented:
Yes, that's what sscanf returns.  It's checking for two inputs from whatever is passed to phase_4.
0

Author Commented:
Thank you for the quick and very helpful response. Now, I have good idea on how to start analyzing it. I'll pick up from this point and see if I can decipher the rest of the phase. I'll make a post once I solve it and thank you for the help.
0

Commented:
>> I'll make a post once I solve it and thank you for the help.

Feel free to ask whenever you have a question or encounter a road block :)
0

Author Commented:
I assumed that the two tokens had to be numbers because of a debugger gui that i was using. I'm not sure exactly which location sscanf will store the two tokens to. Is it to the location specified in <phase_4+20> ?
0

Commented:
>> I assumed that the two tokens had to be numbers because of a debugger gui that i was using.

You can find out by checking the format string at memory location \$0x804920c. If you need to find out how to interpret the format string, please refer to this sscanf reference page :

http://www.cplusplus.com/reference/clibrary/cstdio/sscanf/

>> I'm not sure exactly which location sscanf will store the two tokens to.

The first parameter to sscanf is the string from which to read.
The second parameter is the format string.
All subsequent parameters are the addresses of where the read tokens need to be stored.

When reading assembly code, the first function parameter is placed at the top of the stack, the second parameter just below it, etc. (keep in mind that the stack grows downward - towards lower memory addresses).
0

Author Commented:
Thank you very much for all the help. I got the phase to work. func4 defined the range for the first value and the second one was fixed at 37. Again, I really appreciate the help.
0

Commented:
No problem. Glad I could be of assistance.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

## Featured Post

• 6
• 5
Tackle projects and never again get stuck behind a technical roadblock.