1.4 Returning Values
1.3.4 Empty Functions in Practice.
Despite the fact empty functions seem useless, they are quite frequent in low-level code.
First of all, they are quite popular in debugging functions, like this one:
Listing 1.6: C/C++ Code
void dbg_print (const char *fmt, ...)
{
#ifdef _DEBUG
// open log file
// write to log file
// close log file
#endif
};
void some_function()
{
dbg_print ("we did something\n");
};
In a non-debug build (as in a “release”),_DEBUGis not defined, so thedbg_print()function, despite still
being called during execution, will be empty.
Similarly, a popular method of software protection is to make one build for legal customers, and another
demo build. A demo build can lack some important functions, as with this example:
Listing 1.7: C/C++ Code
void save_file ()
{
#ifndef DEMO
// actual saving code
#endif
};
Thesave_file()function can be called when the user clicksFile->Saveon the menu. The demo version
may be delivered with this menu item disabled, but even if a software cracker will enable it, only an empty
function with no useful code will be called.
IDA marks such functions with names likenullsub_00,nullsub_01, etc.
1.4 Returning Values
Another simple function is the one that simply returns a constant value:
Listing 1.8: C/C++ Code
int f()
{
return 123;
};
Let’s compile it.
1.4.1 x86
Here’s what both the GCC and MSVC compilers produce (with optimization) on the x86 platform:
Listing 1.9: Optimizing GCC/MSVC (assembly output)
f:
mov eax, 123
ret