bomblab实验-bomb1~6and隐藏关

2023-10-31

bomb1:

08048ae0 <phase_1>:

8048ae0:       55                      push   %ebp

8048ae1:       89 e5                   mov    %esp,%ebp   //压栈操作

8048ae3:       83 ec 18                sub    $0x18,%esp  //开辟栈空间(24个字节)

8048ae6:       c7 44 24 04 48 a1 04    movl   $0x804a148,0x4(%esp)//向栈中存储0x804a148处的数据

8048aed:       08

8048aee:       8b 45 08                mov    0x8(%ebp),%eax//将栈帧中数据传入eax(写入参数)

  8048af1:       89 04 24                mov    %eax,(%esp)   //进栈

  8048af4:       e8 59 04 00 00          call   8048f52 <strings_not_equal>//调用函数

  8048af9:       85 c0                   test   %eax,%eax   //进行匹配比较

  8048afb:       74 05                   je     8048b02 <phase_1+0x22>    //跳转到phase_2

  8048afd:       e8 73 06 00 00          call   8049175 <explode_bomb>    //引爆炸弹

  8048b02:       c9                      leave         //释放局部变量

  8048b03:       c3                      ret       //返回函数调用

通过call可知在phase_1中调用了 strings_not_equal() 函数,其作用为判断字符串是否匹配。可知0x804a148处的字符串应该为被匹配的字符串,eax中为传入的参数,即0x804a148处字符串为该题答案。

输入查看eax中test之后为0,所以答案正确!

bomb2:

08048b04 <phase_2>:

 8048b04:       55                      push   %ebp

 8048b05:       89 e5                   mov    %esp,%ebp    //压栈

 8048b07:       56                      push   %esi        

 8048b08:       53                      push   %ebx         //esi,ebx进栈

 8048b09:       83 ec 30                sub    $0x30,%esp   //开辟栈空间(48字节)

 8048b0c:       8d 45 e0                lea    -0x20(%ebp),%eax  //取地址(ebp-0x20)到eax

 8048b0f:       89 44 24 04             mov    %eax,0x4(%esp)    //将eax中内容(地址)存入栈

 8048b13:       8b 45 08                mov    0x8(%ebp),%eax    //ebp+8处的元素存入eax

 8048b16:       89 04 24                mov    %eax,(%esp)       //存入栈中

 8048b19:       e8 99 06 00 00          call   80491b7 <read_six_numbers>//调用函数(读6个数字)

 8048b1e:       83 7d e0 31             cmpl   $0x31,-0x20(%ebp)     //比较0x31和ebp-0x20处的值进行比较【第一个数字a[0]放在了ebp-0x20】

 8048b22:       7f 20                   jg     8048b44 <phase_2+0x40>     //若大于,跳转到8048b44(进入循环体),即第一个数据大于0x31

 8048b24:       e8 4c 06 00 00          call   8049175 <explode_bomb>     //引爆炸弹

 8048b29:       eb 19                   jmp    8048b44 <phase_2+0x40>     //无条件跳转到8048b44(跳转进入循环体)

 8048b2b:       8b 43 fc                mov    -0x4(%ebx),%eax //前一个参数放入eax

 8048b2e:       8d 44 00 01             lea    0x1(%eax,%eax,1),%eax//取eax+eax*1+1放入eax

 8048b32:       39 03                   cmp    %eax,(%ebx)  //比较a[0]和eax中数据

//【a[i]=2*a[i-1]+1】

 8048b34:       74 05                   je     8048b3b <phase_2+0x37> //等于跳转到8048b3b

 8048b36:       e8 3a 06 00 00          call   8049175 <explode_bomb> //则引爆炸弹

 8048b3b:       83 c3 04                add    $0x4,%ebx    //ebx=ebx+4

 8048b3e:       39 f3                   cmp    %esi,%ebx    //比较esi和ebx

 8048b40:       75 e9                   jne    8048b2b <phase_2+0x27>//不相等,跳转到8048b2b

 8048b42:       eb 08                   jmp    8048b4c <phase_2+0x48> //无条件跳转到8048b4c

 8048b44:       8d 5d e4               lea    -0x1c(%ebp),%ebx //(a[1]) ebp-0x1c的地址到ebx

 8048b47:       8d 75 f8                lea    -0x8(%ebp),%esi

 8048b4a:       eb df                  jmp    8048b2b <phase_2+0x27>//无条件跳转到8048b2b(循环)

 8048b4c:       83 c4 30                add    $0x30,%esp//esp+0x30

 8048b4f:       5b                      pop    %ebx

 8048b50:       5e                      pop    %esi

 8048b51:       5d                      pop    %ebp

 8048b52:       c3                      ret

 

080491b7 <read_six_numbers>:

 80491b7:       55                      push   %ebp

 80491b8:       89 e5                   mov    %esp,%ebp         //压栈

 80491ba:       83 ec 28                sub    $0x28,%esp        //栈指针向下移动40个字节

 80491bd:       8b 45 0c                mov    0xc(%ebp),%eax    //数组a地址存入eax

 80491c0:       8d 50 14                lea    0x14(%eax),%edx   //a+5

 80491c3:       89 54 24 1c             mov    %edx,0x1c(%esp)

 80491c7:       8d 50 10                lea    0x10(%eax),%edx   //a+4

 80491ca:       89 54 24 18             mov    %edx,0x18(%esp)

 80491ce:       8d 50 0c                lea    0xc(%eax),%edx    //a+3

 80491d1:       89 54 24 14             mov    %edx,0x14(%esp)

 80491d5:       8d 50 08                lea    0x8(%eax),%edx    //a+2

 80491d8:       89 54 24 10             mov    %edx,0x10(%esp)

 80491dc:       8d 50 04                lea    0x4(%eax),%edx    //a+1

 80491df:       89 54 24 0c             mov    %edx,0xc(%esp)

 80491e3:       89 44 24 08             mov    %eax,0x8(%esp)

 80491e7:       c7 44 24 04 e5 a3 04    movl   $0x804a3e5,0x4(%esp)//a所在地址

 80491ee:       08

 80491ef:       8b 45 08                mov    0x8(%ebp),%eax

 80491f2:       89 04 24                mov    %eax,(%esp)

 80491f5:       e8 e6 f5 ff ff          call   80487e0 <__isoc99_sscanf@plt>   //调用sscanf

 80491fa:       83 f8 05                cmp    $0x5,%eax  //sscanf从input中读取的数据个数

 80491fd:       7f 05                   jg     8049204 <read_six_numbers+0x4d>//5大于输入,跳转到8049204

 80491ff:       e8 71 ff ff ff          call   8049175 <explode_bomb>     //小于等于5,爆炸

 8049204:       c9                      leave

 8049205:       c3                      ret

