bomb炸弹实验

首先对bomb这个文件进行反汇编,得到一个1000+的汇编程序,看的头大。

phase_1:

  1. 0000000000400ef0 <phase_1>:
  2. 400ef0: 48 83 ec 08 sub $0x8,%rsp
  3. 400ef4: be 18 1b 40 00 mov $0x401b18,%esi
  4. 400ef9: e8 10 04 00 00 callq 40130e <strings_not_equal>
  5. 400efe: 85 c0 test %eax,%eax
  6. 400f00: 74 05 je 400f07 <phase_1+0x17>
  7. 400f02: e8 dc 07 00 00 callq 4016e3 <explode_bomb>
  8. 400f07: 48 83 c4 08 add $0x8,%rsp
  9. 400f0b: c3 retq

这个是炸弹一的汇编程序。可以看到,在程序里面,首先注意到了:

callq  40130e <strings_not_equal>

strings_not_equal这个函数应该就是对字符串是否相等进行了判断,所以要找到原来系统设定的字符串。

这是看到前面那句:mov    $0x401b18,%esi

感觉有问题,后来去查了一下,发现esi这个寄存器主要进行串操作,嗯,那字符串应该藏在0x401b18里面了。

用gdb调试,

果然在哪个地址里面。

phase_2:


  1. 400f0c: 55 push %rbp
  2. 400f0d: 53 push %rbx
  3. 400f0e: 48 83 ec 28 sub $0x28,%rsp
  4. 400f12: 48 89 e6 mov %rsp,%rsi
  5. 400f15: e8 eb 07 00 00 callq 401705 <read_six_numbers>
  6. 400f1a: 83 3c 24 01 cmpl $0x1,(%rsp)
  7. 400f1e: 74 25 je 400f45 <phase_2+0x39>
  8. 400f20: e8 be 07 00 00 callq 4016e3 <explode_bomb>
  9. 400f25: eb 1e jmp 400f45 <phase_2+0x39>
  10. 400f27: 83 c3 01 add $0x1,%ebx
  11. 400f2a: 89 d8 mov %ebx,%eax
  12. 400f2c: 0f af 45 fc imul -0x4(%rbp),%eax
  13. 400f30: 39 45 00 cmp %eax,0x0(%rbp)
  14. 400f33: 74 05 je 400f3a <phase_2+0x2e>
  15. 400f35: e8 a9 07 00 00 callq 4016e3 <explode_bomb>
  16. 400f3a: 48 83 c5 04 add $0x4,%rbp
  17. 400f3e: 83 fb 06 cmp $0x6,%ebx
  18. 400f41: 75 e4 jne 400f27 <phase_2+0x1b>
  19. 400f43: eb 0c jmp 400f51 <phase_2+0x45>
  20. 400f45: 48 8d 6c 24 04 lea 0x4(%rsp),%rbp
  21. 400f4a: bb 01 00 00 00 mov $0x1,%ebx
  22. 400f4f: eb d6 jmp 400f27 <phase_2+0x1b>
  23. 400f51: 48 83 c4 28 add $0x28,%rsp
  24. 400f55: 5b pop %rbx
  25. 400f56: 5d pop %rbp
  26. 400f57: c3 retq

这个首先看到代码:

callq 401705<read_six_numbers>

应该是要输入6个数字。

然后接下来按照下面的几行的步骤一步一步看下去,可以知道ebx这个寄存器是一个计数器,rbp这个寄存器用来指向当前比较的数字的地址,经过分析,每个数字的计算方法是:%ebx*(-4(%rbp)).即当前的数字的编号(1,2,3,4,5,6,第几个数字就是第几号)和上一个数字的乘积,第一个数字为1.

所以最后6个数字就是:1 2 6 24 120 720

