Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 86 additions & 0 deletions docs/reverse-engineering/ELF/ELF.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
---
sidebar_position: 3
---

# ELF

## What is an ELF?

ELFs are the executable files of the Linux world. ELF stands for Executable and Linkable Format.
If you are new to this, you are probably more familiar with Windows .exe files, they serve the exact same purpose,
just for two different operating systems.

In this section, we will dive deeper into what an ELF file can reveal through static analysis,
using industry-standard tools like [IDA](/docs/reverse-engineering/Tools/ida.mdx).

## ELF sections

The data contained in an ELF is divided among multiple sections, each one serving a specific function.

- `.text`: The .text section is where the actual compiled code lives. With IDA we can analyze its decompiled version here.
- `.rodata`: The .rodata section is where constants live. In fact, "rodata" stands for read-only data, exactly what a constant value is.
- `.data`: The .data section stores the global variables of the program that are initialized with a value. Here we can see that the "ro" is no
longer there, because this section is RW, meaning that writing to it would not cause any problems.
Comment on lines +22 to +23
- `.bss`: The .bss section is very similar to .data, with the only difference being that it stores only the global variables that are NOT
initialized.
Comment on lines +24 to +25

To clarify what we are talking about, take the following code as an example:
```c
#include <stdio.h>
#include <stdlib.h>
char not_initialized[8];
int initialized = 1337;
const char constant[16] = "i'm a constant";

int main(){
int local_variable = 1;
int second_local_variable = local_variable + 10;
printf("%d",second_local_variable);
printf("%s",constant);
printf("%d",initialized);
fgets(not_initialized,8,stdin);
return 0;
}
```
We can see that there are three global variables, each with different characteristics.
With IDA we can analyze the binary produced by compiling this code, and find out that:

- `not_initialized` is in `.bss`:

![not_initialized in .bss](./img/BSS.png)

- `initialized` is in `.data`:

![initialized in .data](./img/DATA.png)

- `constant` is in `.rodata`:

![constant in .rodata](./img/RODATA.png)

- The compiled `main` function itself, along with the rest of the program's code, lives in `.text`:

![main in .text](./img/TEXT.png)

There are two other very important sections, called `.got` and `.plt`.
These introduce a new concept: <b>Dynamic Linking</b>.
A Dynamically Linked program is simply one that relies on functions the developer did not write themselves,
for example the `printf` function used in a simple C program. `printf` is part of `libc`, a library
that contains a ton of useful functions used daily in C and C++ programs.
So, how can a function from the library actually be used in a Dynamically Linked program?

### .plt
To keep things simple we will just give a brief introduction to this section, which will later be explained
in more detail in other topics in the [pwn](/docs/binary-exploitation/intro) chapter.
When a program starts, it doesn't yet know where those libc functions are. In fact, the `.plt` section is the
one that resolves them, with the help of some dedicated functions. For each libc function present in the
executable, the `.plt` stores an entry that tells the resolver which function's address it needs to find.
This way, the first time you call `printf` the program resolves its address and then stores it in the `.got`.

![PLT entry for printf](./img/PLT.png)

### .got
As we already hinted, the `.got` is the section that stores the resolved addresses of the library functions.
In fact, whenever a function is called, it first "asks" the GOT. If the GOT entry for that function is already
filled in, it uses the address that's there; otherwise, it starts the process where the `.plt` gets involved.

![GOT entry for printf](./img/GOT.png)
Binary file added docs/reverse-engineering/ELF/img/BSS.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/reverse-engineering/ELF/img/DATA.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/reverse-engineering/ELF/img/GOT.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/reverse-engineering/ELF/img/PLT.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/reverse-engineering/ELF/img/RODATA.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/reverse-engineering/ELF/img/TEXT.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions docs/reverse-engineering/Tools/_category_.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"position": 2
}
2 changes: 0 additions & 2 deletions docusaurus.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,6 @@ const config: Config = {
{
docs: {
sidebarPath: './sidebars.ts',
// Please change this to your repo.
// Remove this to remove the "edit this page" links.
editUrl:
'https://github.com/PascalCTF/Training-Wiki/tree/main/',
},
Expand Down