入栈eax,ebx 可以看出是两个地址,而 read_six_numbers 可以看出这个关卡的答案是 6 个数字。

phase_2汇编到调用函数之前为以下状况,由此可知 read_six_number 的参数除输入的内容外,还有一个 ebp-0x20,结合后面代码以及考虑到栈中还有很多空间开辟后未使用,可推出读取的六个数字以类似数组形式存储在了 ebp-0x20 开始的连续空间中

可以看出,该题为一个循环。第一个数字要大于0x31即49(10),后续数字需要满足a[i]=(a[i]+a[i]*1)+1

所以,设定第一个数字为50,得到结果:50 101 203 407 815 1631(结果不唯一,第一个数字大于49即可)

成功解除炸弹2!

bomb3:

08048b53 <phase_3>:

 8048b53:       55                      push   %ebp

 8048b54:       89 e5                   mov    %esp,%ebp

 8048b56:       83 ec 28                sub    $0x28,%esp

 8048b59:       8d 45 f0                lea    -0x10(%ebp),%eax//第二个数

 8048b5c:       89 44 24 0c             mov    %eax,0xc(%esp)

 8048b60:       8d 45 f4                lea    -0xc(%ebp),%eax//第一个数

 8048b63:       89 44 24 08             mov    %eax,0x8(%esp)

 8048b67:       c7 44 24 04 f1 a3 04    movl   $0x804a3f1,0x4(%esp)//通过x/s查看为 %d %d

 8048b6e:       08

 8048b6f:       8b 45 08                mov    0x8(%ebp),%eax

 8048b72:       89 04 24                mov    %eax,(%esp)

 8048b75:       e8 66 fc ff ff          call   80487e0 <__isoc99_sscanf@plt>//调用sscanf()

 8048b7a:       83 f8 01                cmp    $0x1,%eax

 8048b7d:       7f 05                  jg     8048b84 <phase_3+0x31>//函数输入参数个数大于1

 8048b7f:       e8 f1 05 00 00          call   8049175 <explode_bomb>//不然爆炸

 8048b84:       83 7d f4 07             cmpl   $0x7,-0xc(%ebp)

 8048b88:       77 1f                   ja     8048ba9 <phase_3+0x56>//大于7爆炸,-0xc(%ebp)数不超过7

 8048b8a:       8b 45 f4                mov    -0xc(%ebp),%eax

 8048b8d:       ff 24 85 c0 a1 04 08    jmp    *0x804a1c0(,%eax,4)//跳转到4*eax+0x804a1c0基址加比例变址->应该是一个switch跳转语句。通过x/s可得基址为98(10)

 8048b94:       b8 72 03 00 00          mov    $0x372,%eax  //0x372->eax

 8048b99:       eb 1f                   jmp    8048bba <phase_3+0x67> //跳转到8048bba

 8048b9b:       b8 44 02 00 00          mov    $0x244,%eax 

 8048ba0:       eb 18                   jmp    8048bba <phase_3+0x67> //

 8048ba2:       b8 a4 03 00 00          mov    $0x3a4,%eax

 8048ba7:       eb 11                   jmp    8048bba <phase_3+0x67> //

 8048ba9:       e8 c7 05 00 00          call   8049175 <explode_bomb>

 8048bae:       b8 00 00 00 00          mov    $0x0,%eax//0->eax

 8048bb3:       eb 30                   jmp    8048be5 <phase_3+0x92>//跳转进行操作

 8048bb5:       b8 16 02 00 00          mov    $0x216,%eax  //eax=0x216

 8048bba:       83 e0 c0                and    $0xffffffc0,%eax //跟踪调试为0x1f5与之与(跳转而来)

 8048bbd:       3b 45 f0                cmp    -0x10(%ebp),%eax //eax此时为0x1c0,查看此时的ebp-0x10中内容就是对应的第二个参数值

 8048bc0:       74 28                   je     8048bea <phase_3+0x97> //相等,则跳出

 8048bc2:       e8 ae 05 00 00          call   8049175 <explode_bomb> //不等,爆炸

 8048bc7:       eb 21                   jmp    8048bea <phase_3+0x97> //跳出

 8048bc9:       b8 f5 01 00 00          mov    $0x1f5,%eax

 8048bce:       66 90                   xchg   %ax,%ax   //交换操作数数据

 8048bd0:       eb e8                   jmp    8048bba <phase_3+0x67>

 8048bd2:       b8 77 03 00 00          mov    $0x377,%eax

 8048bd7:       eb e1                   jmp    8048bba <phase_3+0x67>

 8048bd9:       b8 5c 00 00 00          mov    $0x5c,%eax

 8048bde:       eb 05                   jmp    8048be5 <phase_3+0x92>

 8048be0:       b8 04 01 00 00          mov    $0x104,%eax

 8048be5:       83 e0 7f                and    $0x7f,%eax

 8048be8:       eb d3                   jmp    8048bbd <phase_3+0x6a>

 8048bea:       c9                      leave

 8048beb:       c3                      ret

movl $0x804a3f1,0x4(%esp)//通过x/s查看为 %d %d,获得读取参数

得知,密码应该是两个整数

cmpl $0x7,-0xc(%ebp) 即输入的第一个参数值必须不大于 7。然后看到 jmp    *0x804a1c0(,%eax,4)这是典型的 switch 跳转语句,即跳转到以地址 * 0x804a1c0 为基址的跳转表中。用 x/s*0x804a1c0,读出 switch 跳转基值为0x98

在代码中找到该处指令,得到第一个输入为 1 时对应的第二个输入为 0x1c0, 转换成十进制为 448。经调试后结果正确。



bomb4:

