做的是bomb2,一共有大概40多个,简要记录一下
环境:ubuntu14.04,32bit
phase1:
08048b80 <phase_1>:
8048b80: 55 push %ebp
8048b81: 89 e5 mov %esp,%ebp
8048b83: 83 ec 08 sub $0x8,%esp
8048b86: c7 44 24 04 98 99 04 movl $0x8049998,0x4(%esp)
8048b8d: 08
8048b8e: 8b 45 08 mov 0x8(%ebp),%eax
8048b91: 89 04 24 mov %eax,(%esp)
8048b94: e8 3e 05 00 00 call 80490d7 <strings_not_equal>
8048b99: 85 c0 test %eax,%eax
8048b9b: 74 05 je 8048ba2 <phase_1+0x22>
8048b9d: e8 fc 0a 00 00 call 804969e <explode_bomb>
8048ba2: c9 leave
8048ba3: c3 ret
主要是画出内存栈的结构来就很好理解,phase1()从ebp+8取输入参数,结合bomb.c来看
input = read_line(); /* Get input */
phase_1(input); /* Run the phase */
phase_defused(); /* Drat! They figured it out!
phase1函数栈的上一个栈是read_line()函数,即phase1将readline读取的键盘输入存入(esp),在(esp+4)位置存入0x8049998,然后将这两个参数传给strings_not_equal().
这个函数用于比较传入两个参数arg和(0x8049998),arg是用户输入,(0x8049998)存放着string,用命令:
(gdb) x/s 0x8049998
将该字符串输出得:You are the Diet Coke of evil, just one calorie, not evil enough.
即为第一关答案
phase2:
08048ba4 <phase_2>:
8048ba4: 55 push %ebp
8048ba5: 89 e5 mov %esp,%ebp
8048ba7: 83 ec 28 sub $0x28,%esp
8048baa: 8d 45 e4 lea -0x1c(%ebp),%eax
8048bad: 89 44 24 04 mov %eax,0x4(%esp)
8048bb1: 8b 45 08 mov 0x8(%ebp),%eax
8048bb4: 89 04 24 mov %eax,(%esp)
8048bb7: e8 88 04 00 00 call 8049044 <read_six_numbers>
8048bbc: 8b 45 e4 mov -0x1c(%ebp),%eax
8048bbf: 83 f8 01 cmp $0x1,%eax
8048bc2: 74 05 je 8048bc9 <phase_2+0x25>
8048bc4: e8 d5 0a 00 00 call 804969e <explode_bomb>
8048bc9: c7 45 fc 01 00 00 00 movl $0x1,-0x4(%ebp) # i=1
8048bd0: eb 22 jmp 8048bf4 <phase_2+0x50>
8048bd2: 8b 45 fc mov -0x4(%ebp),%eax #x=i
8048bd5: 8b 4c 85 e4 mov -0x1c(%ebp,%eax,4),%ecx #find a[x]
8048bd9: 8b 45 fc mov -0x4(%ebp),%eax
8048bdc: 48 dec %eax # x--
8048bdd: 8b 54 85 e4 mov -0x1c(%ebp,%eax,4),%edx #find a[x-1]
8048be1: 8b 45 fc mov -0x4(%ebp),%eax #resume x
8048be4: 40 inc %eax # x++
8048be5: 0f af c2 imul %edx,%eax #a[x-1]*(x+1)
8048be8: 39 c1 cmp %eax,%ecx
8048bea: 74 05 je 8048bf1 <phase_2+0x4d> #if a[x-1]*(x+1) == a[x]
8048bec: e8 ad 0a 00 00 call 804969e <explode_bomb>
8048bf1: ff 45 fc incl -0x4(%ebp) #i++
8048bf4: 83 7d fc 05 cmpl $0x5,-0x4(%ebp)
8048bf8: 7e d8 jle 8048bd2 <phase_2+0x2e>
8048bfa: c9 leave
8048bfb: c3 ret
发现使用Imm(Eb,Ei,s)的形式访存(CSAPP,2ed,中文版p113),确定是数组,首先a[0]=1,判断是否满足a[1]=2a[0],a[2]=3a[1],...,a[5]=6a[4]
于是得出a1~a6为1,2,6,24,120,720
phase3:
08048bfc <phase_3>:
8048bfc: 55 push %ebp
8048bfd: 89 e5 mov %esp,%ebp
8048bff: 83 ec 28 sub $0x28,%esp
8048c02: c7 45 f8 00 00 00 00 movl $0x0,-0x8(%ebp)
8048c09: c7 45 fc 00 00 00 00 movl $0x0,-0x4(%ebp)
8048c10: 8d 45 f0 lea -0x10(%ebp),%eax
8048c13: 89 44 24 0c mov %eax,0xc(%esp)
8048c17: 8d 45 f4 lea -0xc(%ebp),%eax
8048c1a: 89 44 24 08 mov %eax,0x8(%esp)
8048c1e: c7 44 24 04 da 99 04 movl $0x80499da,0x4(%esp)
8048c25: 08
8048c26: 8b 45 08 mov 0x8(%ebp),%eax
8048c29: 89 04 24 mov %eax,(%esp)
8048c2c: e8 37 fc ff ff call 8048868 <sscanf@plt> #input a string,output its length
8048c31: 89 45 fc mov %eax,-0x4(%ebp) # eax= return value of sscanf (string length)
8048c34: 83 7d fc 01 cmpl $0x1,-0x4(%ebp) #compare 1 with length
8048c38: 7f 05 jg 8048c3f <phase_3+0x43> #如果参数个数<=1,boom
8048c3a: e8 5f 0a 00 00 call 804969e <explode_bomb>
8048c3f: 8b 45 f4 mov -0xc(%ebp),%eax
8048c42: 89 45 ec mov %eax,-0x14(%ebp) #get num1
8048c45: 83 7d ec 07 cmpl $0x7,-0x14(%ebp)
8048c49: 77 54 ja 8048c9f <phase_3+0xa3> #if num1>7,boom
8048c4b: 8b 55 ec mov -0x14(%ebp),%edx #switch(num1)语句,num1作为偏移量
8048c4e: 8b 04 95 e0 99 04 08 mov 0x80499e0(,%edx,4),%eax #计算地址p=(0x80499e0+num1*4) num1=0时,p=(0x80499e0)=0x8048c57
8048c55: ff e0 jmp *%eax #jmp *表示跳转到绝对地址
8048c57: c7 45 f8 d7 02 00 00 movl $0x2d7,-0x8(%ebp) #case 0x2d7(十进制:727):若num1==0则跳转到这位置,令a=727
8048c5e: eb 44 jmp 8048ca4 <phase_3+0xa8>
8048c60: c7 45 f8 4c 01 00 00 movl $0x14c,-0x8(%ebp) #case 332:num1==1,以此类推
8048c67: eb 3b jmp 8048ca4 <phase_3+0xa8>
8048c69: c7 45 f8 7e 02 00 00 movl $0x27e,-0x8(%ebp) #case 638
8048c70: eb 32 jmp 8048ca4 <phase_3+0xa8>
8048c72: c7 45 f8 e5 01 00 00 movl $0x1e5,-0x8(%ebp) #case 485
8048c79: eb 29 jmp 8048ca4 <phase_3+0xa8>
8048c7b: c7 45 f8 c4 01 00 00 movl $0x1c4,-0x8(%ebp) #case 452
8048c82: eb 20 jmp 8048ca4 <phase_3+0xa8>
8048c84: c7 45 f8 c7 03 00 00 movl $0x3c7,-0x8(%ebp) #case 967
8048c8b: eb 17 jmp 8048ca4 <phase_3+0xa8>
8048c8d: c7 45 f8 d5 03 00 00 movl $0x3d5,-0x8(%ebp) #case 981
8048c94: eb 0e jmp 8048ca4 <phase_3+0xa8>#if
8048c96: c7 45 f8 74 00 00 00 movl $0x74,-0x8(%ebp) #case 116:num1==7
8048c9d: eb 05 jmp 8048ca4 <phase_3+0xa8>
8048c9f: e8 fa 09 00 00 call 804969e <explode_bomb>
8048ca4: 8b 45 f0 mov -0x10(%ebp),%eax # get num2
8048ca7: 39 45 f8 cmp %eax,-0x8(%ebp) # 比较num2与a
8048caa: 74 05 je 8048cb1 <phase_3+0xb5> #if a!=num2,boom
8048cac: e8 ed 09 00 00 call 804969e <explode_bomb>
8048cb1: c9 leave
8048cb2: c3 ret
实现了一个跳转表(8048c57开始,switch语句)0x80499da地址内容打出来为“%d %d”,提示输入两个整数,num1存于-0xc(%ebp),num2存于-0x10(%ebp)(这个我也没弄明白,网上查的)num1范围为0~7,也就是有多个答案。
注意8048c55:jmp *%eax ,加星号表示“绝对地址”,不加的是“相对地址”
答案(7种):0 727 , 1 332 , 2 638 ,3 485, 4 452 ,5 967, 6 981 or 7 116
phase4:
08048cb3 <func4>:
8048cb3: 55 push %ebp
8048cb4: 89 e5 mov %esp,%ebp
8048cb6: 83 ec 08 sub $0x8,%esp
8048cb9: 83 7d 08 00 cmpl $0x0,0x8(%ebp)
8048cbd: 7f 09 jg 8048cc8 <func4+0x15>
8048cbf: c7 45 fc 01 00 00 00 movl $0x1,-0x4(%ebp)
8048cc6: eb 1a jmp 8048ce2 <func4+0x2f>
8048cc8: 8b 45 08 mov 0x8(%ebp),%eax
8048ccb: 48 dec %eax
8048ccc: 89 04 24 mov %eax,(%esp)
8048ccf: e8 df ff ff ff call 8048cb3 <func4>
8048cd4: 89 c2 mov %eax,%edx
8048cd6: 89 d0 mov %edx,%eax
8048cd8: c1 e0 03 shl $0x3,%eax
8048cdb: 89 c1 mov %eax,%ecx
8048cdd: 29 d1 sub %edx,%ecx
8048cdf: 89 4d fc mov %ecx,-0x4(%ebp)
8048ce2: 8b 45 fc mov -0x4(%ebp),%eax #return value in eax
8048ce5: c9 leave
8048ce6: c3 ret #f(0) return at here,move to return address where f(0) was
#call by f(1),and starts executing at 0x8048cd4
08048ce7 <phase_4>:
8048ce7: 55 push %ebp
8048ce8: 89 e5 mov %esp,%ebp
8048cea: 83 ec 28 sub $0x28,%esp
8048ced: 8d 45 f4 lea -0xc(%ebp),%eax
8048cf0: 89 44 24 08 mov %eax,0x8(%esp)
8048cf4: c7 44 24 04 00 9a 04 movl $0x8049a00,0x4(%esp)
8048cfb: 08
8048cfc: 8b 45 08 mov 0x8(%ebp),%eax
8048cff: 89 04 24 mov %eax,(%esp)
8048d02: e8 61 fb ff ff call 8048868 <sscanf@plt>
8048d07: 89 45 fc mov %eax,-0x4(%ebp) #string length in eax
8048d0a: 83 7d fc 01 cmpl $0x1,-0x4(%ebp)
8048d0e: 75 07 jne 8048d17 <phase_4+0x30>
8048d10: 8b 45 f4 mov -0xc(%ebp),%eax
8048d13: 85 c0 test %eax,%eax #保证输入fun4的参数>0
8048d15: 7f 05 jg 8048d1c <phase_4+0x35> #if -0xc(%ebp)>0,jump
8048d17: e8 82 09 00 00 call 804969e <explode_bomb>
8048d1c: 8b 45 f4 mov -0xc(%ebp),%eax
8048d1f: 89 04 24 mov %eax,(%esp)
8048d22: e8 8c ff ff ff call 8048cb3 <func4>
8048d27: 89 45 f8 mov %eax,-0x8(%ebp)
8048d2a: 81 7d f8 61 09 00 00 cmpl $0x961,-0x8(%ebp)
8048d31: 74 05 je 8048d38 <phase_4+0x51>
8048d33: e8 66 09 00 00 call 804969e <explode_bomb>
8048d38: c9 leave
8048d39: c3 ret
func4是个递归,画出栈图就加深了对递归的理解,每次call就新开栈,ret就退栈
//对应C语言代码:
//int fun4(int n)
//{
// if(n==0)
// return 1;
// else
// return 7*fun4(n-1);
//}
即求7的n次方
phase4中硬编码0x8049a00,用x/s 0x8049a00 输出“%d”,提示输入一个整数。func4的返回值应该在-0x8(%ebp),与0x961(2401)比较,相等则返回
7的4次方=2041,答案为4
phase5
08048d3a <phase_5>:
8048d3a: 55 push %ebp
8048d3b: 89 e5 mov %esp,%ebp
8048d3d: 83 ec 38 sub $0x38,%esp
8048d40: 8d 45 e8 lea -0x18(%ebp),%eax #get y(second input arg)
8048d43: 89 44 24 0c mov %eax,0xc(%esp)
8048d47: 8d 45 ec lea -0x14(%ebp),%eax #get x(first input arg)
8048d4a: 89 44 24 08 mov %eax,0x8(%esp)
8048d4e: c7 44 24 04 da 99 04 movl $0x80499da,0x4(%esp)
8048d55: 08
8048d56: 8b 45 08 mov 0x8(%ebp),%eax
8048d59: 89 04 24 mov %eax,(%esp)
8048d5c: e8 07 fb ff ff call 8048868 <sscanf@plt>
8048d61: 89 45 fc mov %eax,-0x4(%ebp)
8048d64: 83 7d fc 01 cmpl $0x1,-0x4(%ebp)
8048d68: 7f 05 jg 8048d6f <phase_5+0x35>
8048d6a: e8 2f 09 00 00 call 804969e <explode_bomb>
8048d6f: 8b 45 ec mov -0x14(%ebp),%eax
8048d72: 83 e0 0f and $0xf,%eax #get x lowest 4 bits,ensure <= 15
8048d75: 89 45 ec mov %eax,-0x14(%ebp)
8048d78: 8b 45 ec mov -0x14(%ebp),%eax
8048d7b: 89 45 f8 mov %eax,-0x8(%ebp)
8048d7e: c7 45 f0 00 00 00 00 movl $0x0,-0x10(%ebp) # -0x10(%ebp) is counter
8048d85: c7 45 f4 00 00 00 00 movl $0x0,-0xc(%ebp) # -0xc(%ebp) is sum
8048d8c: eb 16 jmp 8048da4 <phase_5+0x6a>
8048d8e: ff 45 f0 incl -0x10(%ebp) #counter++
8048d91: 8b 45 ec mov -0x14(%ebp),%eax #get x
8048d94: 8b 04 85 c0 a5 04 08 mov 0x804a5c0(,%eax,4),%eax #array a[x]
8048d9b: 89 45 ec mov %eax,-0x14(%ebp) #x=a[x]
8048d9e: 8b 45 ec mov -0x14(%ebp),%eax
8048da1: 01 45 f4 add %eax,-0xc(%ebp) #accumulate the sum
8048da4: 8b 45 ec mov -0x14(%ebp),%eax
8048da7: 83 f8 0f cmp $0xf,%eax #if a[x]!=15
8048daa: 75 e2 jne 8048d8e <phase_5+0x54>
8048dac: 83 7d f0 0b cmpl $0xb,-0x10(%ebp) #counter != 11,boom!
8048db0: 75 08 jne 8048dba <phase_5+0x80>
8048db2: 8b 45 e8 mov -0x18(%ebp),%eax
8048db5: 39 45 f4 cmp %eax,-0xc(%ebp) #cmp y and sum
8048db8: 74 05 je 8048dbf <phase_5+0x85>
8048dba: e8 df 08 00 00 call 804969e <explode_bomb>
8048dbf: c9 leave
8048dc0: c3 ret
有点绕,思路都在注释里,取输入x的低四位,要求<=15,易知数据都在15以内。代码中用到了一个地址a=0x804a5c0来偏移寻址,偏移x,数组a[x],然后令x=a[x],有点类似于顺序表实现的索引表,要求a[x]==15,否则继续循环。且每次操作求sum,还设置了counter控制循环为11次。用(gdb) p *(0x804a5c0)@16 输出a的前16个元素(多的没用),得到
{10, 2, 14, 7, 8, 12, 15, 11, 0, 4, 1, 13, 3, 9, 6, 5}
a[x]15,满足的只有x=6,然后看a[y]=6,找y,发现y=14,再以此类推。。。直到a[11]=13,ok得出答案,即
a[11]=13,a[13]=9,a[9]=4,a[4]=8,a[8]=0,a[0]=10,a[10]=1,a[1]=2,a[2]=14,a[14]=6,a[6]=15,刚好索引11次,所有a[x]累加sum=82
因此答案为11 82
phase6
08048dc1 <phase_6>:
8048dc1: 55 push %ebp
8048dc2: 89 e5 mov %esp,%ebpx
8048dc4: 83 ec 48 sub $0x48,%esp
8048dc7: c7 45 f0 3c a6 04 08 movl $0x804a63c,-0x10(%ebp) #q=0x804a63c
8048dce: 8d 45 d8 lea -0x28(%ebp),%eax #get a[0]
8048dd1: 89 44 24 04 mov %eax,0x4(%esp)
8048dd5: 8b 45 08 mov 0x8(%ebp),%eax #get input
8048dd8: 89 04 24 mov %eax,(%esp)
8048ddb: e8 64 02 00 00 call 8049044 <read_six_numbers>
8048de0: c7 45 f8 00 00 00 00 movl $0x0,-0x8(%ebp) #i=0
8048de7: eb 48 jmp 8048e31 <phase_6+0x70>
8048de9: 8b 45 f8 mov -0x8(%ebp),%eax # get i
8048dec: 8b 44 85 d8 mov -0x28(%ebp,%eax,4),%eax #get a[i]
8048df0: 85 c0 test %eax,%eax #if a[i]<=0,boom!
8048df2: 7e 0c jle 8048e00 <phase_6+0x3f>
8048df4: 8b 45 f8 mov -0x8(%ebp),%eax #get i
8048df7: 8b 44 85 d8 mov -0x28(%ebp,%eax,4),%eax #get a[i]
8048dfb: 83 f8 06 cmp $0x6,%eax #if a[i] > 6,boom~
8048dfe: 7e 05 jle 8048e05 <phase_6+0x44>
8048e00: e8 99 08 00 00 call 804969e <explode_bomb>
8048e05: 8b 45 f8 mov -0x8(%ebp),%eax # get i
8048e08: 40 inc %eax
8048e09: 89 45 fc mov %eax,-0x4(%ebp) #j=i+1
8048e0c: eb 1a jmp 8048e28 <phase_6+0x67>
8048e0e: 8b 45 f8 mov -0x8(%ebp),%eax
8048e11: 8b 54 85 d8 mov -0x28(%ebp,%eax,4),%edx #get a[i]
8048e15: 8b 45 fc mov -0x4(%ebp),%eax #get j
8048e18: 8b 44 85 d8 mov -0x28(%ebp,%eax,4),%eax #get a[j]
8048e1c: 39 c2 cmp %eax,%edx
8048e1e: 75 05 jne 8048e25 <phase_6+0x64> #if a[i]==a[j],boom!
8048e20: e8 79 08 00 00 call 804969e <explode_bomb>
8048e25: ff 45 fc incl -0x4(%ebp) # j++
8048e28: 83 7d fc 05 cmpl $0x5,-0x4(%ebp)
8048e2c: 7e e0 jle 8048e0e <phase_6+0x4d> #if j <= 5,goto
8048e2e: ff 45 f8 incl -0x8(%ebp) #if j>5,i++
8048e31: 83 7d f8 05 cmpl $0x5,-0x8(%ebp)
8048e35: 7e b2 jle 8048de9 <phase_6+0x28> #if i<=5,goto
8048e37: c7 45 f8 00 00 00 00 movl $0x0,-0x8(%ebp) #if i>5,i=0
8048e3e: eb 34 jmp 8048e74 <phase_6+0xb3>
8048e40: 8b 45 f0 mov -0x10(%ebp),%eax #get q
8048e43: 89 45 f4 mov %eax,-0xc(%ebp) #p=q
8048e46: c7 45 fc 01 00 00 00 movl $0x1,-0x4(%ebp) # j=1
8048e4d: eb 0c jmp 8048e5b <phase_6+0x9a>
8048e4f: 8b 45 f4 mov -0xc(%ebp),%eax #get p
8048e52: 8b 40 08 mov 0x8(%eax),%eax
8048e55: 89 45 f4 mov %eax,-0xc(%ebp) #(p+8)-->p
8048e58: ff 45 fc incl -0x4(%ebp) # j++
8048e5b: 8b 45 f8 mov -0x8(%ebp),%eax # get i
8048e5e: 8b 44 85 d8 mov -0x28(%ebp,%eax,4),%eax # get a[i]
8048e62: 3b 45 fc cmp -0x4(%ebp),%eax
8048e65: 7f e8 jg 8048e4f <phase_6+0x8e> # if a[i]>j,goto
8048e67: 8b 55 f8 mov -0x8(%ebp),%edx
8048e6a: 8b 45 f4 mov -0xc(%ebp),%eax
8048e6d: 89 44 95 c0 mov %eax,-0x40(%ebp,%edx,4) #b[i]=p
8048e71: ff 45 f8 incl -0x8(%ebp) #i++
8048e74: 83 7d f8 05 cmpl $0x5,-0x8(%ebp)
8048e78: 7e c6 jle 8048e40 <phase_6+0x7f> #if i<=5,goto
8048e7a: 8b 45 c0 mov -0x40(%ebp),%eax # get b[0]
8048e7d: 89 45 f0 mov %eax,-0x10(%ebp) #q=b[0]
8048e80: 8b 45 f0 mov -0x10(%ebp),%eax
8048e83: 89 45 f4 mov %eax,-0xc(%ebp) # p=q
8048e86: c7 45 f8 01 00 00 00 movl $0x1,-0x8(%ebp) # i=1
8048e8d: eb 19 jmp 8048ea8 <phase_6+0xe7>
8048e8f: 8b 45 f8 mov -0x8(%ebp),%eax
8048e92: 8b 54 85 c0 mov -0x40(%ebp,%eax,4),%edx #get b[i]
8048e96: 8b 45 f4 mov -0xc(%ebp),%eax
8048e99: 89 50 08 mov %edx,0x8(%eax) #(p+8)=b[i]
8048e9c: 8b 45 f4 mov -0xc(%ebp),%eax
8048e9f: 8b 40 08 mov 0x8(%eax),%eax
8048ea2: 89 45 f4 mov %eax,-0xc(%ebp) # p=(p+8) (做5次)
8048ea5: ff 45 f8 incl -0x8(%ebp) #i++
8048ea8: 83 7d f8 05 cmpl $0x5,-0x8(%ebp)
8048eac: 7e e1 jle 8048e8f <phase_6+0xce> #if i<=5,goto
8048eae: 8b 45 f4 mov -0xc(%ebp),%eax #get p
8048eb1: c7 40 08 00 00 00 00 movl $0x0,0x8(%eax) #(p+8)=0
8048eb8: 8b 45 f0 mov -0x10(%ebp),%eax
8048ebb: 89 45 f4 mov %eax,-0xc(%ebp) #p=q
8048ebe: c7 45 f8 00 00 00 00 movl $0x0,-0x8(%ebp) #i=0
8048ec5: eb 22 jmp 8048ee9 <phase_6+0x128>
8048ec7: 8b 45 f4 mov -0xc(%ebp),%eax #get p
8048eca: 8b 10 mov (%eax),%edx #(p)
8048ecc: 8b 45 f4 mov -0xc(%ebp),%eax
8048ecf: 8b 40 08 mov 0x8(%eax),%eax # get (p+8)
8048ed2: 8b 00 mov (%eax),%eax #((p+8))=(p+8)
8048ed4: 39 c2 cmp %eax,%edx #if (p)<((p+8)),boom!
8048ed6: 7d 05 jge 8048edd <phase_6+0x11c>
8048ed8: e8 c1 07 00 00 call 804969e <explode_bomb>
8048edd: 8b 45 f4 mov -0xc(%ebp),%eax
8048ee0: 8b 40 08 mov 0x8(%eax),%eax
8048ee3: 89 45 f4 mov %eax,-0xc(%ebp) #p=(p+8)
8048ee6: ff 45 f8 incl -0x8(%ebp) #i++
8048ee9: 83 7d f8 04 cmpl $0x4,-0x8(%ebp)
8048eed: 7e d8 jle 8048ec7 <phase_6+0x106> #if i<=4,goto
8048eef: c9 leave
8048ef0: c3 ret
太长了,很难看懂。应该是链表操作,后来看到一篇帖子得到启发,先打印代码中出现的硬编码地址0x8046a3c:
这个<node>简直就是在提示,就是节点~里面的内容有点奇怪,画出内存分布分析就能看出,每个节点实际上占3个内存单位(4B,32位系统)多打出的第四列数据实际上是节点外的数据,比如node2多打了一个764,实际上是node1的数据域~,于是节点结构为(数据,序号,next)。
然后比较一下各节点数据,看代码的意思应该是降序,于是得答案5 6 4 1 3 2
over~隐藏关没时间做了,略(逃