---
# System prepended metadata

title: 'Lista 9 (06.05.2021), grupa pwit'
tags: [pwit, ask21, ćwiczenia]

---

# Lista 9 (06.05.2021), grupa pwit

###### tags: `ask21` `ćwiczenia` `pwit`

## Deklaracje

Gotowość rozwiązania zadania należy wyrazić poprzez postawienie X w odpowiedniej kolumnie! Jeśli pożądasz zreferować dane zadanie (co najwyżej jedno!) w trakcie dyskusji oznacz je znakiem ==X== na żółtym tle.

**UWAGA: Tabelkę wolno edytować tylko wtedy, gdy jest na zielonym tle!**

Tabelka zawiera tylko osoby zapisane do grupy. Osoby oczekujące proszone są o wpisanie się do osobnej tabelki poniżej.


:::danger
|                      | 1   | 2   | 3   | 4   |  5  |  6  | 7   |
| --------------------:| --- | --- | --- | --- |:---:|:---:| --- |
|Wojciech Adamiec      |     |  X  |     |     |  X  |     |     |
|Kacper Bajkiewicz     |     |  X  |  X  |  X  |  X  |     |     |
|Bartłomiej Hildebrandt|  X  |  X  |     |     |  X  |     |     |
|Dominik Komła         |     |     |     |     |     |     |     |
|Aleksandra Kosińska   |     |  X  |     |     |     |     |     |
|Oleś Kulcewicz        |     |  X  |     |     |  X  |     |     |
|Damian Lukas          |     |  X  |     |     |  X  |     |     |
|Michał Mikołajczyk    |     |  X  |  X  |     |  X  |     |     |
|Mateusz Opala         |     |  X   |     |     | X   |     |     |
|Łukasz Orawiec        |     |  X  |  X  | X   |  X  |     |     |
|Szymon Pielat         |     |  X  |  X  |     |  X  |     |     |
|Łukasz Pluta          |     |  X  |     |     |  X  |     |     |
|Kamil Puchacz         |    |  X  |  X  |     |  X  |     |     |
|Magdalena Rzepka      |     |  X  |     |     |     |     |     |
|Cezary Stajszczyk     |     |  X  |  X  |     |     |     |     |
|Jakub Szajner         |     |  X  |  X  |  X  |  X  |     |     |
|Bartosz Troszka       |     |     |     |     |     |     |     |
|Miłosz Urbanik        |     |     |     |     |     |     |     |



Deklaracje zadań z listy 8:

|                      | 7   |  8  |
| --------------------:| --- |:---:|
| Bartłomiej Hildebrandt |  X  |  X  |

:::


## Zadanie 8.7 i 8.8
:::info
Autor: Bartłomiej Hildebrandt 
(Rozwiązania proszę wpisać w formularzu dla poprzedniej listy)
:::


