Link to home
Start Free TrialLog in
Avatar of rawdog21
rawdog21

asked on

Binary Bomb Phase One

I am working on the cvlassic binary bomb assignment, and I am having a little bit of difficulty on the first phase.

I have a pretty good understanding of what each individual line of code represents and does, but the logic flow is confusing, and I don't know how to paste the lines together to figure out the correct password

My code is:

8048d8f <phase_1>:
8048d8f: 55                                        push   %ebp
8048d90: 89 e5                                  mov     %esp,%ebp
8048d92: 83 ec 08                             sub      $0x8,%esp
8048d95: c7 44 24 04 0e 97 04         mov1   $0x804970e,0x4(%esp)
8048d9c: 08                                    
8048d9d: 8b 45 08                             mov     0x8(%ebp),%eax
8048da0: 89 04 24                             mov    %eax,(%esp)
8048da3: e8 88 00 00 00                   call      8048e30 <strings_not_equal>
8048da8: 85 c0                                  test     %eax,%eax
8048daa: 74 05                                  je         8048db1 <phase_1+0x22>
8048dac: e8 5b 01 00 00                   call      8048f0c <explode_bomb>
8048db1: c9                                       leave
8048db2: c3                                       ret
Avatar of Infinity08
Infinity08
Flag of Belgium image

The important part is this :

8048da8: 85 c0                                  test     %eax,%eax
8048daa: 74 05                                  je         8048db1 <phase_1+0x22>

You want this jump to be taken, because otherwise the bomb would explode. So, you want %eax to be 0.

%eax is what's returned by the strings_not_equal function.
Avatar of rawdog21
rawdog21

ASKER

ok, that's what I thought. I knew it had something to do with strings_not_equal. My real problem is being able to translate that into what i need to input to get the bomb to not explode. I'm just not seeing how I know what string to enter, since it looks like the strings just need to not ne the same, and they will meet the strings_not_equal condition
>> I'm just not seeing how I know what string to enter,

Take a closer look at which two strings are compared. One of them is fixed, the other is entered by the user. So, you have control over only one of them.

Also analyze how strings_not_equal works, and what it returns under which conditions.
here is the strings_not_equal code. I am having a little more trouble figuring out what all of this code does than i did figuring out what phase one does



 08048e30 <strings_not_equal>:
 8048e30:       55                      push   %ebp
 8048e31:       89 e5                   mov    %esp,%ebp
 8048e33:       57                      push   %edi
 8048e34:       56                      push   %esi
 8048e35:       53                      push   %ebx
 8048e36:       83 ec 04                sub    $0x4,%esp
 8048e39:       8b 75 08                mov    0x8(%ebp),%esi
 8048e3c:       8b 7d 0c                mov    0xc(%ebp),%edi
 8048e3f:       89 34 24                mov    %esi,(%esp)
 8048e42:       e8 c9 ff ff ff          call   8048e10 <string_length>
 8048e47:       89 c3                   mov    %eax,%ebx
 8048e49:       89 3c 24                mov    %edi,(%esp)
 8048e4c:       e8 bf ff ff ff          call   8048e10 <string_length>
 8048e51:       39 c3                   cmp    %eax,%ebx
 8048e53:       75 29                   jne    8048e7e <strings_not_equal+0x4e>
 8048e55:       0f b6 06                movzbl (%esi),%eax
 8048e58:       84 c0                   test   %al,%al
 8048e5a:       74 29                   je     8048e85 <strings_not_equal+0x55>
 8048e5c:       89 f1                   mov    %esi,%ecx
 8048e5e:       89 fa                   mov    %edi,%edx
 8048e60:       3a 07                   cmp    (%edi),%al
 8048e62:       74 10                   je     8048e74 <strings_not_equal+0x44>
 8048e64:       eb 18                   jmp    8048e7e <strings_not_equal+0x4e>
 8048e66:       0f b6 42 01             movzbl 0x1(%edx),%eax
 8048e6a:       83 c1 01                add    $0x1,%ecx
 8048e6d:       83 c2 01                add    $0x1,%edx
 8048e70:       38 c3                   cmp    %al,%bl
 8048e72:       75 0a                   jne    8048e7e <strings_not_equal+0x4e>
 8048e74:       0f b6 59 01             movzbl 0x1(%ecx),%ebx
 8048e78:       84 db                   test   %bl,%bl
 8048e7a:       75 ea                   jne    8048e66 <strings_not_equal+0x36>
 8048e7c:       eb 07                   jmp    8048e85 <strings_not_equal+0x55>
 8048e7e:       b8 01 00 00 00          mov    $0x1,%eax
 8048e83:       eb 05                   jmp    8048e8a <strings_not_equal+0x5a>
 8048e85:       b8 00 00 00 00          mov    $0x0,%eax
 8048e8a:       83 c4 04                add    $0x4,%esp
 8048e8d:       5b                      pop    %ebx
 8048e8e:       5e                      pop    %esi
 8048e8f:       5f                      pop    %edi
 8048e90:       5d                      pop    %ebp
 8048e91:       c3                      ret