08048bec <func4>:

 8048bec:       55                      push   %ebp

 8048bed:       89 e5                   mov    %esp,%ebp

 8048bef:       56                      push   %esi //函数内临时变量1

 8048bf0:       53                      push   %ebx //函数内临时变量2

 8048bf1:       83 ec 10                sub    $0x10,%esp //开辟空间

 8048bf4:       8b 55 08                mov    0x8(%ebp),%edx //edx->a

 8048bf7:       8b 45 0c                mov    0xc(%ebp),%eax

 8048bfa:       8b 5d 10                mov    0x10(%ebp),%ebx //ebx->b

 8048bfd:       89 d9                   mov    %ebx,%ecx //ecx->c

 8048bff:       29 c1                   sub    %eax,%ecx  // x=c-b (用x代替ebx)*/

 8048c01:       89 ce                   mov    %ecx,%esi  //

 8048c03:       c1 ee 1f                shr    $0x1f,%esi //

 8048c06:       01 f1                   add    %esi,%ecx  //

 8048c08:       d1 f9                   sar    %ecx       //x = (x>>31 + x) >> 1

 8048c0a:       01 c1                   add    %eax,%ecx  //x=[(x>>31 + x) >> 1]+b

 8048c0c:       39 d1                   cmp    %edx,%ecx  //a和x比较

 8048c0e:       7e 17                   jle    8048c27 <func4+0x3b>//a<=x跳转.。。。。。。。。

 8048c10:       83 e9 01                sub    $0x1,%ecx      

 8048c13:       89 4c 24 08             mov    %ecx,0x8(%esp)  //ecx->c

 8048c17:       89 44 24 04             mov    %eax,0x4(%esp) 

 8048c1b:       89 14 24                mov    %edx,(%esp)     //edx->a

 8048c1e:       e8 c9 ff ff ff          call   8048bec <func4>//调用自身(递归)

 8048c23:       01 c0                   add    %eax,%eax

 8048c25:       eb 20                   jmp    8048c47 <func4+0x5b>

 8048c27:       b8 00 00 00 00          mov    $0x0,%eax //eax为返回值

 8048c2c:       39 d1                   cmp    %edx,%ecx //a和x比较

 8048c2e:       7d 17                   jge    8048c47 <func4+0x5b>//a>=转移

 8048c30:       89 5c 24 08             mov    %ebx,0x8(%esp)

 8048c34:       83 c1 01                add    $0x1,%ecx

 8048c37:       89 4c 24 04             mov    %ecx,0x4(%esp)

 8048c3b:       89 14 24                mov    %edx,(%esp)

 8048c3e:       e8 a9 ff ff ff          call   8048bec <func4>//调用自身(递归)

 8048c43:       8d 44 00 01             lea    0x1(%eax,%eax,1),%eax

 8048c47:       83 c4 10                add    $0x10,%esp

 8048c4a:       5b                      pop    %ebx

 8048c4b:       5e                      pop    %esi

 8048c4c:       5d                      pop    %ebp

 8048c4d:       c3                      ret

08048c4e <phase_4>:

 8048c4e:       55                      push   %ebp

 8048c4f:       89 e5                   mov    %esp,%ebp //压栈

 8048c51:       83 ec 28                sub    $0x28,%esp //开辟空间

 8048c54:       8d 45 f0                lea    -0x10(%ebp),%eax 参数num2

 8048c57:       89 44 24 0c             mov    %eax,0xc(%esp) //& [ebp-0x10]->栈

 8048c5b:       8d 45 f4                lea    -0xc(%ebp),%eax 参数num1

 8048c5e:       89 44 24 08             mov    %eax,0x8(%esp) //& [ebp-0xc]->栈

 8048c62:       c7 44 24 04 f1 a3 04    movl   $0x804a3f1,0x4(%esp)// %d,%d

 8048c69:       08

 8048c6a:       8b 45 08                mov    0x8(%ebp),%eax

 8048c6d:       89 04 24                mov    %eax,(%esp)// [val1]->栈

 8048c70:       e8 6b fb ff ff          call   80487e0 <__isoc99_sscanf@plt>//调用sscanf()

 8048c75:       83 f8 02                cmp    $0x2,%eax  //eax中为参数个数

 8048c78:       75 06                   jne    8048c80 <phase_4+0x32>//不等于2跳转爆炸

 8048c7a:       83 7d f4 0e             cmpl   $0xe,-0xc(%ebp)

 8048c7e:       76 05                   jbe    8048c85 <phase_4+0x37>// val1<=0xc

 8048c80:       e8 f0 04 00 00          call   8049175 <explode_bomb>

 8048c85:       c7 44 24 08 0e 00 00    movl   $0xe,0x8(%esp) //func4一个函数参数

 8048c8c:       00

 8048c8d:       c7 44 24 04 00 00 00    movl   $0x0,0x4(%esp) //func4一个函数参数

 8048c94:       00

 8048c95:       8b 45 f4                mov    -0xc(%ebp),%eax//phase_4返回值->eax

 8048c98:       89 04 24                mov    %eax,(%esp) eax->地址为esp的寄存器  

 8048c9b:       e8 4c ff ff ff          call   8048bec <func4> //调用函数func4

 8048ca0:       83 f8 04                cmp    $0x4,%eax //eax中为0x4:func4返回值为0x4

 8048ca3:       75 06                   jne    8048cab <phase_4+0x5d> //不等跳转爆炸

 8048ca5:       83 7d f0 04             cmpl   $0x4,-0x10(%ebp) 参数必须为0x4才能结束

 8048ca9:       74 05                   je     8048cb0 <phase_4+0x62>

 8048cab:       e8 c5 04 00 00          call   8049175 <explode_bomb>

 8048cb0:       c9                      leave

 8048cb1:       c3                      ret

movl   $0x804a3f1,0x4(%esp)//通过x/s查看为 %d %d,获得读取参数为2个

先从我们的输入中获取两个 int 型整数。我们命令为 num1 和 num2。接着判断 sscanf 函数的返回值,如果不等于 2 (输入为2个数)则触发炸弹,否则继续。接下来的几条指令看出[cmpl $0xe,-0xc(%ebp)],num1 必须小于等于 12,否则触发炸弹

接下来调用函数 func4,参数分别为 num1,0 和 14。

cmp    $0x4,%eax检验函数func4()返回值应该为4. cmpl   $0x4,-0x10(%ebp)表明num2应该为0x4.

再关注func4:

可以看到func()中有调用自己,所以为递归函数 且func4 的原型应该是 int func4(int a, int b, int c);根据计算结果,反推c语言代码如下:

要其返回值为4,所以可以得到num1应该为2

所以该题结果为2  4

bomb5:

