Reverse Engineering for Beginners

(avery) #1

CHAPTER 9. MORE ABOUT RESULTS RETURNING CHAPTER 9. MORE ABOUT RESULTS RETURNING


Chapter 9


More about results returning


In x86, the result of function execution is usually returned^1 in theEAXregister. If it is byte type or a character (char), then
the lowest part of registerEAX(AL) is used. If a function returns afloatnumber, the FPU registerST(0)is used instead. In
ARM, the result is usually returned in theR0register.


9.1 Attempt to use the result of a function returningvoid


So, what if themain()function return value was declared of typevoidand notint?


The so-called startup-code is callingmain()roughly as follows:


push envp
push argv
push argc
call main
push eax
call exit


In other words:


exit(main(argc,argv,envp));


If you declaremain()asvoid, nothing is to be returned explicitly (using thereturnstatement), then something random, that
was stored in theEAXregister at the end ofmain()becomes the sole argument of the exit() function. Most likely, there
will be a random value, left from your function execution, so the exit code of program is pseudorandom.


We can illustrate this fact. Please note that here themain()function has avoidreturn type:


#include <stdio.h>


void main()
{
printf ("Hello, world!\n");
};


Let’s compile it in Linux.


GCC 4.8.1 replacedprintf()withputs()(we have seen this before:3.4.3 on page 14) , but that’s OK, sinceputs()
returns the number of characters printed out, just likeprintf(). Please notice thatEAXis not zeroed beforemain()’s
end. This implies that the value ofEAXat the end ofmain()contains whatputs()has left there.


Listing 9.1: GCC 4.8.1

.LC0:
.string "Hello, world!"
main:
push ebp
mov ebp, esp
and esp, -16
sub esp, 16
mov DWORD PTR [esp], OFFSET FLAT:.LC0


(^1) See also: MSDN: Return Values (C++):MSDN

Free download pdf