## Zadanie 1
:::info
Autor: Bartłomiej Hildebrandt
:::
> W trakcie tłumaczenia poniższego kodu na asembler kompilator umieścił tablicę skoków dla instrukcji wyboru switch w sekcji «.rodata». W sekcji «.text» i «.rodata» wskaż miejsca występowania referencji do symboli, a następnie podaj zawartość tablicy rekordów relokacji «.rela.text» i «.rela.rodata».
> 
> ![](https://i.imgur.com/0OR076h.png)
> 
> W wyniku konsolidacji pliku wykonywalnego zawierającego procedurę «relo3», została ona umieszczona pod adresem 0x1000, a tablica skoków pod 0x2000. Oblicz wartości, które należy wstawić w miejsca referencji, do których odnoszą się rekordy relokacji.

Kod w C:
```c=
int relo3(int val) {
    switch (val) {
        case 100:
            return val;
        case 101:
            return val + 1;
        case 103:
        case 104:
            return val + 3;
        case 105:
            return val + 5;
        default:
            return val + 6;
    }
}
```

Kod w assemblerze:
```c=
0000000000000000 <relo3>:
0: 8d 47 9c             lea  -0x64(%rdi), %eax
3: 83 f8 05             cmp  $0x5, %eax
6: 77 15                ja   1d <relo3+0x1d>
8: 89 c0                mov  %eax, %eax
a: ff 24 c5 00 00 00 00 jmpq *0x0(,%rax,8)
11: 8d 47 01            lea  0x1(%rdi), %eax
14: c3                  retq
15: 8d 47 03            lea  0x3(%rdi), %eax
18: c3                  retq
19: 8d 47 05            lea  0x5(%rdi), %eax
1c: c3                  retq
1d: 8d 47 06            lea  0x6(%rdi), %eax
20: c3                  retq
21: 89 f8               mov  %edi,%eax
23: c3                  retq
```

Sekcje: 
- `.text` - kod programu
- `.rodata` - dane do odczytu (tablica skoków, stałe stringowe itp.)
- `.rel.text` - informacje o relokacji dla sekcji `.text` (np. adresy instrukcji, które będą musiały być zmodyfikowane w pliku wykonywalnym)
- `.rel.rodata` - informacje o relokacji dla sekcji `.rodata`

Narzędzia:
- `objdump` - wyświetla ogólne informacje o dowolnym formacie pliku obiektowego
- `readelf` - również wyświetla informacje o pliku obiektowym, ale może wydrukować wszystkie możliwe informacje na jego temat i jest niezależny od architektury

### W sekcji `.text` i `.rodata` wskaż miejsca występowania referencji do symboli.

Aby wskazać miejsca występowania referencji do symboli, użyjemy polecenia, które wyświetli relokacje.

```bash=
objdump -D -r -j .text relo3.o
```

Flaga `-D` deassembluje cały dany obiekt, flaga `-r` drukuje wpisy relokacji pliku, a flaga `-j` pozwala nam wybrać sekcję.

#### Sekcja `.text`

```bash=
objdump -D -r -j .text relo3.o

relo3.o:     file format elf64-x86-64


Disassembly of section .text:

0000000000000000 <relo3>:
   0:	f3 0f 1e fa          	endbr64 
   4:	8d 47 9c             	lea    -0x64(%rdi),%eax
   7:	83 f8 06             	cmp    $0x6,%eax
   a:	77 23                	ja     2f <relo3+0x2f> # referencja do symbolu
   c:	89 c0                	mov    %eax,%eax
   e:	48 8d 15 00 00 00 00 	lea    0x0(%rip),%rdx        # 15 <relo3+0x15>
			11: R_X86_64_PC32	.rodata-0x4    
  15:	48 63 04 82          	movslq (%rdx,%rax,4),%rax
  19:	48 01 d0             	add    %rdx,%rax
  1c:	3e ff e0             	notrack jmpq *%rax
  1f:	8d 47 01             	lea    0x1(%rdi),%eax
  22:	c3                   	retq   
  23:	8d 47 03             	lea    0x3(%rdi),%eax
  26:	c3                   	retq   
  27:	8d 47 05             	lea    0x5(%rdi),%eax
  2a:	c3                   	retq   
  2b:	8d 47 0a             	lea    0xa(%rdi),%eax
  2e:	c3                   	retq   
  2f:	8d 47 06             	lea    0x6(%rdi),%eax
  32:	c3                   	retq   
  33:	89 f8                	mov    %edi,%eax
  35:	c3                   	retq   
```

#### Sekcja `.rodata`

```bash=
objdump -D -r -j .rodata relo3.o

relo3.o:     file format elf64-x86-64


Disassembly of section .rodata:

0000000000000000 <.rodata>:
	...
			0: R_X86_64_PC32	.text+0x33    
			4: R_X86_64_PC32	.text+0x23
			8: R_X86_64_PC32	.text+0x37
			c: R_X86_64_PC32	.text+0x2f
			10: R_X86_64_PC32	.text+0x33
			14: R_X86_64_PC32	.text+0x3b
			18: R_X86_64_PC32	.text+0x43
```

### Podaj zawartość tablicy rekordów relokacji `.rela.text` i `.rela.rodata`.

**rekordy relokacji (ang. relocation entries)** - struktury danych w relokowalnych modułach obiektowych, których zadaniem jest poinformowanie konsolidatora jak zmodyfikować referencję do obiektu, którego lokalizacji nie zna, kiedy łączy plik obiektowy w plik wykonywalny. 

Ilekroć asembler napotka odniesienie do obiektu, którego ostateczne położenie jest nieznane, generuje pozycję relokacji, która mówi konsolidatorowi, jak zmodyfikować odniesienie, gdy łączy plik obiektowy w plik wykonywalny.

Relokacja typu `R_X86_64_PC32` relokuje referencje do adresów, które są obliczane na podstawie przesunięcia aktualnej wartości PC (Program Counter) o dany offset. Wartość PC to zawsze adres następnej instrukcji w pamięci.

Natomiast relokacja typu `R_X86_64_32` relokuje referencje do adresów, które są `absolute`, czyli bierzemy surowy adres zakodowany w instrukcji i przekształcamy na efektywny adres, bez modyfikowania go w żaden sposób.

```bash=
readelf -r relo3.o

Relocation section '.rela.text' at offset 0x4e0 contains 1 entry:
  Offset          Info           Type           Sym. Value    Sym. Name + Addend
000000000011  000500000002 R_X86_64_PC32     0000000000000000 .rodata - 4

Relocation section '.rela.rodata' at offset 0x4f8 contains 7 entries:
  Offset          Info           Type           Sym. Value    Sym. Name + Addend
000000000000  000200000002 R_X86_64_PC32     0000000000000000 .text + 33
000000000004  000200000002 R_X86_64_PC32     0000000000000000 .text + 23
000000000008  000200000002 R_X86_64_PC32     0000000000000000 .text + 37
00000000000c  000200000002 R_X86_64_PC32     0000000000000000 .text + 2f
000000000010  000200000002 R_X86_64_PC32     0000000000000000 .text + 33
000000000014  000200000002 R_X86_64_PC32     0000000000000000 .text + 3b
000000000018  000200000002 R_X86_64_PC32     0000000000000000 .text + 43
```

### Oblicz wartości, które należy wstawić w miejsca referencji, do których odnoszą się rekordy relokacji.

Algorytm relokacji:

```c=
// s - sekcja (tablica bajtów)
// r - wpis tablicy relokacji (struktury typu Elf32_Rel)

foreach section s {              // iteracja po sekcjach s
    foreach relocation entry r { // iteracja po wpisach relokacji
        refptr = s + r.offset;   // oblicza adres w tablicy s 4-bajtowego odniesienia, które ma zostać przeniesione

        /* realokuj referencję zależną od PC */
        if (r.type == R_X86_64_PC32) {    // jeżeli jest to adres typu relative to do adresu sekcji dodaj offset wpisu i realokuj
            refaddr = ADDR(s) + r.offset; // adres referencji = adres sekcji + offset wpisu realokacji
            *refptr = (unsigned) (ADDR(r.symbol) + r.addend - refaddr);
        }

        // wpp. jest to adres typu absolute, więc po prostu realokujemy go
        if (r.type == R_X86_64_32)
            *refptr = (unsigned) (ADDR(r.symbol) + r.addend);
    }
}
```

Obliczenia:

```c=
a) obliczenia dla relokacji z procedury relo3 dla sekcji .text

Sekcja .text ma tylko 1 wpis relokacji.

ADDR(r.symbol) = 0x2000
ADDR(.text)    = 0x4e0 
r.type         = R_X86_64_PC32 

// Informacje z tabeli rekordów aktywacji
r.offset = 0x11
r.addend = -0x4

refaddr = ADDR(.text) + r.offset = 0x4e0 + 0x11 = 0x4f1
*refptr = (unsigned) (ADDR(r.symbol) + r.addend - refaddr) = 0x2000 - 0x4 - 0x4f1 = 0x1b0b

b) obliczenia dla relokacji z procedury relo3 dla sekcji .rodata

Sekcja .rodata ma 7 wpisów relokacji.

ADDR(.text)    = 0x4f8 
ADDR(r.symbol) = 0x1000
r.type         = R_X86_64_PC32 

1)
r.offset = 0x0
r.addend = 0x33

refaddr = ADDR(.text) + r.offset = 0x4f8
*refptr = (unsigned) (ADDR(r.symbol) + r.addend - refaddr) = 0x1000 + 0x33 - 0x4f8 = 0xb3b

2)
r.offset = 0x4
r.addend = 0x23

refaddr = ADDR(.text) + r.offset = 0x4fc
*refptr = (unsigned) (ADDR(r.symbol) + r.addend - refaddr) = 0x1000 + 0x23 - 0x4fc = 0xb27

3)
r.offset = 0x8
r.addend = 0x37

refaddr = ADDR(.text) + r.offset = 0x500
*refptr = (unsigned) (ADDR(r.symbol) + r.addend - refaddr) = 0x1000 + 0x37 - 0x500 = 0xb37

4)
r.offset = 0xc
r.addend = 0x2f

refaddr = ADDR(.text) + r.offset = 0x504
*refptr = (unsigned) (ADDR(r.symbol) + r.addend - refaddr) = 0x1000 + 0x2f - 0x504 = 0xb2b

5)
r.offset = 0x10
r.addend = 0x33

refaddr = ADDR(.text) + r.offset = 0x508
*refptr = (unsigned) (ADDR(r.symbol) + r.addend - refaddr) = 0x1000 + 0x33 - 0x508 = 0xb2b

6)
r.offset = 0x14
r.addend = 0x3b

refaddr = ADDR(.text) + r.offset = 0x50c
*refptr = (unsigned) (ADDR(r.symbol) + r.addend - refaddr) = 0x1000 + 0x3b - 0x50c = 0xb2f

7)
r.offset = 0x18
r.addend = 0x43

refaddr = ADDR(.text) + r.offset = 0x510
*refptr = (unsigned) (ADDR(r.symbol) + r.addend - refaddr) = 0x1000 + 0x43 - 0x510 = 0xb33
```


## Zadanie 2
:::info
Autor: Szymon Pielat
:::

![](https://i.imgur.com/of1nUCm.png)

**Dekorowanie nazw** służy do tego, aby odróżnić implementację różnych funkcji (o różnych sygnaturach) mających taką samą nazwę. Jest to oczywiście potrzebne w C++, ponieważ możemy przeciążać funkcje. Funkcja dekorująca jest różnowartościowa.

Udekorowane symbole zaczynają się od `_Z`.
Następnie mamy literę `N` mówiąca czy następuje`namespace`

1. Jeśli nie ma `N` to od razu po `Z` kodujemy nazwę podając najpierw liczbę liter wchodzących w skład nazwy, a następnie pełną nazwę. 
2. Jeśli jest `N` to podajemy kolejne `namespace`'y na tej samej zasadzie co powyżej a po podaniu nazwy funkcji mamy literę `E`.

Następnie przechodzimy do argumentów funkcji. Tutaj mamy:
1. `P` oznacza `*`
2. `K` oznacza `const`
3. `R` oznacza `&`
4. `i` oznacza `int`, `d` oznacza `double` ....

Przykłady z zadania:
- `_Z4funcPKcRi` = `func(char const*, int&)`
- `_ZN3Bar3bazEPc` = `Bar::baz(char*)`
- `_ZN3BarC1ERKS_` =`Bar::Bar(Bar const&)`
- `_ZN3foo6strlenER6string` =`foo::strlen(string&)`


## Zadanie 3
:::info
Autor: Michał Mikołajczyk
:::
:::info
Przeprowadź na swoim komputerze atak na program «ropex» wykorzystując podatność **przepełnienia bufora** w procedurze «echo». Posłuż się techniką **ROP** (ang. return oriented programming). Wyznacz adresy  procedury  `«gadget»`  oraz  dowolnej  instrukcji  `«syscall»`  w  pliku  `«ropex»`.  Wpisz  je,  w  porządku little-endian, do pliku `«ropex.in.txt»` na pozycji **0x38** i **0x40**, po czym przetłumacz go do postaci binarnej. Następnie uruchom polecenie `«ropex ropex.in»`, aby zobaczyć rezultat wykonania programu `«nyancat»` w  terminalu.  Przy  pomocy  debuggera gdb zaprezentuj  zawartość  stosu  przed  i  po  wykonaniu  procedury `«gets»`. Pokaż jak procesor wykonując instrukcje `«ret»` skacze pod przygotowane przez Ciebie adresy.
:::

#### Definicje:
- **Przepełnienie bufora** -- funkcja może alokować bufor na stosie, a następnie przy wczytywaniu danych z wejścia/pliku może nie sprawdzać czy wczytała za dużo danych. W takim przypadku wypełnimy cały bufor na stosie, a następnie nadpiszemy część stosu poniżej tej części, która należy do wywoływanej funkcji. W ten sposób możemy nadpisać np. adres powrotu z funkcji.
- **ROP** -- technika polegająca na wykorzystywaniu istniejących części kodu atakowanej aplikacji. Polega na wczytaniu na stos i skoku do adresów instrukcji, które wykonują pożądane przez nas operacje i kończą się instrukcją *0xc3* (`ret`).

#### Przydatne polecenia:
```
sh:
    objdump -d ropex
    gdb --args ropex ropex.in

gdb:
    x/32x $rsp[+0x??]      (wyświetlanie bajtów ze stosu)
    x/16c $rsp[+0x??]      (wyświetlanie ascii ze stosu)
```

#### Procedura echo:
```
000000000040187b <echo>:
  40187b:       48 83 ec 38             sub    $0x38,%rsp
  40187f:       48 89 e6                mov    %rsp,%rsi
  401882:       e8 be ff ff ff          call   401845 <readline>
  401887:       48 89 e7                mov    %rsp,%rdi
  40188a:       e8 d1 90 00 00          call   40a960 <_IO_puts>
  40188f:       48 83 c4 38             add    $0x38,%rsp
  401893:       c3                      ret    
```

#### Procedura gadget:
```
00000000004018cb <gadget>:
  4018cb:       48 ff c8                dec    %rax
  4018ce:       48 89 d6                mov    %rdx,%rsi
  4018d1:       48 89 fa                mov    %rdi,%rdx
  4018d4:       48 8d 7c 24 10          lea    0x10(%rsp),%rdi
  4018d9:       c3                      ret    
  4018da:       66 0f 1f 44 00 00       nopw   0x0(%rax,%rax,1)
```

#### Jedna z instrukcji syscall:
```
  4011ed:       be 81 00 00 00          mov    $0x81,%esi
  4011f2:       b8 ca 00 00 00          mov    $0xca,%eax
  4011f7:       48 8d 3d 42 0b 0b 00    lea    0xb0b42(%rip),%rdi   # 4b1d40 <lock>
  4011fe:       0f 05                   syscall  # <==============================
  401200:       bf 06 00 00 00          mov    $0x6,%edi
  401205:       e8 e6 76 00 00          call   4088f0 <raise>
  40120a:       64 48 8b 1c 25 10 00    mov    %fs:0x10,%rbx
```

## Zadanie 4
:::info
Autor: Łukasz Orawiec
:::

**Kanarek** *(ang. canary)* -- losowa liczba umieszczana na stosie na początku wykonywania procedury, tuż przed adresem powrotu. Na końcu procedury jest sprawdzane, czy wartość się nie zmieniła, co mogłoby oznaczać przepełnienie bufora. 

<br/>

**Uszkodzenie stosu** *(ang. stack smashing)* -- sytuacja, w której przepełnienie bufora prowadzi do nadpisania sąsiadującego obszaru pamięci na stosie (np. adres powrotu).

<br/>

**Randomizacja rozkładu przestrzeni adresowej** -- zabezpieczenie sprawiające, że różne sekcje programu są umieszczane pod losowymi adresami. Utrudnia atak przez wstrzyknięcie kodu na stos, bo trudno ustalić adres bufora.

<br/>

**Gadżet** -- fragment kodu istniejącego w programie wykorzystywany do ataku ROP.


## Zadanie 5
:::info
Autor: Wojciech Adamiec
:::
:::info
![](https://i.imgur.com/xooVenK.png)
:::

**Dyrektywa asemblera** (assembler directive) to fraza w języku asemblera, która określa działanie asemblera i nie tłumaczy się bezpośrednio na kod maszynowy. Wszystkie dyrektywy asemblera zaczynają się od kropki (`.`).

Kod napisany w C. Potem przetłumaczony do `.s`:
`gcc -S -Og 1.c`
`gcc -S 2.c`
`gcc -S -O0 3.c`

Teraz, żeby sprawdzić `.symtab` to trzeba przetłumaczyć do `.o`. Po czym robimy `readelf -s nazwa.o`

Foo:
![](https://i.imgur.com/Lrph5St.png)

Struct:
![](https://i.imgur.com/bA35cIB.png)

Array:
![](https://i.imgur.com/Uh8yDRM.png)

[Link do dokumentacji](https://docs.oracle.com/cd/E26502_01/html/E28388/eoiyg.html)

Legenda:

`.align` integer, pad
The .align directive causes the next data generated to be aligned modulo integer bytes. Integer must be a positive integer expression and must be a power of 2. If specified, pad is an integer byte value used for padding. The default value of pad for the text section is 0x90 (nop); for other sections, the default value of pad is zero (0).

`.comm` name, size,alignment
The .comm directive allocates storage in the data section. The storage is referenced by the identifier name. Size is measured in bytes and must be a positive integer. Name cannot be predefined. Alignment is optional. If alignment is specified, the address of name is aligned to a multiple of alignment.

`.size` symbol, expr
Declares the symbol size to be expr. expr must be an absolute expression.

`.zero` expression
While filling a data section, the .zero directive fills the number of bytes specified by expression with zero (0).

Sprawdzamy `.symtab`:
1.
![](https://i.imgur.com/AL0Bpue.png)
2.
![](https://i.imgur.com/k4EIV1Q.png)
3.
![](https://i.imgur.com/rKiv6Rv.png)



## Zadanie 6
:::info
Autor:
:::


## Zadanie 7
:::info
Autor:
:::



