xorl %eax, %eax

Funny C programming interview questions

with 14 comments

I was having a look at a really nice site which you can find here. It has numerous technical job interview questions. Most of them are just basic questions for programming, algorithms, mathematics, data structures, problem solving etc. but the last one from the C programming questions was pretty cool. It was this (hope it still is):

Are there legal ways of solving this problem? If there isn’t, can it be solved on some systems vs. others using non-standard means?

#include <stdio.h>
#include <stdlib.h>

void foo(void);

int main (void)
{       
        int i=2;
        foo();
        printf ("%d\n",i);
        return EXIT_SUCCESS;
}
void foo(void)
{
    // add code so that printf above prints d
}

The funny part about this is that the replies posted are crappy and say that there is no way of doing that!! Of course there is at least one way!!! :P Here is the easiest one..
Just trick foo() to get the into the old stack frame and change the value of variable ‘i‘ which can be easily found using an offset from the base pointer. Of course, my code works just on Linux/x86 but using some #ifdef you can make it support any platform you know. Here is the code:

#include <stdio.h>
#include <stdlib.h>

void foo(void);

int main (void)
{
        int i=2;
        foo();
        printf ("%d\n",i);
        return EXIT_SUCCESS;
}
void foo(void)
{
  __asm__("popl %ebp                     \n" /* get the stored base pointer         */
          "movl %ebp, %edx               \n" /* store it temporarily on EDX         */
          "movl $313, 0xfffffff8(%ebp)   \n" /* Insert whatever value you want on i */
          "movl %edx, %ebp               \n" /* restore the foo()'s base pointer    */
          "pushl %ebp"                    ); /* put back the original base pointer  */
}

And here it is on runtime:

sh-3.1$ gcc lol.c -o lol
sh-3.1$ ./lol
313
sh-3.1$

Of course there are more elegant ways for doing this but this was just a PoC to demonstrate that this is definitately feasible! :P

Message to the people who failed answering this question on a job interview:
Guys, I just hope you didn’t get the job! You suck!! :P Go back and study the essentials of systems’ programming now.

P.S.: Dear code auditors, I’m really really sorry for not posting anything interesting the past days but apart from the cool Adobe bug there was nothing notable to discuss. If you have any suggestions on recently disclosed vulnerabilities please contact me via email :)

Written by xorl

February 26, 2009 at 13:56

Posted in C programming, fun

14 Responses

Subscribe to comments with RSS.

  1. The following should be a bit more generic, assuming stack based storage (growing up or down) of i in the scope of main. Of course this could clubber additional relevant stack data, but what the heck :-)

    void foo(void)
    {
    int *i;

    for (i = &i – 10; i < &i + 10; i++)
    if (*i == 2)
    *i = 42;
    }

    Of course, the question never mentioned crashing out as being a concern, so alternatively void foo(void) { void *a; *(&a + 1) -= 1; } could suffice.

    Just adding 2 cents to the endless pool of possibilities.

    dividead

    March 5, 2009 at 17:47

  2. Thinking outside the box, I also thought the following non-portable option is pretty neat:

    void foo(void)
    {
    char *p = “%d\n”;
    mprotect(p – (long)p % 4096, 4096, 7);
    p[0] = ‘1’, p[1] = ‘0’;
    }

    dividead

    March 5, 2009 at 18:10

  3. Nice! I really like your scanning approach but if we only referring to IA32 based platforms then I think there is a more direct way. Since ‘i’ will almost certainly be at EBP-8 then you can grab the current EBP at foo(), subtract whatever is pushed on the stack to reach ‘i’. You can either do it like:

    void foo(void)
    {
    int *base;
    __asm__(“movl %%ebp, %0\n” :”=r”(base));
    base[8 + 1 + 1] = 313;
    /* 1 -> foo’s stack frame */
    /* 1 -> printf’s format string */
    }

    Or using the address of a local variable to get the location on the stack like you did. Of course this is definitely not a portable way but it is another way of doing this. Another one could be to ptrace() this process and since before calling printf(), the main() uses EAX to store ‘i’ you can use GETREGS/SETREGS to change EAX to whatever you want.

    xorl

    March 7, 2009 at 08:23

  4. or you could just change printf’s behavior for %d.
    http://www.gnu.org/software/libc/manual/html_mono/libc.html#Customizing-Printf

    ilja

    April 4, 2009 at 23:32

  5. any value but not 2? :)

    void foo(void) {
    // add code so that printf above prints different value of i (i.e. not 2)
    char str[2];
    strcpy(str,”za”);
    }

    ~$ ./ff
    0

    lol;>

    sn

    June 17, 2009 at 21:51

  6. yet another lame trick;)

    void foo(void) {
    char buff[0];
    sprintf(buff,”%”);
    }

    ~$ ./ff
    134513680

    sn

    June 17, 2009 at 22:36

  7. /* Joke */
    void foo(void) {
    fprintf(stdout, “%d\n”, 10);
    exit(-1);
    }

    bedjo_mendem

    June 19, 2009 at 18:51

  8. No matter what you do, the local variable “i” can’t be affected by a function call (since the address of “i” doesn’t escape); therefore, any optimizing compiler worth its salt will print “2” upon reaching the end of main(), no matter what clever ha^H^Htrickery you put inside foo(). A “solution” that depends on compiling with “gcc-x86 -O0” is no solution at all.

    However, bedjo_mendem’s solution works fine on all targets I’m aware of, and could be made totally portable by using exit(0) instead of exit(-1).

    Anonymous

    August 5, 2009 at 21:11

  9. For this particular program:

    void foo(void) {printf(“42\n”); /*muahaha!*/ exit(EXIT_SUCCESS); }

    P.S. I know this is cheating the spec

    mgk

    November 5, 2009 at 18:04

  10. I didn’t think you’d even need the movl’s into and out of %edx. Sure enough it worked without them (x86 FreeBSD).

    HTH

    November 6, 2009 at 03:46

  11. @HTH: I put them to make it clearer for the readers. Since I’m not touching the popped EBP there is no actual need for them.

    xorl

    November 22, 2009 at 03:16

  12. good one buddy

    Amaresh Das

    December 1, 2009 at 07:38

  13. A few other ways I can think of. The simplest (which assumes you simply want a different output)

    void foo()
    {
    printf( “1” );
    }

    The resulting program should output 12.

    Another way, if the compiler doesn’t put i on the stack due to optimization would be for foo() to get the function address of printf(), vector it by writing a jump to the first instruction of that function to a custom printf that only outputs “3”. Although this won’t work on processors that have protected code segments.

    Yet another way would be to have foo() load the executable, and rewrite the assembly change the ‘2’ to a ‘3’, and remove the call to foo(), then launch that executable and exit.

    To name a few…

    :D

    Dom Humphrey

    December 1, 2009 at 20:19

  14. void foo(){
    char m[3];
    m[8] = ‘a’;
    }

    cperdana

    August 24, 2010 at 02:04


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s