-
September 30th, 2005, 08:07 AM
#1
Junior Member
Question reagarding Smashing the Stack
Hi,
I was trying out examples given in Aleph One's Smashing the Stack article. But somehow I am not getting the expected results. I am running RedHat Linux Kernel 2.4-20 on an Intel Piii.
For instance, this example is printing "1" instead of expected "0"....
void function(int a, int b, int c) {
char buffer1[5];
char buffer2[10];
int *ret;
ret = buffer1 + 12;
(*ret) += 8;
}
void main() {
int x;
x = 0;
function(1,2,3);
x = 1;
printf("%d\n",x);
}
The generated assembly is also different from the one given in the article:
---------------------------------------------------------------------
0x08048346 <main+0>: push %ebp
0x08048347 <main+1>: mov %esp,%ebp
0x08048349 <main+3>: sub $0x8,%esp
0x0804834c <main+6>: and $0xfffffff0,%esp
0x0804834f <main+9>: mov $0x0,%eax
0x08048354 <main+14>: sub %eax,%esp
0x08048356 <main+16>: movl $0x0,0xfffffffc(%ebp)
0x0804835d <main+23>: sub $0x4,%esp
0x08048360 <main+26>: push $0x3
0x08048362 <main+28>: push $0x2
0x08048364 <main+30>: push $0x1
0x08048366 <main+32>: call 0x8048328 <function>
0x0804836b <main+37>: add $0x10,%esp
0x0804836e <main+40>: movl $0x1,0xfffffffc(%ebp)
0x08048375 <main+47>: sub $0x8,%esp
0x08048378 <main+50>: pushl 0xfffffffc(%ebp)
0x0804837b <main+53>: push $0x8048438
0x08048380 <main+58>: call 0x8048268 <printf>
0x08048385 <main+63>: add $0x10,%esp
0x08048388 <main+66>: leave
0x08048389 <main+67>: ret
End of assembler dump.
---------------------------------------------------------------------
instead of
---------------------------------------------------------------------
Dump of assembler code for function main:
0x8000490 <main>: pushl %ebp
0x8000491 <main+1>: movl %esp,%ebp
0x8000493 <main+3>: subl $0x4,%esp
0x8000496 <main+6>: movl $0x0,0xfffffffc(%ebp)
0x800049d <main+13>: pushl $0x3
0x800049f <main+15>: pushl $0x2
0x80004a1 <main+17>: pushl $0x1
0x80004a3 <main+19>: call 0x8000470 <function>
0x80004a8 <main+24>: addl $0xc,%esp
0x80004ab <main+27>: movl $0x1,0xfffffffc(%ebp)
0x80004b2 <main+34>: movl 0xfffffffc(%ebp),%eax
0x80004b5 <main+37>: pushl %eax
0x80004b6 <main+38>: pushl $0x80004f8
0x80004bb <main+43>: call 0x8000378 <printf>
0x80004c0 <main+48>: addl $0x8,%esp
0x80004c3 <main+51>: movl %ebp,%esp
0x80004c5 <main+53>: popl %ebp
0x80004c6 <main+54>: ret
0x80004c7 <main+55>: nop
---------------------------------------------------------------------
Shall be grateful if somebody can point out what is the problem and what am I doing wrong.
TIA,
esprain
-
September 30th, 2005, 01:59 PM
#2
Haha, wish I could help you, I'm also stuck on level9 of hackerslab. Good luck 8-)
-
September 30th, 2005, 02:12 PM
#3
I've never read the article, so i'm unsure of what the C functions is trying to accomplish, but from what i can see, the printf statement will always printout a 1 since the last thing that happens before the printf is setting x equal to 1
There are two rules for success in life:
Rule 1: Don't tell people everything you know.
-
September 30th, 2005, 02:21 PM
#4
-
September 30th, 2005, 03:47 PM
#5
Hi
Opus00, there is no need to read Aleph One's article as a whole if
you want to understand the principle behind the example given
above. In a few words:
After "x=0;" you call a function. Of course, once the function has
completed its task, you want to go back and continue with the
statement "x=1;". Such a function call stores a return address,
let's here say the address of the statement "x=1;". The idea
of the above example is to modify this return address (esprain,
this is a hint): the return address is increased by 8. Since the
statement "x=1;" may take exactly 8 bytes (esprain, this is another
hint), you actually modify the return addresss such that you return
to "printf(...);" rather than "x=1;", effectively skipping this statement.
Hence, the output is 0 rather than 1.
Cheers
If the only tool you have is a hammer, you tend to see every problem as a nail.
(Abraham Maslow, Psychologist, 1908-70)
-
September 30th, 2005, 04:01 PM
#6
Ok, i get it now(I think), wasn't obvious to me. I've actually had this happen before unwittingly i believe. I wrote some code and it would seg fault or something, so i was trying to troubleshoot and put some printf statements in trying to find out where exactly it was dying, weird thing was it wouldn't die after putting the printf statements in, essentially the printf, ironically moved the pointer back to the proper spot on the stack. without the printf i was trying to use information in memory that was crap(pointer was in the wrong place) and it crashed. Close?
There are two rules for success in life:
Rule 1: Don't tell people everything you know.
-
September 30th, 2005, 04:23 PM
#7
Hi
If you just have added a few printf-statements, I do not see how this could
"moved the pointer back to the proper spot on the stack". Maybe you have
added a few more variables within the scope of the function, which, by accident,
hindered the return address to be overwritten.
Myself, I actually also observed the same behaviour once. I realised that the
gcc-version was slightly buggy, such that the optimisation flag -O3 produced
incorrect code. Now, by inserting a printf-function, a few optimisations cannot
be performed such that the bug had no effect. Since then, I always crosscheck
the outputs of my code with/without -O3 and with various compilers etc.
I also learned to develop code more methodically
I apologise for getting off-topic.
Cheers
If the only tool you have is a hammer, you tend to see every problem as a nail.
(Abraham Maslow, Psychologist, 1908-70)
-
September 30th, 2005, 06:59 PM
#8
Se esprian the assembly will vary from compiler flags ( the switch you give on commandline)
and the compiler itself Mr. Aleph wrote this article a time ago and things like the gcc and
gdb have evolved since then.
Nothing to be sacred though work on it instead you will really enjoy it.
-
September 30th, 2005, 09:14 PM
#9
Things have changed since that article was written. Look at the disassembly output of your code on your box. You will have to add a different value to int * ret to make it point to the return address. Did you get it yet?
-
October 3rd, 2005, 09:49 AM
#10
Junior Member
Trevoke: I've no idea about Hackerslab, but now that you mentioned it will check it.
Sec_ware, Warl0ck7 and h3r3tic: Thanks for the input. Indeed the problem is because of a new version of a compiler which happens to be 3.2.2 in my case (as opposed to the one used by Aleph).
Tried switiching off all optimizations flags (gcc flag -O0)
Actually I did try adding different values to int *ret variable. The program should crash for incorrect values which either make it jump to the middle of an instruction, or make it jump at some arbitrary location. But it seems to work fine for all the values and keeps printing value 1.
Which means either the offset of 12 in "buffer1+12" is wrong or there is some other problem, say the new versions of GCC do not allow altering the call-ret values on the stack frame???
here's the disassembly of function if it could be of any help...
Dump of assembler code for function function:
0x08048328 <function+0>: push %ebp
0x08048329 <function+1>: mov %esp,%ebp
0x0804832b <function+3>: sub $0x38,%esp
0x0804832e <function+6>: lea 0xffffffe8(%ebp),%eax
0x08048331 <function+9>: add $0x30,%eax
0x08048334 <function+12>: mov %eax,0xffffffd4(%ebp)
0x08048337 <function+15>: mov 0xffffffd4(%ebp),%edx
0x0804833a <function+18>: mov 0xffffffd4(%ebp),%eax
0x0804833d <function+21>: mov (%eax),%eax
0x0804833f <function+23>: add $0x3,%eax
0x08048342 <function+26>: mov %eax,(%edx)
0x08048344 <function+28>: leave
0x08048345 <function+29>: ret
End of assembler dump.
(gdb)
Am totally confused. Shall be grateful if somebody can shed some light...
Regards,
esprain
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
|