由于某种原因,这次的分析我不能详加说明,有关软件的信息也从略了,请不要问我。
我个人感觉,这个算法有些意思,就贴上分析结果,大家简单看看行了。
这个东东分注册过程和启动验证,都是分段比较的:
后9位和4-6位是在注册事件前已计算,(注册码输入框的按键响应事件);
注册事件中计算成本1-3位(F(用户名)=注册码前3位)和1-9位,并验证F(前9位)=F(后9位);
启动时又对4-9位进行了检测;
delphi的东东,入口:
004D1B4C u> $ 55 push ebp
004D1B4D . 8BEC mov ebp,esp
004D1B4F . B9 0A000000 mov ecx,0A
004D1B54 > 6A 00 push 0
004D1B56 . 6A 00 push 0
004D1B58 . 49 dec ecx
004D1B59 .^ 75 F9 jnz short XXXXXXXX.004D1B54
注册过程:
计算注册码前3位:
004BCEC4 |. 8B83 18030000 mov eax,[dword ds:ebx+318]
004BCECA |. E8 8527F9FF call XXXXXXXX.0044F654 ; GetText(TControl)
004BCECF |. 8B45 F4 mov eax,[dword ss:ebp-C] ; 取假码
004BCED2 |. 50 push eax
004BCED3 |. 8D55 F0 lea edx,[dword ss:ebp-10]
004BCED6 |. 8B83 14030000 mov eax,[dword ds:ebx+314] ; 取用户名
004BCEDC |. E8 7327F9FF call XXXXXXXX.0044F654 ; GetText(TControl)
004BCEE1 |. 8B45 F0 mov eax,[dword ss:ebp-10] ; 用户名
004BCEE4 |. 5A pop edx ; 00E785F0, 假码
004BCEE5 |. E8 1AFDFFFF call XXXXXXXX.004BCC04 ; 运算!进入!
004BCEEA |. 84C0 test al,al
004BCEEC |. 0F84 20010000 je XXXXXXXX.004BD012 ; 一定不能跳!
004BCEF2 |. E8 7108F5FF call XXXXXXXX.0040D768
进入call:
004BCC53 |. 8B45 FC mov eax,[dword ss:ebp-4]
004BCC56 |. E8 7D7FF4FF call XXXXXXXX.00404BD8 ; LStrLen(String):Integer;
004BCC5B |. 8BC8 mov ecx,eax
004BCC5D |. 83F9 03 cmp ecx,3
004BCC60 |. 0F8C 39010000 jl XXXXXXXX.004BCD9F
004BCC66 |. 83F9 14 cmp ecx,14
004BCC69 |. 0F8F 30010000 jg XXXXXXXX.004BCD9F ; 用户名在3-20之间
004BCC6F |. 8B45 FC mov eax,[dword ss:ebp-4]
004BCC72 |. BA E0CD4B00 mov edx,XXXXXXXX.004BCDE0 ; 'XXXXXXXX',这好象是个黑名单
004BCC77 |. E8 A080F4FF call XXXXXXXX.00404D1C
004BCC7C |. 0F84 1D010000 je XXXXXXXX.004BCD9F
004BCC82 |. 8B45 F8 mov eax,[dword ss:ebp-8]
004BCC85 |. E8 4E7FF4FF call XXXXXXXX.00404BD8
004BCC8A |. 83F8 12 cmp eax,12 ; 注册码要18位,$12
004BCC8D |. 0F85 0C010000 jnz XXXXXXXX.004BCD9F
004BCC93 |. B9 01000000 mov ecx,1
004BCC98 |> 8B45 F8 /mov eax,[dword ss:ebp-8] ; eax=假码
004BCC9B |. 8A4408 FF |mov al,[byte ds:eax+ecx-1] ; 从第一位开始取!
004BCC9F |. 04 D0 |add al,0D0 ; +d0,进位不要
004BCCA1 |. 2C 0A |sub al,0A ; -a
004BCCA3 |. 72 0A |jb short XXXXXXXX.004BCCAF ; 比a小,跳!
004BCCA5 |. 04 D9 |add al,0D9
004BCCA7 |. 2C 1A |sub al,1A
004BCCA9 |. 0F83 F0000000 |jnb XXXXXXXX.004BCD9F
004BCCAF |> 41 |inc ecx ; 计数器加1
004BCCB0 |. 83F9 13 |cmp ecx,13
004BCCB3 |.^ 75 E3 \jnz short XXXXXXXX.004BCC98 ; 未处理完,继续!
004BCCB5 |. BE 01000000 mov esi,1 ; 处理完的结果放在????
004BCCBA |> BB 01000000 /mov ebx,1
004BCCBF |. 8B45 FC |mov eax,[dword ss:ebp-4] ; 处理用户名;计算注册码前3位
004BCCC2 |. E8 117FF4FF |call XXXXXXXX.00404BD8
004BCCC7 |. 8BF8 |mov edi,eax
004BCCC9 |. 85FF |test edi,edi
004BCCCB |. 7E 21 |jle short XXXXXXXX.004BCCEE
004BCCCD |. B9 01000000 |mov ecx,1
004BCCD2 |> 8B45 FC |/mov eax,[dword ss:ebp-4]
004BCCD5 |. 0FB64408 FF ||movzx eax,[byte ds:eax+ecx-1]
004BCCDA |. F7EB ||imul ebx ; 乘法!乘上次余数,第一次是1
004BCCDC |. 03C6 ||add eax,esi ; +大轮数
004BCCDE |. 03C1 ||add eax,ecx ; +小轮数
004BCCE0 |. BB 65010000 ||mov ebx,165
004BCCE5 |. 99 ||cdq ; CDQ 双字扩展
004BCCE6 |. F7FB ||idiv ebx ; IDIV 除法,商回送AX,余数回送DX
004BCCE8 |. 8BDA ||mov ebx,edx ; 余数回送
004BCCEA |. 41 ||inc ecx
004BCCEB |. 4F ||dec edi
004BCCEC |.^ 75 E4 |\jnz short XXXXXXXX.004BCCD2
004BCCEE |> 8BC3 |mov eax,ebx ; 结果
004BCCF0 |. B9 24000000 |mov ecx,24
004BCCF5 |. 99 |cdq
004BCCF6 |. F7F9 |idiv ecx ; 除24,取余.我的11
004BCCF8 |. B8 F4CD4B00 |mov eax,XXXXXXXX.004BCDF4 ; ASCII "0123456789abcdefghijklmnopqrstuvwxyz"
004BCCFD |. 0FB60410 |movzx eax,[byte ds:eax+edx] ; 从余数位开始取!
004BCD01 |. 8B55 F8 |mov edx,[dword ss:ebp-8] ; 注册码!
004BCD04 |. 0FB65432 FF |movzx edx,[byte ds:edx+esi-1] ; 注册码从第一位开始取!
004BCD09 |. 2BD0 |sub edx,eax ; 注册码-str(余数)
004BCD0B |. 81C2 AE000000 |add edx,0AE ; +ae
004BCD11 |. 81FA AE000000 |cmp edx,0AE
004BCD17 |. 0F85 82000000 |jnz XXXXXXXX.004BCD9F ; 不等就跳!一跳就死!
004BCD1D |. 46 |inc esi
004BCD1E |. 83FE 04 |cmp esi,4 ; 处理注册码前3位!
004BCD21 |.^ 75 97 \jnz short XXXXXXXX.004BCCBA
计算注册码4-6位:
004BD42A . 8D45 F4 lea eax,[dword ss:ebp-C] ; 放结果的变量
004BD42D . 50 push eax
004BD42E . B9 06000000 mov ecx,6
004BD433 . BA 04000000 mov edx,4
004BD438 . 8B45 FC mov eax,[dword ss:ebp-4] ; 假码地址传eax
004BD43B . E8 780A0000 call XXXXXXXX.004BDEB8 ; 好象是取eax中的4-6位,结果放在变量中
004BD440 . 8B55 F4 mov edx,[dword ss:ebp-C]
004BD443 . 8D45 FC lea eax,[dword ss:ebp-4]
004BD446 . E8 6D75F4FF call XXXXXXXX.004049B8 ; LStrLAsg(void;void;void;void)
004BD44B . 33C0 xor eax,eax
004BD44D . 55 push ebp
004BD44E . 68 D5D44B00 push XXXXXXXX.004BD4D5
004BD453 . 64:FF30 push [dword fs:eax]
004BD456 . 64:8920 mov [dword fs:eax],esp
004BD459 . 8D45 F0 lea eax,[dword ss:ebp-10]
004BD45C . 8B55 FC mov edx,[dword ss:ebp-4]
004BD45F . 8A12 mov dl,[byte ds:edx] ; 取第四位
004BD461 . E8 9A76F4FF call XXXXXXXX.00404B00 ; LStrFromChar(String;String;Char)
004BD466 . 8B45 F0 mov eax,[dword ss:ebp-10]
004BD469 . E8 E2BFF4FF call XXXXXXXX.00409450 ; StrToInt(AnsiString),,?????
004BD46E . 8BD8 mov ebx,eax
004BD470 . 8D45 EC lea eax,[dword ss:ebp-14]
004BD473 . 8B55 FC mov edx,[dword ss:ebp-4]
004BD476 . 8A52 01 mov dl,[byte ds:edx+1] ; 取第五位
004BD479 . E8 8276F4FF call XXXXXXXX.00404B00 ; LStrFromChar(String;String;Char)
004BD47E . 8B45 EC mov eax,[dword ss:ebp-14]
004BD481 . E8 CABFF4FF call XXXXXXXX.00409450 ; StrToInt(AnsiString)
004BD486 . 03C3 add eax,ebx ; 第五位+第四位
004BD488 . F7EB imul ebx ; *第四位
004BD48A . 8BD8 mov ebx,eax ; 结果暂存于ebx
004BD48C . 8D45 E8 lea eax,[dword ss:ebp-18]
004BD48F . 8B55 FC mov edx,[dword ss:ebp-4]
004BD492 . 8A52 02 mov dl,[byte ds:edx+2] ; 取第六位
004BD495 . E8 6676F4FF call XXXXXXXX.00404B00 ; LStrFromChar(String;String;Char)
004BD49A . 8B45 E8 mov eax,[dword ss:ebp-18]
004BD49D . E8 AEBFF4FF call XXXXXXXX.00409450 ; StrToInt(AnsiString)
004BD4A2 . 03C3 add eax,ebx ; 第六位+上面结果
004BD4A4 . F7EB imul ebx ; *上面结果
004BD4A6 . 8BD8 mov ebx,eax ; 结果暂存于ebx
004BD4A8 . 8D45 E4 lea eax,[dword ss:ebp-1C]
004BD4AB . 8B55 FC mov edx,[dword ss:ebp-4]
004BD4AE . 8A12 mov dl,[byte ds:edx] ; 在取第四位
004BD4B0 . E8 4B76F4FF call XXXXXXXX.00404B00 ; LStrFromChar(String;String;Char)
004BD4B5 . 8B45 E4 mov eax,[dword ss:ebp-1C]
004BD4B8 . E8 93BFF4FF call XXXXXXXX.00409450 ; StrToInt(AnsiString)
004BD4BD . 3BD8 cmp ebx,eax ; 第四位与前面结果相等?
004BD4BF . 74 0A je short XXXXXXXX.004BD4CB
4-6位要满足如下关系:
((a+b)*a+c)*(a+b)*a=a
处理注册码前9位(1-9):
004BCD23 |. BB 01000000 mov ebx,1
004BCD28 |. BF 01000000 mov edi,1
004BCD2D |. BE 0A000000 mov esi,0A
004BCD32 |> B9 01000000 /mov ecx,1
004BCD37 |> 8B45 F8 |/mov eax,[dword ss:ebp-8]
004BCD3A |. 0FB64408 FF ||movzx eax,[byte ds:eax+ecx-1]
004BCD3F |. F7EB ||imul ebx ; *ebx;上轮余数
004BCD41 |. 03C1 ||add eax,ecx ; 结果加ecx
004BCD43 |. 03C6 ||add eax,esi ; +a
004BCD45 |. BB 79010000 ||mov ebx,179
004BCD4A |. 99 ||cdq
004BCD4B |. F7FB ||idiv ebx ; /$179
004BCD4D |. 8BDA ||mov ebx,edx ; 余数传ebx
004BCD4F |. 41 ||inc ecx
004BCD50 |. 83F9 0A ||cmp ecx,0A ; 这是前9位!
004BCD53 |.^ 75 E2 |\jnz short XXXXXXXX.004BCD37
004BCD55 |. 8BC3 |mov eax,ebx ; 结果150
004BCD57 |. B9 24000000 |mov ecx,24
004BCD5C |. 99 |cdq
004BCD5D |. F7F9 |idiv ecx ; 除24,取余.
004BCD5F |. 8BC2 |mov eax,edx
004BCD61 |. F7EE |imul esi ; 余数*a
004BCD63 |. 03C6 |add eax,esi ; +a
004BCD65 |. B9 25000000 |mov ecx,25
004BCD6A |. 99 |cdq
004BCD6B |. F7F9 |idiv ecx ; 除25,取余.
004BCD6D |. 8BCA |mov ecx,edx ; 结果存于ecx
004BCD6F |. 8BC7 |mov eax,edi ; edi==1;上轮结果
004BCD71 |. BF 23000000 |mov edi,23
004BCD76 |. 99 |cdq
004BCD77 |. F7FF |idiv edi ; 上次结果除23,取余
004BCD79 |. 03CA |add ecx,edx ; 本次结果+上次结果
004BCD7B |. 8BF9 |mov edi,ecx
004BCD7D |. 46 |inc esi
004BCD7E |. 83FE 13 |cmp esi,13 ; 又是9轮!(9*9轮)
004BCD81 |.^ 75 AF \jnz short XXXXXXXX.004BCD32
处理注册码后面9位(10-18):
004BD3C4 . E8 8B22F9FF call XXXXXXXX.0044F654 ; GetText(TControl)
004BD3C9 . 8B45 F8 mov eax,[dword ss:ebp-8]
004BD3CC . 8D55 FC lea edx,[dword ss:ebp-4]
004BD3CF . E8 3CBDF4FF call XXXXXXXX.00409110 ; Trim(AnsiString)
004BD3D4 . 8B45 FC mov eax,[dword ss:ebp-4]
004BD3D7 . E8 FC77F4FF call XXXXXXXX.00404BD8 ; LStrLen(String)
004BD3DC . 83F8 12 cmp eax,12 ; 假码要$12位
004BD3DF . 0F85 06010000 jnz XXXXXXXX.004BD4EB
004BD3E5 . C705 085F4D00 >mov [dword ds:4D5F08],1 ; 初始值1
004BD3EF . BB 01000000 mov ebx,1
004BD3F4 > 8B45 FC mov eax,[dword ss:ebp-4] ; 假码地址传eax
004BD3F7 . 8A4418 08 mov al,[byte ds:eax+ebx+8] ; 从第i位开始取数
004BD3FB . E8 B88D0000 call XXXXXXXX.004C61B8 ; 第i位在串中的位置数
004BD400 . 8D53 09 lea edx,[dword ds:ebx+9] ; edx=i
004BD403 . F7EA imul edx ; 第i位在串中的位置数*i
004BD405 . B9 25000000 mov ecx,25
004BD40A . 99 cdq
004BD40B . F7F9 idiv ecx ; /25
004BD40D . 8BCA mov ecx,edx ; 余数传ecx
004BD40F . A1 085F4D00 mov eax,[dword ds:4D5F08] ; 取上轮结果;初始值1
004BD414 . BE 23000000 mov esi,23
004BD419 . 99 cdq
004BD41A . F7FE idiv esi ; /23
004BD41C . 03CA add ecx,edx ; 两次余数之和
004BD41E . 890D 085F4D00 mov [dword ds:4D5F08],ecx ; 本轮结果表明放变量中
004BD424 . 43 inc ebx ; 计数器加1
004BD425 . 83FB 0A cmp ebx,0A ; 计算完了没?
004BD428 .^ 75 CA jnz short XXXXXXXX.004BD3F4 ; 最后ecx=$27
处理注册码:
004BCD83 |. 8D55 EC lea edx,[dword ss:ebp-14] ; 结果保存位置
004BCD86 |. A1 085F4D00 mov eax,[dword ds:4D5F08] ; 为后9位结果
004BCD8B |. 2BC7 sub eax,edi ; 后9位结果-前9位结果
004BCD8D |. E8 1EC6F4FF call XXXXXXXX.004093B0 ; 关键!参数就2个:结果保存位置,前后9位之差
004BCD92 |. 8B45 EC mov eax,[dword ss:ebp-14]
004BCD95 |. 8A00 mov al,[byte ds:eax]
004BCD97 |. 3C 30 cmp al,30 ; al=30就通过!
004BCD99 |. 75 04 jnz short XXXXXXXX.004BCD9F
在上面的关键call中,我们可以得到注册码的如下关系:
f(前9位)=f(后9位);
到现在,你已可以注册成功了,但启动验证不一定能过!我们来看看。
下面的注册码和用户名是在注册过程通过的。
启动验证:
004D1BD0 . A1 6C484D00 mov eax,[dword ds:4D486C]
004D1BD5 . C600 00 mov [byte ds:eax],0
004D1BD8 . 8D45 E8 lea eax,[dword ss:ebp-18]
004D1BDB . E8 6C49FFFF call XXXXXXXX.004C654C ; 读注册码!
004D1BE0 . 8B45 E8 mov eax,[dword ss:ebp-18] ; ASCII "h6s015lphi00000448"
004D1BE3 . 50 push eax
004D1BE4 . 8D45 E4 lea eax,[dword ss:ebp-1C]
004D1BE7 . E8 C848FFFF call XXXXXXXX.004C64B4 ; 读用户名!
004D1BEC . 8B45 E4 mov eax,[dword ss:ebp-1C] ; ASCII "scxtb"
004D1BEF . 5A pop edx
004D1BF0 . E8 8F4EFFFF call XXXXXXXX.004C6A84 ; 启动验证call!
004D1BF5 . 84C0 test al,al
004D1BF7 . 74 34 je short XXXXXXXX.004D1C2D
上面只是验证注册码各数字是否在串 "0123456789abcdefghijklmnopqrstuvwxyz"之中!如下:
004C6AB6 |. E8 1DE1F3FF call XXXXXXXX.00404BD8 ; 用户名长3-20
004C6ABB |. 83F8 03 cmp eax,3
004C6ABE |. 7C 33 jl short XXXXXXXX.004C6AF3
004C6AC0 |. 83F8 14 cmp eax,14
004C6AC3 |. 7F 2E jg short XXXXXXXX.004C6AF3
004C6AC5 |. 8B45 F8 mov eax,[dword ss:ebp-8]
004C6AC8 |. E8 0BE1F3FF call XXXXXXXX.00404BD8 ; 注册码长$12
004C6ACD |. 83F8 12 cmp eax,12
004C6AD0 |. 75 21 jnz short XXXXXXXX.004C6AF3
004C6AD2 |. 8BF8 mov edi,eax
004C6AD4 |. 85FF test edi,edi
004C6AD6 |. 7E 19 jle short XXXXXXXX.004C6AF1
004C6AD8 |. BE 01000000 mov esi,1
004C6ADD |> 8B45 F8 /mov eax,[dword ss:ebp-8] ; 注册码
004C6AE0 |. 8A4430 FF |mov al,[byte ds:eax+esi-1] ; 从第1位取,每次取1位
004C6AE4 |. E8 CFF6FFFF |call XXXXXXXX.004C61B8 ; 验证是否在串中
004C6AE9 |. 85C0 |test eax,eax
004C6AEB |. 74 06 |je short XXXXXXXX.004C6AF3
004C6AED |. 46 |inc esi
004C6AEE |. 4F |dec edi
004C6AEF |.^ 75 EC \jnz short XXXXXXXX.004C6ADD
紧接着,验证前3位:
004D1D1A > /BE 01000000 mov esi,1 ; 启动计算
004D1D1F . |A1 BC4B4D00 mov eax,[dword ds:4D4BBC]
004D1D24 . |8B00 mov eax,[dword ds:eax] ; 用户名5位
004D1D26 . |E8 AD2EF3FF call XXXXXXXX.00404BD8
004D1D2B . |8BC8 mov ecx,eax
004D1D2D . |85C9 test ecx,ecx
004D1D2F . |7E 29 jle short XXXXXXXX.004D1D5A
004D1D31 . |BB 01000000 mov ebx,1
004D1D36 > |A1 BC4B4D00 mov eax,[dword ds:4D4BBC] ; 循环乘,除
004D1D3B . |8B00 mov eax,[dword ds:eax] ; ASCII "scxtb"
004D1D3D . |0FB64418 FF movzx eax,[byte ds:eax+ebx-1] ; 取第i位
004D1D42 . |F7EE imul esi ; *esi,上轮结果,初为1
004D1D44 . |0305 E4604D00 add eax,[dword ds:4D60E4] ; +1
004D1D4A . |03C3 add eax,ebx ; +ebx,轮次!
004D1D4C . |BE 65010000 mov esi,165
004D1D51 . |99 cdq
004D1D52 . |F7FE idiv esi ; /165
004D1D54 . |8BF2 mov esi,edx ; 结果取余数
004D1D56 . |43 inc ebx
004D1D57 . |49 dec ecx
004D1D58 .^|75 DC jnz short XXXXXXXX.004D1D36
004D1D5A > |8BC6 mov eax,esi ; 循环结果
004D1D5C . |B9 24000000 mov ecx,24
004D1D61 . |99 cdq
004D1D62 . |F7F9 idiv ecx ; /24
004D1D64 . |B8 B8244D00 mov eax,XXXXXXXX.004D24B8 ; ASCII "0123456789abcdefghijklmnopqrstuvwxyz"
004D1D69 . |8A0410 mov al,[byte ds:eax+edx] ; 按余数取相应位!
004D1D6C . |8B15 B8484D00 mov edx,[dword ds:4D48B8] ; XXXXXXXX.004D4700
004D1D72 . |8B12 mov edx,[dword ds:edx]
004D1D74 . |8B0D E4604D00 mov ecx,[dword ds:4D60E4]
004D1D7A . |3A440A FF cmp al,[byte ds:edx+ecx-1] ; 与注册码比较
004D1D7E . |74 08 je short XXXXXXXX.004D1D88
004D1D80 . |A1 B44B4D00 mov eax,[dword ds:4D4BB4]
004D1D85 . |C600 01 mov [byte ds:eax],1
004D1D88 > |FF05 E4604D00 inc [dword ds:4D60E4]
004D1D8E . |833D E4604D00 >cmp [dword ds:4D60E4],4 ; 验证前3位?
004D1D95 .^\75 83 jnz short XXXXXXXX.004D1D1A
我们可以看出是与注册过程是相同的。不同是在下面,它验证了前4--9位:
004D1E31 . 8D45 C8 lea eax,[dword ss:ebp-38]
004D1E34 . 50 push eax ; 注册码!
004D1E35 . A1 B8484D00 mov eax,[dword ds:4D48B8]
004D1E3A . 8B00 mov eax,[dword ds:eax] ; ASCII "h6s015lphi00000448"
004D1E3C . B9 09000000 mov ecx,9
004D1E41 . BA 04000000 mov edx,4
004D1E46 . E8 6DC0FEFF call XXXXXXXX.004BDEB8 ; 取4-9位?
004D1E4B . 8B55 C8 mov edx,[dword ss:ebp-38]
004D1E4E . B8 E8604D00 mov eax,XXXXXXXX.004D60E8
004D1E53 . E8 1C2BF3FF call XXXXXXXX.00404974 ; 是否为0?
004D1E58 . 33C0 xor eax,eax
004D1E5A . 55 push ebp
004D1E5B . 68 7C1E4D00 push XXXXXXXX.004D1E7C
004D1E60 . 64:FF30 push [dword fs:eax]
004D1E63 . 64:8920 mov [dword fs:eax],esp
004D1E66 . A1 E8604D00 mov eax,[dword ds:4D60E8] ; 4-9位
004D1E6B . E8 E075F3FF call XXXXXXXX.00409450 ; 验证!
004D1E70 . 8BD8 mov ebx,eax
004D1E72 . 33C0 xor eax,eax
这里计算验证出来后,在下面还有个计算比较:
004D1E8C . E8 E724F3FF call unpacked.00404378
004D1E91 > 8BC3 mov eax,ebx
004D1E93 . B9 10270000 mov ecx,2710
004D1E98 . 99 cdq
004D1E99 . F7F9 idiv ecx ;
004D1E9B . 83F8 0A cmp eax,0A
004D1E9E . 74 08 je short unpacked.004D1EA8 ;
004D1EA0 . A1 B44B4D00 mov eax,[dword ds:4D4BB4]
004D1EA5 . C600 01 mov [byte ds:eax],1
004D1EA8 > E8 770AFFFF call unpacked.004C2924
(由于某种原因,我不能说明这里的关系了)
如果你有兴趣看到这,是否也觉得它的注册验证比较有意思?它这个样子可有不少麻烦的,我一共用了7天来搞它的,回头想想,也就知道我为什么是莱鸟了!
祝元旦快乐!