Has anyone ever seen this before?

This is a discussion on Has anyone ever seen this before? within the C Programming forums, part of the General Programming Boards category; I know most posts are asking why something doesn't work, but in this case, it shouldn't but does. This uses ...

  1. #1
    Registered User
    Join Date
    Jun 2009
    Posts
    30

    Has anyone ever seen this before?

    I know most posts are asking why something doesn't work, but in this case, it shouldn't but does. This uses an array as a function and executes it without a problem. Does anyone know why?

    Code:
    char code[3] = 
    {
    	"\x90"		//nop
    	"\xC3"		//ret
    };
    
    int main () 
    {
    
    	void (*funct)() = (void (__cdecl *)(void))(void*) &code;
    	funct();
    }

  2. #2
    Registered User
    Join Date
    Jan 2009
    Location
    Australia
    Posts
    375
    There isn't really any reason for it not to work. Calls the address of 'code' which has two instructions.

    When a function call is executed the return address is pushed onto the stack and when ret is used it is popped and jumped to.

  3. #3
    cas
    cas is offline
    Registered User
    Join Date
    Sep 2007
    Posts
    984
    Because you're asking the compiler to do it.

    You're going outside of the C standard when you convert from a pointer to an array to a function. Your compiler, apparently, does something "useful" here.

    C is often called a portable assembler, and not without some merit. C does have a type system, but you can get around it pretty easily. A function pointer is supposed to point to a function, but as you can see, you can circumvent that. If the bytes at the location the function pointer points to look like a function, why wouldn't it act like a function call?

    There's no guarantee that this will work--but on some systems, there's really no difference between a function and an array of bytes that happen to look like that function.

  4. #4
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,627
    Likely on modern OS, it will not work because it's stored in a non-executable code segment.
    But there is nothing stopping you from allocating some memory, filling it with some code and marking it as executable. Then it would definitely work.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  5. #5
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,046
    The array contains the machine code for a simple function that does nothing. (Well, a hexadecimal ASCII representation of the machine code.) Normally functions are created by the compiler and put into read-only portions of the memory, but you can put the actual data anywhere and ask the CPU to execute it if you like.

    That doesn't mean it's a good idea. It's very unportable to hard-code machine code like that, and it's not a good idea to put it into read-write memory where the code could be modified. Any antivirus program looking at that might get suspicious.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

Popular pages Recent additions subscribe to a feed

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21