phase_3:

  1. 400f58: 48 83 ec 18 sub $0x18,%rsp
  2. 400f5c: 4c 8d 44 24 08 lea 0x8(%rsp),%r8
  3. 400f61: 48 8d 4c 24 07 lea 0x7(%rsp),%rcx
  4. 400f66: 48 8d 54 24 0c lea 0xc(%rsp),%rdx
  5. 400f6b: be 6e 1b 40 00 mov $0x401b6e,%esi
  6. 400f70: b8 00 00 00 00 mov $0x0,%eax
  7. 400f75: e8 86 fc ff ff callq 400c00 <__isoc99_sscanf@plt>
  8. 400f7a: 83 f8 02 cmp $0x2,%eax
  9. 400f7d: 7f 05 jg 400f84 <phase_3+0x2c>
  10. 400f7f: e8 5f 07 00 00 callq 4016e3 <explode_bomb>
  11. 400f84: 83 7c 24 0c 07 cmpl $0x7,0xc(%rsp)
  12. 400f89: 0f 87 fc 00 00 00 ja 40108b <phase_3+0x133>
  13. 400f8f: 8b 44 24 0c mov 0xc(%rsp),%eax
  14. 400f93: ff 24 c5 80 1b 40 00 jmpq *0x401b80(,%rax,8)
  15. 400f9a: b8 6a 00 00 00 mov $0x6a,%eax
  16. 400f9f: 81 7c 24 08 40 02 00 cmpl $0x240,0x8(%rsp)
  17. 400fa6: 00
  18. 400fa7: 0f 84 e8 00 00 00 je 401095 <phase_3+0x13d>
  19. 400fad: e8 31 07 00 00 callq 4016e3 <explode_bomb>
  20. 400fb2: b8 6a 00 00 00 mov $0x6a,%eax
  21. 400fb7: e9 d9 00 00 00 jmpq 401095 <phase_3+0x13d>
  22. 400fbc: b8 66 00 00 00 mov $0x66,%eax
  23. 400fc1: 81 7c 24 08 bc 03 00 cmpl $0x3bc,0x8(%rsp)
  24. 400fc8: 00
  25. 400fc9: 0f 84 c6 00 00 00 je 401095 <phase_3+0x13d>
  26. 400fcf: e8 0f 07 00 00 callq 4016e3 <explode_bomb>
  27. 400fd4: b8 66 00 00 00 mov $0x66,%eax
  28. 400fd9: e9 b7 00 00 00 jmpq 401095 <phase_3+0x13d>
  29. 400fde: b8 6a 00 00 00 mov $0x6a,%eax
  30. 400fe3: 81 7c 24 08 2a 02 00 cmpl $0x22a,0x8(%rsp)
  31. 400fea: 00
  32. 400feb: 0f 84 a4 00 00 00 je 401095 <phase_3+0x13d>
  33. 400ff1: e8 ed 06 00 00 callq 4016e3 <explode_bomb>
  34. 400ff6: b8 6a 00 00 00 mov $0x6a,%eax
  35. 400ffb: e9 95 00 00 00 jmpq 401095 <phase_3+0x13d>
  36. 401000: b8 76 00 00 00 mov $0x76,%eax
  37. 401005: 81 7c 24 08 c9 00 00 cmpl $0xc9,0x8(%rsp)
  38. 40100c: 00
  39. 40100d: 0f 84 82 00 00 00 je 401095 <phase_3+0x13d>
  40. 401013: e8 cb 06 00 00 callq 4016e3 <explode_bomb>
  41. 401018: b8 76 00 00 00 mov $0x76,%eax
  42. 40101d: eb 76 jmp 401095 <phase_3+0x13d>
  43. 40101f: b8 62 00 00 00 mov $0x62,%eax
  44. 401024: 81 7c 24 08 07 01 00 cmpl $0x107,0x8(%rsp)
  45. 40102b: 00
  46. 40102c: 74 67 je 401095 <phase_3+0x13d>
  47. 40102e: e8 b0 06 00 00 callq 4016e3 <explode_bomb>
  48. 401033: b8 62 00 00 00 mov $0x62,%eax
  49. 401038: eb 5b jmp 401095 <phase_3+0x13d>
  50. 40103a: b8 69 00 00 00 mov $0x69,%eax
  51. 40103f: 81 7c 24 08 3b 03 00 cmpl $0x33b,0x8(%rsp)
  52. 401046: 00
  53. 401047: 74 4c je 401095 <phase_3+0x13d>
  54. 401049: e8 95 06 00 00 callq 4016e3 <explode_bomb>
  55. 40104e: b8 69 00 00 00 mov $0x69,%eax
  56. 401053: eb 40 jmp 401095 <phase_3+0x13d>
  57. 401055: b8 71 00 00 00 mov $0x71,%eax
  58. 40105a: 81 7c 24 08 c6 00 00 cmpl $0xc6,0x8(%rsp)
  59. 401061: 00
  60. 401062: 74 31 je 401095 <phase_3+0x13d>
  61. 401064: e8 7a 06 00 00 callq 4016e3 <explode_bomb>
  62. 401069: b8 71 00 00 00 mov $0x71,%eax
  63. 40106e: eb 25 jmp 401095 <phase_3+0x13d>
  64. 401070: b8 77 00 00 00 mov $0x77,%eax
  65. 401075: 81 7c 24 08 74 01 00 cmpl $0x174,0x8(%rsp)
  66. 40107c: 00
  67. 40107d: 74 16 je 401095 <phase_3+0x13d>
  68. 40107f: e8 5f 06 00 00 callq 4016e3 <explode_bomb>
  69. 401084: b8 77 00 00 00 mov $0x77,%eax
  70. 401089: eb 0a jmp 401095 <phase_3+0x13d>
  71. 40108b: e8 53 06 00 00 callq 4016e3 <explode_bomb>
  72. 401090: b8 68 00 00 00 mov $0x68,%eax
  73. 401095: 3a 44 24 07 cmp 0x7(%rsp),%al
  74. 401099: 74 05 je 4010a0 <phase_3+0x148>
  75. 40109b: e8 43 06 00 00 callq 4016e3 <explode_bomb>
  76. 4010a0: 48 83 c4 18 add $0x18,%rsp
  77. 4010a4: c3 retq