The function name is well chosen, so you can take that as a big hint.

The return value is either :

 8048e7e:       b8 01 00 00 00          mov    $0x1,%eax

or :

 8048e85:       b8 00 00 00 00          mov    $0x0,%eax

When does it return which value ?


I'm just giving hints ;)
8048e7e is invoked when %bl and %al are not equal.

 

8048e78:       84 db                   test   %bl,%bl

i dont know what test means, but it looks like it is comparing %bl with itself or something? well, if it passes this test, it jumps to 8048e85
'test' takes a bitwise AND of the two arguments. The zero flag is set if the result of that bitwise AND is 0.
but if you're bitwise ANDing a number with itself, like %bl and %bl won't the AND equal the number? since every bit is the same for the two numbers
>> won't the AND equal the number?

Precisely.

But note the second phrase in my previous post.
does that mean %bl needs to be zero in order for the AND to be zero and the zero flag to be set?
>> does that mean %bl needs to be zero in order for the AND to be zero and the zero flag to be set?

If you want the zero flag to be set, yes :)
dont i want strings_not_equal to return a 0? because right after the call to it in phase_1, there is the line:

8048da8: 85 c0                                  test     %eax,%eax

which is testing if eax is zero. strings_not_equal dumps the result into eax, so in order for test %eax, %eax to pass, the value from strings_not_equal has to be zero, so we want %bl to be zero as well.
>> dont i want strings_not_equal to return a 0?

I didn't mean to imply anything ;) I was only stating a fact.


>> so in order for test %eax, %eax to pass, the value from strings_not_equal has to be zero, so we want %bl to be zero as well.

Sounds right.
ok, i know what i need my results to be, but i still don't know what to input to get these. i reread the phase_1 function and i can't even tell how many numbers i need to input
Well, as I said earlier : there are two strings : one is fixed, and one is entered by the user. Just take a look at the fixed string, and you know what it contains.
8048d92: 83 ec 08                             sub      $0x8,%esp

%esp = %esp - 8

8048d95: c7 44 24 04 0e 97 04         movl   $0x804970e,0x4(%esp)

(%esp)+4 = 134518542
is this the fixed number? if so, the next two lines are applied to it.

8048d9d: 8b 45 08                             mov     0x8(%ebp),%eax

%eax = (%ebp)+8

8048da0: 89 04 24                             mov    %eax,(%esp)

(%esp) = %eax


does all of this look valid? and is the number above the correct fixed number, or am i looking at the wrong thing?
>> (%esp)+4 = 134518542
>> is this the fixed number? if so, the next two lines are applied to it.

0x804970e is a memory address. At that address, you'll find the second string.

Note that 0x4(%esp) stands for (*esp + 4) where * means a dereference operation, ie. get the value stored in the esp register.

So, the movl instruction stores the 0x804970e memory address at one place below the top of the stack.
"So, the movl instruction stores the 0x804970e memory address at one place below the top of the stack."


there is a $ in front of the 0x804970e, so it is the number, not the memory location. my code does not go as far as 804970e, it stops about 8049500
>> there is a $ in front of the 0x804970e, so it is the number, not the memory location.

It is a literal value that happens to be a memory address (trust me ;) ). The literal value is stored on the stack (as I said earlier) - in that way it's passed as the second argument for the strings_not_equal function. Remember that that function takes two parameters of type string, or ... more accurately, it takes as parameter two memory addresses where the strings can be found.


>> my code does not go as far as 804970e, it stops about 8049500

It's a memory address in the data part of memory, you won't find it in the code. You'll need to use a debugger to find out what the memory contains at that address.
ok, i ran the debugger and found the number at that memory location to be 1818391888.
i dont understand what to do with this number. this is frustrating beyond belief.
>> i ran the debugger and found the number at that memory location to be 1818391888.

You shouldn't be looking for a number, but for a string. Interpret the contents at that memory address as a string, and see what that gives you.

Note that the number you found is 6C627550 in hexadecimal, which corresponds to the 4 ASCII characters "Publ". That's the start of the string, but there's more ...
i ran thre debugger, and that is what it found when i asked it what the value was at 0x804970e
apparently i don't understand anything about this code whatsoever. can you please comment on what this code is doing at each step? i realize this is vague, and you feel you may help me too much, but i am very close to giving up because i thought i understood what was happening, but i don't
>> i ran thre debugger, and that is what it found when i asked it what the value was at 0x804970e

When you simply ask the debugger to get the value at the address, it will interpret the data at that address as an integer value.

However, that address does not contain an integer value - it contains a string. So, you have to tell your debugger to interpret the data as a string, and show it like that.

What debugger are you using ?


>> apparently i don't understand anything about this code whatsoever

Not true. You have got the basics down. I can tell by the way you ask questions.

