You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: got-plt/README.md
+19-14
Original file line number
Diff line number
Diff line change
@@ -1,7 +1,7 @@
1
1
# Analysis of GOT in ELF Programs
2
2
3
3
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*).
5
5
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.
6
6
7
7
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.
33
33
## Demo Files
34
34
35
35
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`).
37
37
The `main.c` will be compiled and linked against the shared library, resulting in an executable `main`.
38
38
We investigate the resulting files: the `main` executable and the `libbasket.so` library.
39
39
40
40
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.
41
41
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.
43
43
44
44
Build the `main` executable and the `libbasket.so` library:
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:
55
55
```
56
56
$ ./main
57
57
```
@@ -161,7 +161,7 @@ Hex dump of section `.got.plt`:
161
161
```
162
162
163
163
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).
165
165
Their useful content (variable and function addresses) is unknown until load time.
166
166
167
167
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:
191
191
3b3: c3 ret
192
192
```
193
193
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.
195
195
The `0x200ff8` is the address of the entry in `.got`.
196
196
197
197
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:
214
214
37b: e9 e0 ff ff ff jmp 360 <.plt>
215
215
```
216
216
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.
219
219
220
220
With static analysis, we found that:
221
221
* 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:
224
224
225
225
## Dynamic Analysis
226
226
227
+
**Note**: Similarly to the static analysis section, addresses shown as part of the dynamic analysis will differ from your own.
228
+
227
229
We use GDB for dynamic analysis.
228
230
Our goal is to check the contents of the `.got` and `.got.plt` sections at runtime, after being filled with the actual addresses.
229
231
@@ -252,6 +254,8 @@ Exec file:
252
254
[...]
253
255
```
254
256
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.
255
259
256
260
### .got
257
261
@@ -282,7 +286,7 @@ We now check the contents of the `.got` section entry for the `basket_size` symb
282
286
```
283
287
The `.got` entry is no longer zero-filled.
284
288
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.
286
290
287
291
We validate that the address `0x00007ffff7dd2018` is indeed the address of the `basket_size` variable by using GDB print and checking its contents:
The value `3` is the initial value of the `basket_size` variable.
295
299
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:
297
302
```
298
303
(gdb) maint info sections ALLOBJ
299
304
[...]
@@ -319,9 +324,9 @@ We use the address from the output of the `maint info sections ALLOBJ`:
319
324
320
325
The 4th instruction in the assembler code dump (marked as `flowers@plt`) uses address `0x555555755018`.
321
326
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.
323
328
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:
325
330
```
326
331
(gdb) x/gx 0x555555755018
327
332
0x555555755018: 0x0000555555554376
@@ -333,7 +338,7 @@ It stores the address `0x0000555555554376`, which is a trampoline address:
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`).
337
342
It basically said: *Get back where you came from!*
338
343
This is a feature of the loader, called [lazy binding](https://docs.oracle.com/cd/E23824_01/html/819-0690/chapter3-7.html).
339
344
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
414
419
* We saw the use of GOT by disassembling the program code and the `.plt` section.
415
420
With this, we saw how and when GOT entries are populated and used by programs.
416
421
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.
418
423
Microsoft Windows PE (*Portable Executable*) programs use [*Import Address Table* (IAT)](http://sandsprite.com/CodeStuff/Understanding_imports.html).
419
424
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