08048cb2 <phase_5>:

 8048cb2:       55                      push   %ebp

 8048cb3:       89 e5                   mov    %esp,%ebp

 8048cb5:       53                      push   %ebx

 8048cb6:       83 ec 14                sub    $0x14,%esp

 8048cb9:       8b 5d 08                mov    0x8(%ebp),%ebx//输入的数num1

 8048cbc:       89 1c 24                mov    %ebx,(%esp)

 8048cbf:       e8 6c 02 00 00          call   8048f30 <string_length>//猜测字符串长度

 8048cc4:       83 f8 06                cmp    $0x6,%eax

 8048cc7:       74 05                   je     8048cce <phase_5+0x1c> //字符串长度为6

 8048cc9:       e8 a7 04 00 00          call   8049175 <explode_bomb>

 8048cce:       ba 00 00 00 00          mov    $0x0,%edx

 8048cd3:       b8 00 00 00 00          mov    $0x0,%eax

 8048cd8:       0f b6 0c 03           movzbl (%ebx,%eax,1),%ecx //一个字节->双字 ebx+eax->ecx【对num1进行扩展为32位】

 8048cdc:       83 e1 0f                and    $0xf,%ecx   //保留后四位,前28位变为0

 8048cdf:       03 14 8d e0 a1 04 08    add    0x804a1e0(,%ecx,4),%edx //基址+寄存器寻址

 8048ce6:       83 c0 01                add    $0x1,%eax  //猜测eax为字符串数组的下标

 8048ce9:       83 f8 06                cmp    $0x6,%eax (循环6次)

 8048cec:       75 ea                   jne    8048cd8 <phase_5+0x26>

 8048cee:       83 fa 2e                cmp    $0x2e,%edx//返回值要为0x2e即46

 8048cf1:       74 05                   je     8048cf8 <phase_5+0x46>

 8048cf3:       e8 7d 04 00 00          call   8049175 <explode_bomb>

 8048cf8:       83 c4 14                add    $0x14,%esp

 8048cfb:       5b                      pop    %ebx

 8048cfc:       5d                      pop    %ebp

 8048cfd:       c3                      ret

由题意可以得知为一个6个字符的字符串

循环段读取含义为分别截取每个字符的后四位放入ecx,将其作为偏移量,将0x804a1e0+(ecx*4)加入edx。6次循环后,edx中的值应该等于0x2e,即(46)10。

 

查看0x804a1e0开始的连续字符(32位)

可得到当选中如下数据最后和为0x2e。则偏移量ecx应该分别为(0x):1 2 4 6 8 B.即选取字符串的6个字符ascii码的二进制编码后4位需要满足上面的关系。所以,取a(0x61),b(0x62),d(0x64),f(0x66),h(0x68),k(0x6B)

运行检验运行,答案正确。

bomb6:

08048cfe <phase_6>:

 8048cfe:       55                      push   %ebp

 8048cff:       89 e5                   mov    %esp,%ebp

 8048d01:       56                      push   %esi

 8048d02:       53                      push   %ebx

 8048d03:       83 ec 40                sub    $0x40,%esp

 8048d06:       8d 45 e0                lea    -0x20(%ebp),%eax  /eax=num/

 8048d09:       89 44 24 04             mov    %eax,0x4(%esp)

 8048d0d:       8b 45 08                mov    0x8(%ebp),%eax

 8048d10:       89 04 24                mov    %eax,(%esp)

 8048d13:       e8 9f 04 00 00          call   80491b7 <read_six_numbers> //读6个数

 8048d18:       be 00 00 00 00          mov    $0x0,%esi

 8048d1d:       8b 44 b5 e0        mov    -0x20(%ebp,%esi,4),%eax  //   a[esi]->eax

 8048d21:       83 e8 01                sub    $0x1,%eax  //eax=a[i]-1

 8048d24:       83 f8 05                cmp    $0x5,%eax

 8048d27:       76 05                   jbe    8048d2e <phase_6+0x30> 

 8048d29:       e8 47 04 00 00          call   8049175 <explode_bomb> //保证num[esi]<=5

 8048d2e:       83 c6 01                add    $0x1,%esi 

 8048d31:       83 fe 06                cmp    $0x6,%esi  //esi为计数器(循环6次)

 8048d34:       74 1c                   je     8048d52 <phase_6+0x54>

 8048d36:       89 f3                   mov    %esi,%ebx

 8048d38:       8b 44 9d e0             mov    -0x20(%ebp,%ebx,4),%eax //ebx=esi+1,eax=a[ebx]

 8048d3c:       39 44 b5 dc             cmp    %eax,-0x24(%ebp,%esi,4)

 8048d40:       75 05                   jne    8048d47 <phase_6+0x49>

 

这里控制6个数据都互不相同(对所有进行扫描保证不同)

 8048d42:       e8 2e 04 00 00          call   8049175 <explode_bomb>//确保num[ebx]!=num[esi]即两个相邻的数不相等

 

 8048d47:       83 c3 01                add    $0x1,%ebx

 8048d4a:       83 fb 05                cmp    $0x5,%ebx

 8048d4d:       7e e9                   jle    8048d38 <phase_6+0x3a>

 8048d4f:       90                      nop

 8048d50:       eb cb                   jmp    8048d1d <phase_6+0x1f>

 8048d52:       8d 45 e0                lea    -0x20(%ebp),%eax  /eax=num/

 8048d55:       8d 5d f8                lea    -0x8(%ebp),%ebx   /ebx=p/

 8048d58:       b9 07 00 00 00          mov    $0x7,%ecx      //ecx=7

 8048d5d:       89 ca                   mov    %ecx,%edx   

 8048d5f:       2b 10                   sub    (%eax),%edx 

 8048d61:       89 10                   mov    %edx,(%eax) 

 8048d63:       83 c0 04                add    $0x4,%eax    //eax=p-num+0x4

 8048d66:       39 d8                   cmp    %ebx,%eax

 8048d68:       75 f3                  jne    8048d5d <phase_6+0x5f> //p(ebx)不指向eax继续计算

 8048d6a:       bb 00 00 00 00          mov    $0x0,%ebx

 8048d6f:       eb 1d                   jmp    8048d8e <phase_6+0x90> //p(ebx)指向eax

 

 8048d71:       8b 52 08                mov    0x8(%edx),%edx

 8048d74:       83 c0 01                add    $0x1,%eax

 8048d77:       39 c8                   cmp    %ecx,%eax  ecp->指向其next

 8048d79:       75 f6                   jne    8048d71 <phase_6+0x73> //不等重新计算

 8048d7b:       eb 05                   jmp    8048d82 <phase_6+0x84> //等于则跳转

 8048d7d:       ba 54 c1 04 08          mov    $0x804c154,%edx

 8048d82:       89 54 b5 c8             mov    %edx,-0x38(%ebp,%esi,4)

 8048d86:       83 c3 01                add    $0x1,%ebx               //ebx+=1

 8048d89:       83 fb 06                cmp    $0x6,%ebx

 8048d8c:       74 17                   je     8048da5 <phase_6+0xa7>//6个元素之间链表建立成功,则跳转下一步。

 8048d8e:       89 de                   mov    %ebx,%esi

 8048d90:       8b 4c 9d e0             mov    -0x20(%ebp,%ebx,4),%ecx /ecx=p->next /

 8048d94:       83 f9 01                cmp    $0x1,%ecx   

 

