9
int eax = ((int(*)())("\xc3 <- This returns the value of the EAX register"))();

How this works ? String is casted to function pointer

6
  • 3
    not sure if it even does. If anything, then maybe c3 in hexadecimal is the opcode of returning the EAX register or something like this. But really, a lot of context is missing. Commented Jul 20, 2014 at 19:15
  • 1
    Here's the original context: stackoverflow.com/a/5602143/544557 Commented Jul 20, 2014 at 19:23
  • And here's a later version: gist.github.com/leegao/910993 Commented Jul 20, 2014 at 19:29
  • Are literal strings still placed in executable memory nowadays? Tssk, tssk… It wouldn't cost anything to place them in non-executable memory, and the less memory is marked as executable, the better (even if it is already read-only) Commented Jul 20, 2014 at 19:29
  • @PascalCuoq Read the comments on the first link I posted. Commented Jul 20, 2014 at 19:30

2 Answers 2

12

c3 is the RET instruction. When an x86 machine jumps to this string interpreted as code, it will execute RET and therefore jump right back without having done anything (the rest of the string is therefore ignored). Since standard calling convention on x86 is to put your return value in eax, but the code didn't do anything before returning, whatever was already in eax will still be there, and in a position for the C code to interpret it as having been "returned".

This is highly dependent on your machine being x86 and that you're allowed to cast between data and function pointers (and execute the result) - a very system-specific hack. This is not standard compliant or portable C by any stretch!

(\xXX is C's escape syntax for inserting single nonreadable characters into strings via their ASCII code in hex, if you didn't know that part.)

Sign up to request clarification or add additional context in comments.

Comments

5

0xc3 is the ret opcode in x86. The rest of the string is only there for flavor. All of the work is done by the calling convention, and the cdecl calling convention (the default one for the C language) says that a function that returns int returns it in eax.

Your function doesn't actually do anything, it just returns as soon as it's called, but any code that calls int foo = eax() is still going to expect it to have put its return value into the eax register, so it's going to copy the contents of the eax register into foo.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.