被第三个炸弹卡了好久……主要原因是汇编不行啊。当年学的汇编是学的8位单片机上的汇编,所有的寄存器都是单独的不相关的。而这个程序是在64位环境下运行的,所以像eax rax al 这些寄存器都是相关的,都是扩展的寄存器。不知道这个东西,一直以为几个寄存器无关,在gdb调试的时候,就随便输了几个数进去,然后看al和rax这两个寄存器里面的值,以为是定值,就一直按照这个定值来分析的,导致后面怎么弄都不对……其实炸弹三就是利用这些相关的寄存器来实现不同的跳转的

分析:

首先,看到:mov    $0x401b6e,%esi  先看看那个地址里面是什么东西。

结果: “%d,%c,%d”

应该是输入的格式,输入三个数据,其中两个整数,一个char型的。

接着看下去,

  1. 400f84: 83 7c 24 0c 07 cmpl $0x7,0xc(%rsp)
  2. 400f89: 0f 87 fc 00 00 00 ja 40108b <phase_3+0x133>

其中一个输入的数字不能大于7,否则就爆炸了……

mov    0xc(%rsp),%eax

接下去eax被赋值为那个输入不能大于7的数据。

jmpq   *0x401b80(,%rax,8)

一个间接跳转,这里一开始以为rax是个独立的寄存器,导致这个程序都理解错了……rax是eax的64为扩展,所以这里rax里面的值和eax一样,所以跳转到(0x401b80+8*rax)地址里面的值所对应的地址(比较绕,就是间接跳转)。这里跳转的值和前面那个输入有关,我输入1,所以跳转到(0x401b88)里面那个值对应的地址,查了一下,地址是0x400fbc.直接看哪里的指令。

  1. 400fbc: b8 66 00 00 00 mov $0x66,%eax
  2. 400fc1: 81 7c 24 08 bc 03 00 cmpl $0x3bc,0x8(%rsp)
  3. 400fc8: 00
  4. 400fc9: 0f 84 c6 00 00 00 je 401095 <phase_3+0x13d>
  5. 400fcf: e8 0f 07 00 00 callq 4016e3 <explode_bomb>

eax被赋值成0x66,并且第二个整数是0X3BC,跳转到0x401095

  1. 401095: 3a 44 24 07 cmp 0x7(%rsp),%al

这里那个char型的大小要和al一样(老坑),eax=0x66,al是eax的低8位,也是0x66,查一下ascii,是f

所以输入就是1 f 956

这里1 和956的输入顺序偷了个懒,直接试了两次给试出来的,没有看程序来推他的顺序……

