Reputation: 738
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
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
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
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
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
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