11
#include <stdio.h>

int main(int argc, char** argv)
{
    void (*p) (void);
    /* this obviously won't work, but what string could I put in 
       here (if anything) to make this execute something meaningful?
       Does any OS allow instructions to be read from
       the stack rather than text area of the process image? */
    char *c = "void f() { printf(\"Hello, world!\"); }";
    p = ( void (*)() )c;
    p();
    return 0;
}
Ethan Heilman
  • 16,347
  • 11
  • 61
  • 88
user389094
  • 111
  • 1
  • 5

3 Answers3

12

Sort of, but not really, there is no eval() in c, like in many scripting languages.

However, what you are describing is sort of like a Buffer Overflow exploit.

Where, you use a string to write "code" (not c syntax, but machine code) into the address space after the buffer. Here's a nice little tutorial of the topic.

Don't use this information to write a virus :(

Stephen
  • 47,994
  • 7
  • 61
  • 70
  • 3
    There is an `eval()` of sorts: write a C compiler, compile the string into machine code, then run it. – Chris Lutz Jul 12 '10 at 00:12
  • Thanks, my intention is to write a program that modifies itself during execution, perhaps even unpredictably. Nothing malicious, just as a learning exercise. – user389094 Jul 12 '10 at 00:36
  • @Chris : good point ;) @rahul : Definitely a good learning experience, sounds fun :) – Stephen Jul 12 '10 at 00:41
  • @Chris Lutz: That is easily the least useful remark I have seen all week. – j_random_hacker Jul 12 '10 at 01:08
  • 1
    @j_random_hacker - A certain level of pedantry is required to be a programmer. – Chris Lutz Jul 12 '10 at 01:17
  • @j_random : Well, dreamlax got 3 upvotes for putting it in an answer :) – Stephen Jul 12 '10 at 01:27
  • @Chris, glad you didn't take it too hard. I'm also a pedant at heart, so perhaps I was just projecting... :) – j_random_hacker Jul 12 '10 at 04:48
  • There is nothing wrong with writing a virus. It is a good exercise that every programmer who wants to call himself advanced should have done once. Not even with “infecting” one’s own systems. Or those of others who agreed to it and knew what they were getting. The problem is only in doing things to other individuals without their consent. It does not matter if it is a computer virus, just running a program on somebody’s PC, or literally infecting somebody with a biological virus. (It’s a bit more complicated for non-individuals, like young children, some mentally disabled people, and voters.) – Evi1M4chine Dec 05 '17 at 11:41
  • Tutorial link is bad. – Gabriel Staples Dec 10 '21 at 05:21
8

You could use libtcc to compile and run C source code:

const char *code = "int main(int argc, char**argv) { printf(\"Hello, world!\"); return 0; }";
TCCState *tcc = tcc_new();

if (tcc_compile_string(tcc, code))
{
    // an error occurred compiling the string (syntax errors perhaps?)
}

int argc = 1;
char *argv[] = { "test" };

int result = tcc_run (tcc, argc, argv);

// result should be the return value of the compiled "main" function.
// be sure to delete the memory used by libtcc

tcc_delete(tcc);

A coouple of issues:

  1. You can only compile libtcc on a supported architecture.
  2. You need to have a main function.
dreamlax
  • 93,976
  • 29
  • 161
  • 209
3

Sure it is possible. Buffer Overflow exploits use it.

See Shellcode for what kind of strings you can place.

Basically what you can do it put machine code on the stack and jump to the address. This will cause execution (if the OS/machine allows it, see NX bit).

You could perhaps even try to do a memcpy from some function address onto a string on the stack and then try jumping to the address on the stack.

  • Thank you, could you elaborate a bit on how I would jump to the address after memcpy? And how big a chunk of memory would i memcpy? Would I have to know how the function is represented in assembly language for that? – user389094 Jul 12 '10 at 00:40
  • Note though that we're talking about inserting binary executable code here -- you're not just going to be able to buffer overflow C and expect the processor to know WTF you're talking about. – Billy ONeal Jul 12 '10 at 00:41
  • @rahulkumar42: You can try casting the string address as a function pointer and try calling it. You don't really need to know how the function is represented, the machine will do the interpretation for you. The size to copy depends on the function you are copying and might be difficult to find out about. –  Jul 12 '10 at 00:55