Page 1 of 2 12 LastLast
Results 1 to 10 of 12

Thread: Question reagarding Smashing the Stack

  1. #1
    Junior Member
    Join Date
    Sep 2005
    Posts
    3

    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

  2. #2
    Senior Member
    Join Date
    Sep 2005
    Posts
    221
    Haha, wish I could help you, I'm also stuck on level9 of hackerslab. Good luck 8-)
    Definitions: Hacker vs. Cracker
    Gentoo Linux user, which probably says a lot about me..
    AGA member 14460 || KGS : Trevoke and games archived

  3. #3
    Senior Member Opus00's Avatar
    Join Date
    May 2005
    Posts
    143
    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.

  4. #4
    Senior Member
    Join Date
    Sep 2005
    Posts
    221
    Definitions: Hacker vs. Cracker
    Gentoo Linux user, which probably says a lot about me..
    AGA member 14460 || KGS : Trevoke and games archived

  5. #5
    Senior Member
    Join Date
    Mar 2004
    Posts
    557
    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)

  6. #6
    Senior Member Opus00's Avatar
    Join Date
    May 2005
    Posts
    143
    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.

  7. #7
    Senior Member
    Join Date
    Mar 2004
    Posts
    557
    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)

  8. #8
    Senior Member
    Join Date
    Jun 2003
    Posts
    188
    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.

  9. #9
    Elite Hacker
    Join Date
    Mar 2003
    Posts
    1,407
    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?

  10. #10
    Junior Member
    Join Date
    Sep 2005
    Posts
    3
    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
  •