这里为对6个元素建立链表部分

 8048d97:       7e e4                   jle    8048d7d <phase_6+0x7f> //指向不正确,重新计算

 

 8048d99:       b8 01 00 00 00          mov    $0x1,%eax

 8048d9e:       ba 54 c1 04 08          mov    $0x804c154,%edx

 8048da3:       eb cc                   jmp    8048d71 <phase_6+0x73>

 

 8048da5:       8b 5d c8                mov    -0x38(%ebp),%ebx

 8048da8:       8d 45 cc                lea    -0x34(%ebp),%eax

 8048dab:       8d 75 e0                lea    -0x20(%ebp),%esi

 8048dae:       89 d9                   mov    %ebx,%ecx

 8048db0:       8b 10                   mov    (%eax),%edx

 8048db2:       89 51 08                mov    %edx,0x8(%ecx)

 8048db5:       83 c0 04                add    $0x4,%eax

 8048db8:       39 f0                   cmp    %esi,%eax

 8048dba:       74 04                   je     8048dc0 <phase_6+0xc2>

 8048dbc:       89 d1                   mov    %edx,%ecx

 8048dbe:       eb f0                   jmp    8048db0 <phase_6+0xb2>

 8048dc0:       c7 42 08 00 00 00 00    movl   $0x0,0x8(%edx)

 8048dc7:       be 05 00 00 00          mov    $0x5,%esi

 8048dcc:       8b 43 08                mov    0x8(%ebx),%eax eax=ebx->next

 8048dcf:       8b 00                   mov    (%eax),%eax

 8048dd1:       39 03                   cmp    %eax,(%ebx) 比较eax和ebx->value

 8048dd3:       7d 05                   jge    8048dda <phase_6+0xdc>

 8048dd5:       e8 9b 03 00 00         call   8049175 <explode_bomb>//链表元素出现升序,爆炸【即排列好的数据要完全降序排列】

 8048dda:       8b 5b 08                mov    0x8(%ebx),%ebx

 8048ddd:       83 ee 01                sub    $0x1,%esi

 8048de0:       75 ea                   jne    8048dcc <phase_6+0xce>

 8048de2:       83 c4 40                add    $0x40,%esp

 8048de5:       5b                      pop    %ebx

 8048de6:       5e                      pop    %esi

 8048de7:       5d                      pop    %ebp

 8048de8:       c3                      ret

输入假设样例1 2 3 4 5 6

用 gdb 查看 0x804c154 附近的内容:

可以确定结构由三个元素组成, 两个整形数据, 一个结构类型的指针, 重复操作可以发现这是一个有 6 个元素的链表, 称此结构为 node

读取顺序为从后往前,此时的链表为:

node6-> node5-> node4-> node3-> node2-> node1-> NULL 

typedef struct node{

    int value;

    int idx;

struct node *next;

}node;

node node1={0x27e,   1,   NULL,   0x73};

node node2={0x73,    2,   &node1,     0x3d3};

node node3={0x3d3,   3,   &node2,     0x1ab};

node node4={0x1ab,   4,   &node3,   0x255};

node node5={0x255,   5,   &node4,   0x248};

node node6={0x248,   6,   &node5,   0x00};

分析代码为:对其按照value值0x3d3,0x255,0x27e,0x1ab,0x248,0x73由大到小排序,重新链接得到链表如下,C语言代码如下:

node3-> node1-> node5-> node6-> node4-> node2-> NULL

从后往前找最大,放在加入链表,形成降序排列。

从6--à1找,最大的0x3d3为最大,是第四个,次大之0x27e为第6个。。。。以此类推

所以,num=4 6 2 1 3 5

隐藏关:

进入方法:

搜索整个汇编代码, 发现只在 phase_defuse 函数中调用过 secret_phase 函数, 所以先分析这个函数.

0804933e <phase_defused>:

 804933e:       55                      push   %ebp

 804933f:       89 e5                   mov    %esp,%ebp

 8049341:       81 ec 88 00 00 00       sub    $0x88,%esp

 8049347:       c7 04 24 01 00 00 00    movl   $0x1,(%esp)

 804934e:       e8 4b fd ff ff          call   804909e <send_msg>

 8049353:       83 3d e8 c7 04 08 06    cmpl   $0x6,0x804c7e8 //

 804935a:       75 7a                   jne    80493d6 <phase_defused+0x98>

 804935c:       8d 45 a8                lea    -0x58(%ebp),%eax

 804935f:       89 44 24 10             mov    %eax,0x10(%esp)

 8049363:       8d 45 a0                lea    -0x60(%ebp),%eax

 8049366:       89 44 24 0c             mov    %eax,0xc(%esp)

 804936a:       8d 45 a4                lea    -0x5c(%ebp),%eax

 804936d:       89 44 24 08             mov    %eax,0x8(%esp)

 8049371:       c7 44 24 04 4b a4 04    movl   $0x804a44b,0x4(%esp)

 8049378:       08

 8049379:       c7 04 24 f0 c8 04 08    movl   $0x804c8f0,(%esp)

 8049380:       e8 5b f4 ff ff          call   80487e0 <__isoc99_sscanf@plt>

 8049385:       83 f8 03                cmp    $0x3,%eax

 8049388:       75 34                   jne    80493be <phase_defused+0x80>

 804938a:       c7 44 24 04 54 a4 04    movl   $0x804a454,0x4(%esp)

 8049391:       08

 8049392:       8d 45 a8                lea    -0x58(%ebp),%eax

 8049395:       89 04 24                mov    %eax,(%esp)

 8049398:       e8 b5 fb ff ff          call   8048f52 <strings_not_equal>

 804939d:       85 c0                   test   %eax,%eax

 804939f:       75 1d                  jne    80493be <phase_defused+0x80>//不匹配跳过隐藏关

 80493a1:       c7 04 24 a0 a2 04 08    movl   $0x804a2a0,(%esp)

 80493a8:       e8 d3 f3 ff ff          call   8048780 <puts@plt>

 80493ad:       c7 04 24 c8 a2 04 08    movl   $0x804a2c8,(%esp)

 80493b4:       e8 c7 f3 ff ff          call   8048780 <puts@plt>

 80493b9:       e8 7e fa ff ff          call   8048e3c <secret_phase>

 80493be:       c7 04 24 00 a3 04 08    movl   $0x804a300,(%esp)

 80493c5:       e8 b6 f3 ff ff          call   8048780 <puts@plt>

 80493ca:       c7 04 24 2c a3 04 08    movl   $0x804a32c,(%esp)

 80493d1:       e8 aa f3 ff ff          call   8048780 <puts@plt>

 80493d6:       c9                      leave

 80493d7:       c3                      ret

 80493d8:       66 90                   xchg   %ax,%ax

 80493da:       66 90                   xchg   %ax,%ax

 80493dc:       66 90                   xchg   %ax,%ax

 80493de:       66 90                   xchg   %ax,%ax