phase_4:

  1. 00000000004010bf <phase_4>:
  2. 4010bf: 48 83 ec 18 sub $0x18,%rsp
  3. 4010c3: 48 8d 54 24 0c lea 0xc(%rsp),%rdx
  4. 4010c8: be 74 1b 40 00 mov $0x401b74,%esi
  5. 4010cd: b8 00 00 00 00 mov $0x0,%eax
  6. 4010d2: e8 29 fb ff ff callq 400c00 <__isoc99_sscanf@plt>
  7. 4010d7: 83 f8 01 cmp $0x1,%eax
  8. 4010da: 75 07 jne 4010e3 <phase_4+0x24>
  9. 4010dc: 83 7c 24 0c 00 cmpl $0x0,0xc(%rsp)
  10. 4010e1: 7f 05 jg 4010e8 <phase_4+0x29>
  11. 4010e3: e8 fb 05 00 00 callq 4016e3 <explode_bomb>
  12. 4010e8: 8b 7c 24 0c mov 0xc(%rsp),%edi
  13. 4010ec: e8 b4 ff ff ff callq 4010a5 <func4>
  14. 4010f1: 3d 00 5f 37 00 cmp $0x375f00,%eax
  15. 4010f6: 74 05 je 4010fd <phase_4+0x3e>
  16. 4010f8: e8 e6 05 00 00 callq 4016e3 <explode_bomb>
  17. 4010fd: 48 83 c4 18 add $0x18,%rsp
  18. 401101: c3 retq

第四个炸弹是关于递归的。

首先看到

  1. 4010c8: be 74 1b 40 00 mov $0x401b74,%esi

看看0x401b74里面的内容。

得到:"%d"

这次只要一个数就行了。

继续下去,看到输入的数被放入edi这个寄存器里面,然后调用了func4这个函数。下面看看func4函数

  1. 00000000004010a5 <func4>:
  2. 4010a5: 53 push %rbx
  3. 4010a6: 89 fb mov %edi,%ebx
  4. 4010a8: b8 01 00 00 00 mov $0x1,%eax
  5. 4010ad: 83 ff 01 cmp $0x1,%edi
  6. 4010b0: 7e 0b jle 4010bd <func4+0x18>
  7. 4010b2: 8d 7f ff lea -0x1(%rdi),%edi
  8. 4010b5: e8 eb ff ff ff callq 4010a5 <func4>
  9. 4010ba: 0f af c3 imul %ebx,%eax
  10. 4010bd: 5b pop %rbx
  11. 4010be: c3 retq

fun4分析:

首先,进行初始化

ebx=edi(函数的输入),eax=1

然后比较edi和1的大小,若edi<=1 退出函数,若edi>1,edi=edi-1;继续调用func4,再计算eax=eax*ebx;

这里就比较清楚了,func4整个函数就是一个递归调用,他的输入是edi,eax寄存器相当于一个累乘器,eax=eax*edi,直到edi<=1;

用c++写,func4就是:

  1. func4(int x)
  2. {
  3. if(x>=1)
  4. return 1;
  5. return x*func4(x-1);
  6. }

fun4调用结束后,

4010f1: 3d 00 5f 37 00 cmp $0x375f00,%eax

把eax和0x375F00比较,也就是求x!=0x375F00

最后求出来X=10;

输入结果,正确!

phase_5:

  1. 0000000000401102 <phase_5>:
  2. 401102: 53 push %rbx
  3. 401103: 48 89 fb mov %rdi,%rbx
  4. 401106: e8 e6 01 00 00 callq 4012f1 <string_length>
  5. 40110b: 83 f8 06 cmp $0x6,%eax
  6. 40110e: 74 05 je 401115 <phase_5+0x13>
  7. 401110: e8 ce 05 00 00 callq 4016e3 <explode_bomb>
  8. 401115: b8 00 00 00 00 mov $0x0,%eax
  9. 40111a: ba 00 00 00 00 mov $0x0,%edx
  10. 40111f: 0f b6 0c 03 movzbl (%rbx,%rax,1),%ecx
  11. 401123: 83 e1 0f and $0xf,%ecx
  12. 401126: 03 14 8d c0 1b 40 00 add 0x401bc0(,%rcx,4),%edx
  13. 40112d: 48 83 c0 01 add $0x1,%rax
  14. 401131: 48 83 f8 06 cmp $0x6,%rax
  15. 401135: 75 e8 jne 40111f <phase_5+0x1d>
  16. 401137: 83 fa 3e cmp $0x3e,%edx
  17. 40113a: 74 05 je 401141 <phase_5+0x3f>
  18. 40113c: e8 a2 05 00 00 callq 4016e3 <explode_bomb>
  19. 401141: 5b pop %rbx
  20. 401142: c3 retq

第五个炸弹,感觉有点像密码转化的意思。

首先看到

  1. 40110b: 83 f8 06 cmp $0x6,%eax

输入6个数据,而且根据上面的指令,数据时字符串形式的,也就是字符串长度为6.

  1. 40111f: 0f b6 0c 03 movzbl (%rbx,%rax,1),%ecx

