Skip to content

Commit f969d9f

Browse files
committed
got-plt: Add review on GOT (and PLT) analysis demo
1 parent 2c3dfb3 commit f969d9f

File tree

1 file changed

+19
-14
lines changed

1 file changed

+19
-14
lines changed

got-plt/README.md

+19-14
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Analysis of GOT in ELF Programs
22

33
Addresses of global symbols (global variables and functions) are only known at load time for dynamically linked libraries; the program is built to work with different versions of dynamic libraries; each version uses different symbol addresses.
4-
Moreover, program and library code will most likely randomly placed in memory (via ASLR - *Address Space Layout Randomization*).
4+
Moreover, program and library code will be most likely randomly placed in memory (via ASLR - *Address Space Layout Randomization*).
55
Lastly, [IFUNC (*indirect functions*) support](https://sourceware.org/glibc/wiki/GNU_IFUNC) provides multiple implementations of a given function, the address of which will only be known at runtime.
66

77
In ELF programs, GOT (*Global Offset Table*) stores **addresses** that are **unknown until load time**.
@@ -33,13 +33,13 @@ We require GDB for dynamic analysis.
3333
## Demo Files
3434

3535
There are two source code files (`main.c` and `basket.c`), a header file (`basket.h`) and a `Makefile`.
36-
The `bascket.c` file will be compiled into a shared library (`libbasket.so`).
36+
The `basket.c` file will be compiled into a shared library (`libbasket.so`).
3737
The `main.c` will be compiled and linked against the shared library, resulting in an executable `main`.
3838
We investigate the resulting files: the `main` executable and the `libbasket.so` library.
3939

4040
To limit the amount of unnecessary information (such as additional sections and functions added by the default compilation and the use of the standard C library), we use the `nostdlib/` folder.
4141
When building files in `nostdlib/`, as its name tells, there will be no use of the standard C library, reducing the unnecessary information.
42-
To build and run without standard C library support, we require a small assembly file (`start.s`) that defines the program entry point (`_start`) and wraps the call to the `main()` function.
42+
To build and run without standard C library support, we require a small assembly file (`start.s`) that defines the program entry point (`_start`) (using `-e_start` as a linker option) and wraps the call to the `main()` function.
4343

4444
Build the `main` executable and the `libbasket.so` library:
4545
```
@@ -51,7 +51,7 @@ ld -shared -o libbasket.so basket.o
5151
ld -e_start -pie -dynamic-linker=/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 -rpath=. -o main start.o main.o -L. -lbasket
5252
```
5353

54-
Running the program prints nothing, but that's not relevant or our investigation:
54+
Running the program prints nothing, but that's not relevant for our investigation:
5555
```
5656
$ ./main
5757
```
@@ -161,7 +161,7 @@ Hex dump of section `.got.plt`:
161161
```
162162

163163
The `.got` section contains one entry (8 bytes), while the `.got.plt` section contains four entries (32 bytes).
164-
Both section are zero-filled (with some exceptions that we won't delve into).
164+
Both sections are zero-filled (with some exceptions that we won't delve into).
165165
Their useful content (variable and function addresses) is unknown until load time.
166166

167167
We see how the `.got` section is used by the program, in the `.text` section (where the `main()` function resides):
@@ -191,7 +191,7 @@ Disassembly of section .text:
191191
3b3: c3 ret
192192
```
193193

194-
At address `39f` above, the instruction accesses the `200ff8` address, marked as refering the `basket_size` symbol.
194+
At address `39f` above, the instruction accesses the `200ff8` address, marked as referring the `basket_size` symbol.
195195
The `0x200ff8` is the address of the entry in `.got`.
196196

197197
We see how the `.got.plt` section is used by the trampoline code in the `.plt` section:
@@ -214,8 +214,8 @@ Disassembly of section .plt:
214214
37b: e9 e0 ff ff ff jmp 360 <.plt>
215215
```
216216

217-
At address `370` above, the instruction accesses the `2010181` address, marked as refering the `flowers` symbol.
218-
The `0x201018` address is the last (4th) entry in the `.got.plt` section.
217+
At address `370` above, the instruction accesses the `201018` address, marked as referring the `flowers` symbol.
218+
`0x201018` is the address of the last (4th) entry in the `.got.plt` section.
219219

220220
With static analysis, we found that:
221221
* The `.got` and `.got.plt` sections are not filled with actual data (with some exceptions in `.got.plt` that we don't delve into).
@@ -224,6 +224,8 @@ With static analysis, we found that:
224224

225225
## Dynamic Analysis
226226

227+
**Note**: Similarly to the static analysis section, addresses shown as part of the dynamic analysis will differ from your own.
228+
227229
We use GDB for dynamic analysis.
228230
Our goal is to check the contents of the `.got` and `.got.plt` sections at runtime, after being filled with the actual addresses.
229231

@@ -252,6 +254,8 @@ Exec file:
252254
[...]
253255
```
254256
The runtime address is `0x555555754ff8` for the `.got` section, and `0x555555755000` for the `.got.plt` section.
257+
Note that, because `main` is a position-independent executable, these addresses differ from the ones found when doing static analysis: `0x200ff8` and `0x201000`.
258+
Even so, their relative placement and page address (the last 3 hex digits) are identical.
255259

256260
### .got
257261

@@ -282,7 +286,7 @@ We now check the contents of the `.got` section entry for the `basket_size` symb
282286
```
283287
The `.got` entry is no longer zero-filled.
284288
It stores the address `0x00007ffff7dd2018`, the actual address of the `basket_size` variable.
285-
After loading the `libbasket.so` library in memory, the loader was able to determine the addres of the `basket_size` variable and place it the corresponding `.got` memory entry.
289+
After loading the `libbasket.so` library in memory, the loader was able to determine the address of the `basket_size` variable and place it the corresponding `.got` memory entry.
286290

287291
We validate that the address `0x00007ffff7dd2018` is indeed the address of the `basket_size` variable by using GDB print and checking its contents:
288292
```
@@ -293,7 +297,8 @@ $1 = (<data variable, no debug info> *) 0x7ffff7dd2018 <basket_size>
293297
```
294298
The value `3` is the initial value of the `basket_size` variable.
295299

296-
As expected, the `basket_size` variable (at address `0x7ffff7dd2018`) is part of the `.data` section (for global data) of the `libbasket.so` shared library:
300+
As expected, the `basket_size` variable (at address `0x7ffff7dd2018`) is part of the `.data` section (for global data) of the `libbasket.so` shared library.
301+
Use the `Enter`/`Return` key in the `maint info sections ALLOBJ` command below to reach the listing of sections in the `libbasket.so` object:
297302
```
298303
(gdb) maint info sections ALLOBJ
299304
[...]
@@ -319,9 +324,9 @@ We use the address from the output of the `maint info sections ALLOBJ`:
319324

320325
The 4th instruction in the assembler code dump (marked as `flowers@plt`) uses address `0x555555755018`.
321326
This is an address in the `.got.plt` section, belonging to the `flowers` symbol.
322-
The `flowers@plt` address (`0x555555554370`) is used main to call the `flowers()` function, as shown in the `main` assembler code dump.
327+
The `flowers@plt` address (`0x555555554370`) is used in the `main()` function to call the `flowers()` function, as shown in the `main` assembler code dump.
323328

324-
We check the contents of the `.got.plt` entry belonging the `flowers` symbol:
329+
We check the contents of the `.got.plt` entry belonging to the `flowers` symbol:
325330
```
326331
(gdb) x/gx 0x555555755018
327332
0x555555755018: 0x0000555555554376
@@ -333,7 +338,7 @@ It stores the address `0x0000555555554376`, which is a trampoline address:
333338
0x555555554376 <flowers@plt+6>: push 0x0
334339
0x55555555437b <flowers@plt+11>: jmp 0x555555554360
335340
```
336-
The address now stored in the `.got.plt` entry is the address of tne next instruction in `.plt` (`0x555555554376`).
341+
The address now stored in the `.got.plt` entry is the address of the next instruction in `.plt` (`0x555555554376`).
337342
It basically said: *Get back where you came from!*
338343
This is a feature of the loader, called [lazy binding](https://docs.oracle.com/cd/E23824_01/html/819-0690/chapter3-7.html).
339344
The actual function address is not determined at load time, but the first time the function is called.
@@ -414,6 +419,6 @@ We used `nm`, `objdump` and `readelf` for static analysis and GDB for dynamic an
414419
* We saw the use of GOT by disassembling the program code and the `.plt` section.
415420
With this, we saw how and when GOT entries are populated and used by programs.
416421

417-
While GOT and PLT are particular to ELF programs, the feature itself is used for other executable formats.
422+
While GOT and PLT are particular to ELF programs, the feature itself is used by other executable formats.
418423
Microsoft Windows PE (*Portable Executable*) programs use [*Import Address Table* (IAT)](http://sandsprite.com/CodeStuff/Understanding_imports.html).
419424
Apple macOS/iOS Mach-O programs [use](https://www.apriorit.com/dev-blog/225-dynamic-linking-mach-o) the `__TEXT.__stubs`, `__TEXT.__stub_helpers` and `__DATA.__la_symbol_ptr` sections.

0 commit comments

Comments
 (0)