在 phase_defused 函数中有 cmpl   $0x6,0x804c7e8 语句, 搜索 0x804c7e8 发现这个内存的值在每读入一条字符串后就会加 1,

则显然 secret_phase 是在第 6 条字符串之后输入. 又发现 cmp    $0x3,%eax, 语句, 此时的 %eax 是 sscanf 读取的参数个数。sscanf 读取的参数格式保存在0x804a44b 位置处, 为 "%d %d %s", 待读取的参数存放在 0x804c8f0 内存处,

用 x/s 0x804b770 看时发现这个内存位置的字符串为 " ", 什么都没有, 从后面的调用
strings_not_equal 来看, 还要读入的字符保存在0x804a454 中, 查看为DrEvil

查看0x804a2a0发现提示:

之后在前面结果中插入DrEvil测试,发现在phase_4这样就可以正确执行到 secret_phase 函数调用位置处了.

08048e3c <secret_phase>:

 8048e3c:       55                      push   %ebp

 8048e3d:       89 e5                   mov    %esp,%ebp

 8048e3f:       53                      push   %ebx

 8048e40:       83 ec 14                sub    $0x14,%esp

 8048e43:       e8 be 03 00 00          call   8049206 <read_line>//读取一行

 8048e48:       c7 44 24 08 0a 00 00    movl   $0xa,0x8(%esp)

 8048e4f:       00

 8048e50:       c7 44 24 04 00 00 00    movl   $0x0,0x4(%esp)

 8048e57:       00

 8048e58:       89 04 24                mov    %eax,(%esp) //eax为read_line()返回值

 8048e5b:       e8 e0 f9 ff ff          call   8048840 <strtol@plt>//返回值 %eax 作为函数 <strtol@plt> 的参数之一,另外两个参数分别是 0xa 和 0x0

 8048e60:       89 c3                   mov    %eax,%ebx

 8048e62:       8d 40 ff                lea    -0x1(%eax),%eax /*

 8048e65:       3d e8 03 00 00          cmp    $0x3e8,%eax  

 8048e6a:       76 05                   jbe    8048e71 <secret_phase+0x35>

 8048e6c:       e8 04 03 00 00          call   8049175 <explode_bomb>输入的十进制数要小于等于 1001*/

 8048e71:       89 5c 24 04             mov    %ebx,0x4(%esp)

 8048e75:       c7 04 24 a0 c0 04 08    movl   $0x804c0a0,(%esp)

 8048e7c:       e8 68 ff ff ff          call   8048de9 <fun7>

//随后将所输入的数作为 <fun7> 的参数之一。另外一个参数来自 0x804c178,查看为 0x55。

 8048e81:       83 f8 05                cmp    $0x5,%eax

 8048e84:       74 05                   je     8048e8b <secret_phase+0x4f>

 8048e86:       e8 ea 02 00 00          call   8049175 <explode_bomb>

 8048e8b:       c7 04 24 94 a1 04 08    movl   $0x804a194,(%esp)

 8048e92:       e8 e9 f8 ff ff          call   8048780 <puts@plt>

 8048e97:       e8 a2 04 00 00          call   804933e <phase_defused>

 8048e9c:       83 c4 14                add    $0x14,%esp

 8048e9f:       5b                      pop    %ebx

 8048ea0:       5d                      pop    %ebp

 8048ea1:       c3                      ret

 8048ea2:       66 90                   xchg   %ax,%ax

 8048ea4:       66 90                   xchg   %ax,%ax

 8048ea6:       66 90                   xchg   %ax,%ax

 8048ea8:       66 90                   xchg   %ax,%ax

 8048eaa:       66 90                   xchg   %ax,%ax

 8048eac:       66 90                   xchg   %ax,%ax

 8048eae:       66 90                   xchg   %ax,%ax

08048de9 <fun7>:

 8048de9:       55                      push   %ebp

 8048dea:       89 e5                   mov    %esp,%ebp

 8048dec:       53                      push   %ebx

 8048ded:       83 ec 14                sub    $0x14,%esp

 8048df0:       8b 55 08                mov    0x8(%ebp),%edx  // 第一个参数 A

 8048df3:       8b 4d 0c                mov    0xc(%ebp),%ecx   // 第二个参数 B 即输入

 8048df6:       85 d2                   test   %edx,%edx       

 8048df8:       74 37                   je     8048e31 <fun7+0x48>// 递归终止,返回 %edx=0

 8048dfa:       8b 1a                   mov    (%edx),%ebx

 8048dfc:       39 cb                   cmp    %ecx,%ebx

 8048dfe:       7e 13                   jle    8048e13 <fun7+0x2a>// 若 * A>b,将 (A+4) 作为地址进入递归

 8048e00:       89 4c 24 04             mov    %ecx,0x4(%esp)

 8048e04:       8b 42 04                mov    0x4(%edx),%eax

 8048e07:       89 04 24                mov    %eax,(%esp)

 8048e0a:       e8 da ff ff ff          call   8048de9 <fun7>//递归

 8048e0f:       01 c0                   add    %eax,%eax  //递归返回值加倍

 8048e11:       eb 23                   jmp    8048e36 <fun7+0x4d>

 8048e13:       b8 00 00 00 00          mov    $0x0,%eax

 8048e18:       39 cb                   cmp    %ecx,%ebx

 8048e1a:       74 1a                   je     8048e36 <fun7+0x4d>// 若 * A<B,将 (A+8) 作为地址进入递归

 8048e1c:       89 4c 24 04             mov    %ecx,0x4(%esp)

 8048e20:       8b 42 08                mov    0x8(%edx),%eax

 8048e23:       89 04 24                mov    %eax,(%esp)

 8048e26:       e8 be ff ff ff          call   8048de9 <fun7>