这条指令中,rax已经初始化为0,但是一开始没有搞明白rbx的大小,回过头看上面,有一句

  1. 401103: 48 89 fb mov %rdi,%rbx

表示rbx就是输入的数据的存储地址,那前面那句的意思就是一个一个读取输入的字符,将其赋值给ecx这个寄存器。

  1. 401123: 83 e1 0f and $0xf,%ecx

这句就是取ecx的低4位,其他为置零。

  1. 401126: 03 14 8d c0 1b 40 00 add 0x401bc0(,%rcx,4),%edx

这句就是从(0x401bc0+rcx*4)里面拿数据出来,加到edx上。

因为rcx只能是0~F的数,所以0x401bc0这个地址里面存的应该是一个数据大小为16的数组,用gdb看,得到:

果然是一个数组,然后下面就是把6个输入一个一个的转化为这个数组,得到累加值edx
  1. 401137: 83 fa 3e cmp $0x3e,%edx

最后得到的edx要是0x3e,这个就凑,最后凑了一个答案出来LMNOKA

输入,正确!

这题总结一下,就是输入6个字符,然后程序会根据6个字符的ascii码的低4位作为索引,在这里,可以看成是一个预先设定好的数组的下标,通过索引,把数组中相应的值拿出来求和,最后要求求得的和为0x3e就可以了。

最后一个了

phase_6:

  1. 00000000004011b2 <phase_6>:
  2. 4011b2: 48 83 ec 08 sub $0x8,%rsp
  3. 4011b6: ba 0a 00 00 00 mov $0xa,%edx
  4. 4011bb: be 00 00 00 00 mov $0x0,%esi
  5. 4011c0: e8 1b fa ff ff callq 400be0 <strtol@plt>
  6. 4011c5: 89 05 55 21 20 00 mov %eax,0x202155 (%rip) # 603320 <node0>
  7. 4011cb: bf 20 33 60 00 mov $0x603320,%edi
  8. 4011d0: e8 6e ff ff ff callq 401143 <fun6>
  9. 4011d5: 48 8b 40 08 mov 0x8(%rax),%rax
  10. 4011d9: 8b 0d 41 21 20 00 mov 0x202141(%rip),%ecx # 603320 <node0>
  11. 4011df: 39 08 cmp %ecx,(%rax)
  12. 4011e1: 74 05 je 4011e8 <phase_6+0x36>
  13. 4011e3: e8 fb 04 00 00 callq 4016e3 <explode_bomb>
  14. 4011e8: 48 83 c4 08 add $0x8,%rsp
  15. 4011ec: c3 retq

这个,太坑了。一开始在做的时候,看到一个func6,就一头扎了进去,被里面的跳转搞得快疯了,以前的程序员真是牛逼,写这种代码应该还能接受,但是要是去读这种汇编级别的代码,逻辑能被搞死啊……

后来实在受不了了,不看func6,直接给了一个输入,gdb一步一步调试,竟然成功了,我也是醉了。

从调用func6之后看这段程序。

可以看到:

  1. 4011df: 39 08 cmp %ecx,(%rax)

这句是关键,他其实比较的是ecx和rax两个寄存器,经过调试,发现ecx就是输入的那个数,而rax竟然是一个定值……

通过查看rax这个寄存器,取出里面地址所对应的的值,得到:

发现就是和692比较,最后输入692,正确。

最后一个太坑,要是跳到func6里面就完蛋了。

结果:


版权声明:本文为博主原创文章,未经博主允许不得转载。

