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
x