Jay Elrod
Jay Elrod

Reputation: 738

GDB assembler debugging

I have to do a some binary analyses for a class, and I am stuck on one of the programs. When I set some breakpoints and disas, I see that it looks like this :

Dump of assembler code for function main:
    0x080484e2 <+0>:    push   %ebp
    0x080484e3 <+1>:    mov    %esp,%ebp
    0x080484e5 <+3>:    sub    $0x48,%esp
    0x080484e8 <+6>:    and    $0xfffffff0,%esp
    0x080484eb <+9>:    mov    $0x0,%eax
    0x080484f0 <+14>:   sub    %eax,%esp
    0x080484f2 <+16>:   cmpl   $0x1,0x8(%ebp)
    0x080484f6 <+20>:   jg     0x8048504 <main+34>
    0x080484f8 <+22>:   movl   $0x7,(%esp)
 => 0x080484ff <+29>:   call   0x804833c <exit@plt>
    0x08048504 <+34>:   mov    0xc(%ebp),%eax
    0x08048507 <+37>:   add    $0x4,%eax
    0x0804850a <+40>:   mov    (%eax),%eax
    0x0804850c <+42>:   mov    %eax,(%esp)
    0x0804850f <+45>:   call   0x804832c <atoi@plt>
    0x08048514 <+50>:   mov    %eax,-0x10(%ebp)
    0x08048517 <+53>:   cmpl   $0xd,-0x10(%ebp)
    0x0804851b <+57>:   jne    0x804853b <main+89>
    0x0804851d <+59>:   lea    -0x38(%ebp),%eax
    0x08048520 <+62>:   mov    %eax,(%esp)
    0x08048523 <+65>:   call   0x8048414 <makebuf>
    0x08048528 <+70>:   lea    -0x38(%ebp),%eax
    0x0804852b <+73>:   mov    %eax,0x4(%esp)
    0x0804852f <+77>:   movl   $0x804863b,(%esp)
 ** 0x08048536 <+84>:   call   0x804831c <printf@plt>
    0x0804853b <+89>:   movl   $0x1,(%esp)
    0x08048542 <+96>:   call   0x804833c <exit@plt>
End of assembler dump.

(I've edited in the stars next to the location of call to printf@plt). What it looks like to me is a program that has a call to exit(), then builds a string, then prints that string out, and then does another exit(). I think that if I can bypass this first call to exit(), it will print me out the answer to the challenge. Is the right way to do this to set the location where the call occurs to execute NOP? If so, what is the opcode for NOP? I've tried setting to 0x0 and 0x00000000. Any help would be greatly appreciated! Thanks.

Upvotes: 0

Views: 2102

Answers (5)

Rsh
Rsh

Reputation: 7752

It doesn't necessarily exit, because of this line :

cmpl   $0x1,0x8(%ebp)

In this line, the program checks the value of the first argument to this function with one and if it greater, jumps.
Also, if you want to see the format of printf in here, you can enter printf "%s", 0x804863b in gdb.
Update :
If this procedure is main, then 0x8($ebp) contains so-called argc, which is the number of inputs of your program. So what you need to do is when you're running the program give it input. like ./a.out blah.
Also you can check this value by entering x/2wx $esp in gdb.

Upvotes: 1

Altair
Altair

Reputation: 67

If this is about homework then you should know what is allowed to do.

If patching is allowed, then the best way would be to change the opcode from jg to jng, you will have to look in the intel manuals to see what will have to be changed, but it will generally be one byte.

If patching is not allowed then you will have to find the function that will set the variable that is being compared and figure out how to make that function set it to something else.

Upvotes: 1

jcombs
jcombs

Reputation: 101

You probably don't want to just NOP out the calls to exit. You might be able to get away with it this time, but in both calls to exit they are placing the exit code onto the stack prior to the call. Depending on the rest of the program those stack values may or may not be used.

So your options would be to either NOP out both the MOV and the CALL or to force the jumps to always go the way you want.

Or the best way is to figure out exactly what parameters make it do what you want.

Also the standard NOP opcode for x86 is 0x90.

Upvotes: 1

KevinDTimm
KevinDTimm

Reputation: 14376

look at the lines

0x080484f2 <+16>:   cmpl   $0x1,0x8(%ebp)
0x080484f6 <+20>:   jg     0x8048504 <main+34>

and ascertain how you can get the program to skip the first exit - no need for injection

Upvotes: 2

HeatfanJohn
HeatfanJohn

Reputation: 7333

0x90 is a NOP instruction for x86. Therefore 0x90 is one NOP instruction, 0x9090 is two NOP instructions, 0x90909090 would be 4 NOP instructions.

Carefully check the length of the call 0x804833c instruction. I don't believe that it is 4 bytes long.

Upvotes: 0

Related Questions