All you need, is to piece the things together.

Can you answer me these questions ?

1) when does the strings_not_equal return 1, and when does it return 0 ?

2) which two string parameters are passed to the strings_not_equal function ? (one of them is fixed, one is entered by the user)

3) which value do you want the strings_not_equal function to return ? What input do you need to give to make that happen ?

If you can answer these questions (in the order they're given), you have your solution :)
i understand the steps to do it, but i don't know the answer to question number 2 (and therefore the second half of question 3 as well)


1) it returns 1 when the strings are not equal, 0 if they are

2) ???

3) i want the value returned to be 0, so test %eax,%eax is 0, and the jump past bomb_explode can be made
ASKER CERTIFIED SOLUTION
Avatar of Infinity08
Infinity08
Flag of Belgium image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
i am using the gdb debugger. for our class, we have remote access to linux servers, and gdb is the only thing my teacher taught us about. he never discussed getting strings from addresses, just values which in examples were always numbers
after a google search, i found the right commands to use, and i got the string "Public speaking is very easy."
gdb is a great debugger. You'll make a lot of use of it for this kind of assignment. And using it correctly will allow you to quickly find the solutions.

I suggest you read up on what the gdb debugger can do for you, how to use it, what commands are available, etc. I assume that's covered in your classes.

Here's the official documentation :

        http://www.gnu.org/software/gdb/documentation/

The part you're interested in now, is the section about examining memory :

        http://sourceware.org/gdb/current/onlinedocs/gdb_10.html#SEC71

and more specifically, to show the string stored at address 0x804970e, you do :

        x/s 0x804970e
>> i found the right commands to use

Good :)

So, can you now answer question 2) ?
>> 2) which two string parameters are passed to the strings_not_equal function ? (one of them is fixed, one is entered by the user)

i don't knwo what is being passed to the function. can you give me a hint to where i would find this? i see the fixed string being saved, but i don't see where it is passed into the strings_not_equal function
ok, i can see the string being passed is "Public speaking is very easy." This should be the solution, shouldn't it? this is the fixed parameter for the strings_not_equal function. for my input to be equal, i would need to put this in.

The only problem is, this is not correct. I put in the string exactly as I see it, and the bomb still goes boom.
i got it! the passphrase was correct, but it was giving me errors when i put it in using the gdb. when i run the program normally, it works. thanks infinity
Nice. And just to answer your earlier question (you'll need it for later phases) :

>> i don't knwo what is being passed to the function. can you give me a hint to where i would find this?

The arguments are passed on the stack. Always keep track of what happens to the stack (by drawing it for example).

At the start of the phase_1 function, the stack looks like this :

        x+4     yyy
        x         ...                                             <--- esp       (top of the stack)
        x-4      ???

where ... is whatever was at the top of the stack before the test function was called, and yyy is whatever was at the position just under the top of the stack. And x is the address of the top of the stack.

After this :

>> 8048d8f <phase_1>:
>> 8048d8f: 55                                        push   %ebp

we get (remember that the stack grows downwards to lower memory addresses) :

        x+4     yyy
        x         ...
        x-4      saved %ebp                             <--- esp       (top of the stack)
        x-8      ???

ie. the old base pointer is saved on the stack.

And then :

>> 8048d90: 89 e5                                  mov     %esp,%ebp
>> 8048d92: 83 ec 08                             sub      $0x8,%esp

gives :

        x+4     yyy
        x         ...
        x-4      saved %ebp                              <--- ebp       (the new stack frame for the test function starts here)
        x-8      ???
        x-12    ???                                            <--- esp        (top of the stack)
        x-16    ???

ie. we reserved room for 2 32bit values on the stack (from x-8 to x-12).

We then do :

>>  8048d95: c7 44 24 04 0e 97 04         movl   $0x804970e,0x4(%esp)

So :

        x+4     yyy
        x         ...
        x-4      saved %ebp                              <--- ebp       (the new stack frame for the test function starts here)
        x-8      0x804970e
        x-12    ???                                            <--- esp        (top of the stack)
        x-16    ???

And :

>>  8048d9d: 8b 45 08                             mov     0x8(%ebp),%eax
>>  8048da0: 89 04 24                             mov    %eax,(%esp)

gives :

        x+4     yyy
        x         ...
        x-4      saved %ebp                              <--- ebp       (the new stack frame for the test function starts here)
        x-8      0x804970e
        x-12    yyy                                            <--- esp        (top of the stack)
        x-16    ???

We have saved the two arguments of the strings_not_equal function on the stack. The first argument is yyy, and the second is 0x804970e. Both are memory addresses where a string can be found.

And at that time, the strings_not_equal function is called (with those two arguments) :

>> 8048da3: e8 88 00 00 00                   call      8048e30 <strings_not_equal>

If you continue drawing the stack contents like this (as soon as it enters the strings_not_equal function), you'll see what's happening with those parameters.