csapp lab2 bomb 二进制炸弹《深入理解计算机系统》的更多相关文章

  1. CSAPP Lab2: Binary Bomb

    著名的CSAPP实验:二进制炸弹 就是通过gdb和反汇编猜测程序意图,共有6关和一个隐藏关卡 只有输入正确的字符串才能过关,否则会程序会bomb终止运行 隐藏关卡需要输入特定字符串方会开启 实验材料下 ...

  2. 《CSAPP》实验二:二进制炸弹

    二进制炸弹是第三章<程序的机器级表示>的配套实验,这章主要介绍了x64汇编,包括:操作数的表示方式,数据传送指令,算术和逻辑指令,控制流跳转指令,过程(procedure)的实现与运行时栈 ...

  3. 读完了csapp(中文名:深入理解计算机系统)

    上个星期最终把csapp看完了. 我买的是中文版的,由于除了貌似评价不错以外,由于涉及到些自己不了解的底层东西,怕是看英文会云里雾里.如今看来,大概不能算是个长处,可是的确可以加快我的看书速度,否则一 ...

  4. CSAPP深入理解计算机系统(第二版)第三章家庭作业答案

    <深入理解计算机系统(第二版)>CSAPP 第三章 家庭作业 这一章介绍了AT&T的汇编指令 比较重要 本人完成了<深入理解计算机系统(第二版)>(以下简称CSAPP) ...

  5. CSAPP lab2 二进制拆弹 binary bombs phase_1

    这个实验从开始到完成大概花了三天的时间,由于我们还没有学习编译原理.汇编语言等课程,为了完成这个实验我投机取巧了太多,看了网上很多的解题方法,为了更加深入学习编译反编译,觉得需要从头开始好好梳理一下. ...

  6. CSAPP:逆向工程【二进制炸弹】

    转载请注明出处:https://www.cnblogs.com/ustca/p/11694127.html 二进制炸弹任务描述 拓展:缓冲区溢出攻击 "二进制炸弹包含若干个阶段,每个阶段需要 ...

  7. <深入理解计算机系统> CSAPP Tiny web 服务器

    本文是我学习<深入理解计算机系统>中网络编程部分的学习笔记. 1. Web基础       web客户端和服务器之间的交互使用的是一个基于文本的应用级协议HTTP(超文本传输协议).一个w ...

  8. 《深入理解计算机系统》学习笔记整理(CSAPP 学习笔记)

    简介 本笔记目前已包含 CSAPP 中除第四章(处理器部分)外的其他各章节,但部分章节的笔记尚未整理完全.未整理完成的部分包括:ch3.ch11.ch12 的后面几小节:ch5 的大部分. 我在整理笔 ...

  9. CSAPP(深入理解计算机系统)读后感

    9月到10月8号,包括国庆七天,大概每天5小时以上的时间,把Computer System: A Programmer Perspective 2rd version(深入理解计算机系统)的英文版啃完 ...

随机推荐

  1. deal with 'non-admin area' warn

    We usually use the follow code to delete product in Magento $product = Mage::getSingleton('catalog/p ...

  2. 不同版本的 IIS 中使用 ASP.NET MVC(C#)【转】

    由微软 ASP.NET 团队|2008 年 8 月 19 日 推特 在本教程中,您将学习在不同版本的 Internet Information Services 中如何使用 ASP.NET MVC 和 ...

  3. 依赖注入及AOP简述(十一)——生命周期管理 .

    2.     生命周期管理 各种依赖注入框架提供了替开发者管理各种Scope的便利功能,随之而来的就必然是被管理的依赖对象的生命周期管理的问题.所谓生命周期管理,就是一个对象在它所属的Scope中从被 ...

  4. collectionView关于点击事件

    -(void)collectionView:(UICollectionView *)collectionView didDeselectItemAtIndexPath:(NSIndexPath *)i ...

  5. Hadoop Eclipse远程连接出现:Error:Call to /10.10.10.10:9000 failed on local exception: java.io.EOFException

    异常截图:

  6. error C4996 The POSIX name for this item is deprecated. Instead, use the ISO C and C++ conformant name

    error C4996: 'strupr': The POSIX name for this item is deprecated. Instead, use the ISO C and C++ co ...

  7. (跨平台)cocos2d-x C++ or Object-C(前端)调用C# webservices(后台),实现交叉编译到Android/IOS/WinPhone等移动终端设备

    1.2014年4月2号算是正式找到自己的实习工作-杭州美迪软件有限公司(移动物联事业部)合作于:四川管家婆总部移动终端代理,由于在校选编程专业语言C#和在浙大网新培训课程(C#.Asp.net开发)缘 ...

  8. 已知w是一个大于10但不大于1000000的无符号整数,若w是n(n≥2)位的整数,则求出w的后n-1位的数。

    描述 已知w是一个大于10但不大于1000000的无符号整数,若w是n(n≥2)位的整数,则求出w的后n-1位的数.   输入 第一行为M,表示测试数据组数.接下来M行,每行包含一个测试数据. 输出 ...

  9. JVM学习之堆和栈

    Java栈与堆 1. 栈(stack)与堆(heap)都是Java用来在Ram中存放数据的地方.与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆. 2. 栈的优势是,存取速度比堆要快, ...

  10. cookie简介

    上例子 1.首先要用php创建cookie发送给客户端,利用setcookie()方法即可 <?php /* * * @Authors peng--jun * @Email 1098325951 ...