// 在此处将递归返回值加倍后在加 1

 8048e2b:       8d 44 00 01             lea    0x1(%eax,%eax,1),%eax

 8048e2f:       eb 05                   jmp    8048e36 <fun7+0x4d>

 8048e31:       b8 ff ff ff ff          mov    $0xffffffff,%eax

 8048e36:       83 c4 14                add    $0x14,%esp

 8048e39:       5b                      pop    %ebx

 8048e3a:       5d                      pop    %ebp

 8048e3b:       c3                      ret

在调用完 <fun7> 之后,紧跟着 cmp   $0x5,%eax,即返回值必须为 5。<fun7> 分析如上,为递归函数,与第四题十分相似。递归最深处的返回值肯定为 0,最外层返回值为 5,可得出如下反递归过程:

A*2+1=5 - ->A=2    即有 * A<B

A*2=2  -->A=1    有 * A>B

A*2+1=1 - ->A=0    即有 * A<B

也就是说在这三次递归中两次执行了 “若 * A<B 将(A+8) 作为地址进入递归”系列代码,一次执行了 “若 * A>b,将(A+4) 作为地址进入递归”系列代码。使用 gdb 查询储存值:

最后得到 0x2f,即使我们要输入的十进制值 47。

运行结果,找出了所有关的答案:

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

bomblab实验-bomb1~6and隐藏关 的相关文章

  • 网站迁移或者调整页面链接的方法

    背景 这两天我在重新规划我的博客网站逐步前行STEP 将改版导航以及整体内容结构 将单纯的博客网站打造成集博客 资讯 工具 社区于一体的综合站点 这必然涉及到要重新规划原有的路由 直接修改路由将导致搜索引擎收录的链接或者访客收藏的网址失效
  • UNIX网络编程卷一 学习笔记 第十一章 名字与地址转换

    到目前为止 本书中所有例子都用数值地址表示主机 如206 6 226 33 用数值端口号来标识服务器 如端口13代表daytime服务器 但出于某些理由 我们应使用名字而非数值 名字比较容易记住 数值地址可以变动而名字保持不变 随着往IPv
  • ajax基础

    ajax基础 ajax get ajax post ajax get query ajax post body ajax post 用户注册 ajax post 用户登陆 ajax get h1 这是第一个ajax网页 h1
  • OpenMMLab实战营第四课:目标检测与MMDetection

    什么是目标检测 目标检测应用 目标检测vs图像分类 滑窗 Sliding Window 简介 设定一个固定大小的窗口 遍历图像所有位置 所到之处用分类模型 假设已经训练好 识别窗口中的内容 为了检测不同大小 不同形状的物体 可以使用不同大小
  • mseloss pytorch_PyTorch现的一个简单线性回归的样例

    线性回归基本概念 线性回归是利用数理统计中的回归分析来确定两种或两种以上变量间相互依赖的定量关系的一种统计分析方法 表达形式为y wx e 其中e为误差服从均值为0的正态分布 回归分析中 只包括一个自变量和一个因变量 且二者的关系可用一条直
  • java list 和数组区别_java list和数组的区别

    展开全部 List和ArrayList的区别在于 1 在编程语言中ArrayList类是 Net Framework提供的用于数据存储和检索的专用类 List 类可以简单视之为双向62616964757a686964616fe78988e6
  • ClickHouse之常见的时间周期函数

    文章目录 前言 时区相关 timeZone toTimeZone timeZoneOf 年相关 toYear toStartOfYear toStartOfISOYear toRelativeYearNum toISOYear 季度相关 t
  • VS2008解决“MSVCRT”与其他库的使用冲突的警告

    警告信息如下 1 gt LINK warning LNK4098 默认库 MSVCRT 与其他库的使用冲突 请使用 NODEFAULTLIB library 原因 在使用多线程调试dll MDd 模式的时候 lt 位置 配置属性 c c 代
  • 如何将github项目上传至gitlab

    一 修改远程分支关联 删除远程分支关联 将指向github的远程分支关联关系删除 git remote rm origin 添加新的远程分支关联 新的remote地址指向gitlab相应地址 git remote add origin lt
  • 【中文】【吴恩达课后编程作业】Course 4 - 卷积神经网络 - 第二周作业

    中文 吴恩达课后编程作业 Course 4 卷积神经网络 第二周作业 Keras入门与残差网络的搭建 上一篇 课程4 第二周测验 回到目录 下一篇 课程4 第三周测验 资料下载 下载1 本文所使用的资料已上传到百度网盘 点击下载 15 97
  • 【小程序】为什么使用let that=this

    this 会随着上下文环境而变换它的指向 在当前作用域中设置一个变量用来存储 this 可以防止在其他地方找不到 this 的错误 一般情况 举个例子 btn click function var that this 这里this和that
  • react项目:react拦截器和token问题

    登录获取token后 如何对后面的接口统一在请求头header里面设置token 让后面的请求header都带有token axios拦截器 interceptor 作用 当一个请求发出的时候 会先流过 interceptors 的 req
  • virtualbox禁用硬件虚拟化_Mac版Virtualbox6.1开启嵌套虚拟化

    Virtualbox从6 0版本后 支持起了Intel cpu的嵌套虚拟化 很多用Virtualbox的朋友开始陷入了茫然 为何在BIOS或EFI中开启了CPU硬件虚拟化后 Virtualbox中的vm菜单中启用嵌套虚拟化的框还是灰色不可用
  • 我一下子说出4种分布式ID生成方案,把面试官给搞懵了!

    V xin ruyuanhadeng获得600 页原创精品文章汇总PDF 上一篇文章 我们聊了一下分库分表相关的一些基础知识 具体可以参见 支撑日活百万用户的高并发系统 应该如何设计其数据库架构 这篇文章 我们就接着分库分表的知识 来具体聊
  • 在Cocos2dX游戏中使用Lua脚本进行游戏开发(基础篇)

    对于游戏公司而言 采用游戏脚本lua python等进行开发也很常见 但是很多童鞋对脚本并没有很熟悉的概念 本篇则向大家简单介绍脚本的用途以及在Cocos2dx基础用法 Lua和python这些详细介绍的话 请不太熟悉的童鞋自行百度百科哈
  • 50道SQL练习题及答案与详细分析:

    流传较广的50道SQL训练 奋斗了不知道多久终于写完了 前18道题的难度依次递增 从19题开始的后半部分算是循环练习和额外function的附加练习 难度恢复到普通状态 第9题非常难 我反正没有写出来 如果有写出来了的朋友还请赐教 这50道
  • 教育平台的线上课程智能推荐策略

    题目来自 http www tipdm org 一 背景 近年来 随着互联网与通信技术的高速发展 学习资源的建设与共享呈现出 新的发展趋势 各种网课 慕课 直播课等层出不穷 各种在线教育平台和学习 应用纷纷涌现 尤其是 2020 年春季学期

