Functions
What is a function?
Functions are logical, repeatable constructs in programming. However, there are no formal definitions for how functions are expressed.
So what does this mean for us as binary analysts? Well, the onus is on us to define function clearly when we claim to find them. To do this well, we need to clearly define where the definitions get hazy.
Function Inlining
Compilers are designed to take a high-level programming language and convert it to assembly language, where much of the semantical distinctions made in the higher-level language are lost.
Many times, compilers make optimizations for performance. A specific case of this occurs when a program attempts to optimize space.
Here is a minimal reproducible example of this:
#include <stdlib.h>
int add(int a, int b) { return a + b; }
int main(int argc, char **argv) {
int a = atoi(argv[1]), b = atoi(argv[2]);
int sum = add(a, b);
return sum;
}
Compile this program with gcc -Oz -fwhole-program
. The flag -Oz
will hyper-optimize for file size, even at the cost of performance, while -fwhole-program
will allow GCC to remove dead-code.
When this gets compiled, you will get the following assembly:
main:
push rbp
mov rbp, rsi
push rbx
push rax
mov rdi, QWORD PTR [rsi+8]
call atoi
mov rdi, QWORD PTR [rbp+16]
xchg eax, ebx
call atoi
pop rdx
add eax, ebx
pop rbx
pop rbp
ret