随机推荐

  • 用Python学习吴恩达机器学习——梯度下降算法理论篇

    开篇词 CSDN专供 欢迎阅读我的文章 本文起先是在B站上进行投稿 一开始是采用吴恩达机器学习2012年版的 目前已经出了十二期了 现在我决定将我摸索出来的学习笔记在各个平台上进行连载 保证同时更新 半年已过 谁知道AI领域已发生很大的变数
  • ajax获取500,使用Python请求库500获取Ajax Json输出

    import requests import json class Yurtici object baseUrl http www yurticikargo com ajaxRoot1 layouts ArikanliHolding Yur
  • 模板之特化与偏特化

    C 模板 C 模板提供了对逻辑结构相同的数据对象通用行为的定义 这些模板运算对象的类型不是实际的数据类型 而是一种参数化的类型 C 模板分为类模板和函数模板那 类模板示例 template
  • MySQL的binlog功能详解

    什么是binlog binlog日志用于记录所有更新了数据或者已经潜在更新了数据 例如 没有匹配任何行的一个DELETE 的所有语句 语句以 事件 的形式保存 它描述数据更改 binlog作用 因为有了数据更新的binlog 所以可以用于实
  • MySQL主从复制

    1 基础环境配置 1 修改主机名 使用hostnamectl命令修改2台主机的主机名 root localhost hostnamectl set hostname db1 root localhost bash root db1 root
  • 干货-YOLOv5检测烟火

    火灾是一种常见的自然灾害和事故 经常给人们的生命财产安全带来威胁 在人力无法及时发现火灾的情况下 火势可能迅速扩散 造成不可挽回的损失 因此 及时发现火灾并采取有效的救援措施至关重要 利用计算机视觉技术检测火灾具有以下意义 提高火灾检测效率
  • 深入理解Socket套接字:必要的参数详解

    深入理解Socket套接字 必要的参数详解 文章目录 深入理解Socket套接字 必要的参数详解 引言 1 1 简介 1 2 Socket套接字的作用 Socket套接字的创建 2 1 Socket函数 2 2 Socket函数参数详解 S
  • 完美的mysql备份脚本

    转自 https www cnblogs com leffss p 7832047 html bin bash 全备方式 一般在从机上执行 适用于小中型mysql数据库 删除15天以前备份 作者 fafu li 时间 2015 08 10
  • 【全栈开发指南】OAuth2授权获取token调试接口的方式

    在我们实际应用接口的调用调试过程中 需要用到token或者刷新token GitEgg支持OAuth2 0协议进行认证授权 这里介绍说明如何通过Postman获取token和refresh token并进行接口调试 1 使用密码模式获取to
  • win10禁用windows更新

    Windows 10系统中有一项Update Orchestrator Service 更新协调器办事 在当地办事窗口中 我们发现 Update Orchestrator Service 状态的启动类型为灰色 无法进行点击修改 2 禁用Wi
  • ESB产品Oracle数据库升级说明

    ESB企业服务总线平台作为支撑企业综合集成的产品 在应用集成 数据集成 数据治理等解决方案都发挥着非常重要的作用 随着产品和解决方案的不断优化和升级 ESB企业服务总线平台功能需要逐步进行完善 不断提升产品功能的完备性 易用性和全面性 为了
  • 类和对象

    面向对象 类和对象 数据存储方面 变量 只能存储一个 如果内容多了 存储起来需要定义n个变量 麻烦 数组 可以存储一组相同数据类型的数据 数据类型相同 如果用数组存储一个人的信息 比较丰富的信息的话 不太方便 例如 吃货联盟中存储订单和菜品
  • Flowable-ui-modeler和MybatisPlus冲突问题

    启动出现报错 file F code test flowable boot target classes com example flowableboot flowable mapper ProcessModelMapper class r
  • 目录功能详解

    bin usr bin usr local bin 是Binary的缩写 这个目录存放着最经常使用的命令 sbin usr sbin usr local sbin s就是Super User的意思 这里存放的是系统管理员使用的系统管理程序
  • SpringBoot配置多个Redis集群数据源+自定义缓存注解实例

    今天找了半天没找到线程的 网上都是多个Redis示例 最还还是自己想办法实现了 两个Redis集群作为数据源 自定义缓存注解 不会做的是否发现好tm难 都不知道怎么动手 做完之后 发现原理其实特别简单 很容易就能实现 分两部分原理和示例代码
  • 使用pycharm传入初始化环境配置参数(Run configuration)

    在run gt edit configurations 选择项目并填写参数
  • td 字典表_字典表设计

    为什么字典表 存在问题 某些变量在多个地方使用 而且一般是固定的 但是随着系统升级和后期变化 可能需要改变 如果这些变量写死在代码里面将会变得难以维护 所以要将其从代码中抽离出来 一般的业务系统客户端与用户交互的时候都会使用下拉框组件 对于
  • day2作业

    1 列举出3种常见的操作系统 答 操作系统 windows ubuntu MacOS 其内核 windowsNT Linux uniux 2 简述Ubuntu和Linux的关系 答 Ubuntu 乌班图 是一个以桌面应用为主的Linux操作
  • 数据结构C语言版——初始化一个线性表

    问题描述 初始化一个线性表 程序代码 include stdio h include stdlib h define OVERFLOW 0 define OK 1 define LIST INIT SIZE 100 define LISTI
  • bomblab实验-bomb1~6and隐藏关

    bomb1 08048ae0