2019 360杯 re wp--Here are some big nums

 测试文件:https://www.lanzous.com/i7303oh

 

1.准备

 

 

获取信息:

  • 32位文件 

 

2.IDA打开

找到主函数之后,反编译为伪C代码

 1 int sub_404D70()
 2 {
 3   int result; // eax
 4   char v1; // [esp+0h] [ebp-58h]
 5   char v2[16]; // [esp+18h] [ebp-40h]
 6   char v3; // [esp+28h] [ebp-30h]
 7   char v4[16]; // [esp+2Ch] [ebp-2Ch]
 8   char v5; // [esp+3Ch] [ebp-1Ch]
 9   int v6; // [esp+40h] [ebp-18h]
10   size_t v7; // [esp+44h] [ebp-14h]
11   int i; // [esp+48h] [ebp-10h]
12   int v9; // [esp+54h] [ebp-4h]
13 
14   sub_404EF0("------360CTF------\n", v1);
15   sub_404EF0("Please input fl@g:", v1);
16   sub_404F30("%s", (unsigned int)Str);
17   v7 = strlen(Str);
18   if ( v7 == 32 )
19   {
20     sub_401F20(&v1);
21     v9 = 0;
22     for ( i = 0; i < 16; ++i )
23     {
24       v4[i] = Str[i];
25       v2[i] = byte_4080A8[i];
26     }
27     v5 = 0;
28     v3 = 0;
29     if ( (unsigned __int8)((int (__cdecl *)(char *, signed int))loc_404600)(v4, 16) && (unsigned __int8)sub_404860(v2) )
30     {
31       sub_404EF0("Congratulations!!!", v1);
32       system("PAUSE");
33       v9 = -1;
34       sub_401FD0(&v1);
35       result = 0;
36     }
37     else
38     {
39       sub_404EF0("Wrong!!!", v1);
40       v6 = 0;
41       v9 = -1;
42       sub_401FD0(&v1);
43       result = v6;
44     }
45   }
46   else
47   {
48     sub_404EF0("wrong format!!!", v1);
49     result = 0;
50   }
51   return result;
52 }

 

从第18行代码,我们能够得知flag(输入字符串)长度应该为32

代码的第26行loc_404600(v4, 16) && sub_404860(v2)很明显就是我们需要关注的两个函数,但是打开loc_404600(v4, 16)

.text:00404600 loc_404600:                             ; CODE XREF: sub_404D70+D3↓p
.text:00404600                                         ; DATA XREF: TlsCallback_0:loc_404552↑o ...
.text:00404600                 cmp     ch, ah
.text:00404602                 mov     ds, word ptr [edx+edx*4]
.text:00404605                 push    es
.text:00404606                 adc     [ecx], ebp
.text:00404608                 sub     eax, 6DD7066Eh
.text:0040460D                 outsb
.text:0040460E                 bound   esi, [esi+3Dh]
.text:00404611                 or      ch, bl
.text:00404613                 push    ebx
.text:00404614                 insd
.text:00404615                 outsb
.text:00404616                 bound   esi, [esi-14h]
.text:00404619                 adc     dl, 76h
.text:0040461C                 insd
.text:0040461D                 outsb
.text:0040461E                 movsd
.text:0040461F                 xor     eax, [ecx+6D76626Eh]
.text:00404625                 push    es
.text:00404626                 cdq
.text:00404627                 pop     ss
.text:00404628                 sub     eax, 0E13BEF6Eh
.text:0040462D                 xchg    bh, [esi+ebp*4]
.text:00404630                 xchg    eax, edx
.text:00404631                 xchg    eax, ecx
.text:00404632                 movsd
.text:00404633                 xor     edx, [ecx+6D76626Eh]
.text:00404639                 push    es
.text:0040463A                 inc     ecx
.text:0040463B                 adc     al, 2Dh
.text:0040463D                 outsb
.text:0040463E                 out     dx, eax
.text:0040463F                 cmp     ecx, ecx
.text:00404641                 xchg    ch, [eax]
.text:00404643                 scasb
.text:00404644                 xchg    eax, edx
.text:00404645                 xchg    eax, ecx
.text:00404646                 movsb
.text:00404647                 xor     edx, [ecx+0F160A6Fh]

于是尝试用OD进行动态调试,并和IDA中的伪C代码作比较

 

3. OD 动态调试

一句一句分析理解,直接上代码和注释了

 

3.1 loc_404600函数

输入“abcdefghijklmnopqrstuvwxyz123456”作为测试,第56行找到了loc_404600函数,进入

  1   1 00404600    55              push ebp
  2   2 00404601    8BEC            mov ebp,esp
  3   3 00404603    6A FF           push -0x1
  4   4 00404605    68 735F4000     push test.00405F73
  5   5 0040460A    64:A1 00000000  mov eax,dword ptr fs:[0]
  6   6 00404610    50              push eax                                 ; eax=0x19FF1C
  7   7 00404611    64:8925 0000000>mov dword ptr fs:[0],esp
  8   8 00404618    81EC B0000000   sub esp,0xB0                             ; 为局部变量申请栈空间
  9   9 0040461E    C745 EC 0000000>mov dword ptr ss:[ebp-0x14],0x0          ; 原本指向flag前16个字符
 10  10 00404625    68 FB614000     push test.004061FB                       ; 指向开头的字符串--360CTF...
 11  11 0040462A    8D4D 8C         lea ecx,dword ptr ss:[ebp-0x74]
 12  12 0040462D    E8 5ED8FFFF     call test.00401E90
 13  13 00404632    C745 FC 0000000>mov dword ptr ss:[ebp-0x4],0x0
 14  14 00404639    68 23624000     push test.00406223
 15  15 0040463E    8D4D A4         lea ecx,dword ptr ss:[ebp-0x5C]          ; 0x19fe60其中的值为0x0F
 16  16 00404641    E8 4AD8FFFF     call test.00401E90
 17  17 00404646    C645 FC 01      mov byte ptr ss:[ebp-0x4],0x1            ; 下面的字符串压入了0x19FE00=EBP-0xC0
 18  18 0040464A    68 60624000     push test.00406260                       ; ASCII "12345679"
 19  19 0040464F    8D8D 74FFFFFF   lea ecx,dword ptr ss:[ebp-0x8C]
 20  20 00404655    E8 36D8FFFF     call test.00401E90                       ; 返回的eax="123456789"
 21  21 0040465A    C645 FC 02      mov byte ptr ss:[ebp-0x4],0x2
 22  22 0040465E    C745 E8 6C62400>mov dword ptr ss:[ebp-0x18],test.0040626>; ASCII "greatctf"
 23  23 00404665    8D4D F3         lea ecx,dword ptr ss:[ebp-0xD]
 24  24 00404668    E8 F3D6FFFF     call test.00401D60
 25  25 0040466D    C645 FC 03      mov byte ptr ss:[ebp-0x4],0x3
 26  26 00404671    8B45 E8         mov eax,dword ptr ss:[ebp-0x18]
 27  27 00404674    50              push eax                                 ; 将新赋值的eax="greatctf"压入栈中
 28  28 00404675    E8 14160000     call <jmp.&api-ms-win-crt-string-l1-1-0.>; 计算长度strlen
 29  29 0040467A    83C4 04         add esp,0x4
 30  30 0040467D    8BC8            mov ecx,eax                              ; ecx=8
 31  31 0040467F    8B45 EC         mov eax,dword ptr ss:[ebp-0x14]          ; eax=[ebp-0x14]
 32  32 00404682    33D2            xor edx,edx                              ; edx清零
 33  33 00404684    F7F1            div ecx                                  ; [ebp-0x14]/8
 34  34 00404686    8B45 E8         mov eax,dword ptr ss:[ebp-0x18]          ; eax="greatctf"
 35  35 00404689    0FBE0C10        movsx ecx,byte ptr ds:[eax+edx]          ; 取eax=“greatctf”的第edx(这里相当于是[ebp-0x14]%8的值)个字节放入ecx
 36  36 0040468D    8B55 08         mov edx,dword ptr ss:[ebp+0x8]           ; edx="abcdefghijklmnop",flag前16个字符
 37  37 00404690    0355 EC         add edx,dword ptr ss:[ebp-0x14]          ; edx=edx+0
 38  38 00404693    0FBE02          movsx eax,byte ptr ds:[edx]              ; 取edx="abc..."的第edx([ebp-0x14])个字节放入eax
 39  39 00404696    33C1            xor eax,ecx                              ; “greatctf"的首字母与"abcd.."的首字母做异或
 40  40 00404698    8B4D 08         mov ecx,dword ptr ss:[ebp+0x8]           ; ecx="abcdefghijklmnop"的地址
 41  41 0040469B    034D EC         add ecx,dword ptr ss:[ebp-0x14]          ; ecx=ecx+0---有点怀疑是个循环操作了
 42  42 0040469E    8801            mov byte ptr ds:[ecx],al                 ; 将异或结果保存到"abcd..."的首字符处
 43  43 004046A0    8B55 EC         mov edx,dword ptr ss:[ebp-0x14]          ; edx=0
 44  44 004046A3    83C2 01         add edx,0x1                              ; edx=edx+1
 45  45 004046A6    8955 EC         mov dword ptr ss:[ebp-0x14],edx          ; 更新[ebp-0x14]中的值为edx
 46  46 004046A9    8B45 EC         mov eax,dword ptr ss:[ebp-0x14]          ; 将[ebp-0x14]赋值到eax
 47  47 004046AC    3B45 0C         cmp eax,dword ptr ss:[ebp+0xC]           ; eax与16比较,截取的部分flag的长度
 48  48 004046AF  ^ 7C C0           jl Xtest.00404671                        ; 小于就跳回上面,继续执行异或操作
 49  49 004046B1    83EC 18         sub esp,0x18                             ; 获取大小为0x18的栈空间
 50  50 004046B4    8BCC            mov ecx,esp
 51  51 004046B6    8965 D0         mov dword ptr ss:[ebp-0x30],esp          ; 将esp=0x19FDEC存入0x19FE90
 52  52 004046B9    8B55 08         mov edx,dword ptr ss:[ebp+0x8]           ; 将0x19fefc存入edx
 53  53 004046BC    52              push edx                                 ; edx入栈,0x19fde8,[ebp-d8],edx的地址指向的值是异或后的结果
 54  54 004046BD    E8 CED7FFFF     call test.00401E90
 55  55 004046C2    8945 CC         mov dword ptr ss:[ebp-0x34],eax          ; eax=0x19FDEC,即异或后的地址存入0x19FE8C
 56  56 004046C5    C645 FC 04      mov byte ptr ss:[ebp-0x4],0x4            ; 0x4存入0x19febc
 57  57 004046C9    6A 2A           push 0x2A                                ; 将0x2a压入栈中
 58  58 004046CB    83EC 18         sub esp,0x18                             ; esp=0x19fdd0
 59  59 004046CE    8BCC            mov ecx,esp
 60  60 004046D0    8965 C8         mov dword ptr ss:[ebp-0x38],esp
 61  61 004046D3    8B45 08         mov eax,dword ptr ss:[ebp+0x8]
 62  62 004046D6    50              push eax                                 ; eax=0x19fefc
 63  63 004046D7    E8 B4D7FFFF     call test.00401E90
 64  64 004046DC    8D8D 5CFFFFFF   lea ecx,dword ptr ss:[ebp-0xA4]          ; ecx=0x19fe1c
 65  65 004046E2    51              push ecx
 66  66 004046E3    C645 FC 03      mov byte ptr ss:[ebp-0x4],0x3            ; 0x3存入0x19febc
 67  67 004046E7    8D4D F3         lea ecx,dword ptr ss:[ebp-0xD]           ; ecx=0x19feb3
 68  68 004046EA    E8 51F0FFFF     call test.00403740                       ; 自身平方
 69  69 004046EF    8945 E4         mov dword ptr ss:[ebp-0x1C],eax          ; eax=0x19fe1c
 70  70 004046F2    8B55 E4         mov edx,dword ptr ss:[ebp-0x1C]          ; edx=0x19fe1c
 71  71 004046F5    8955 E0         mov dword ptr ss:[ebp-0x20],edx
 72  72 004046F8    8B45 E0         mov eax,dword ptr ss:[ebp-0x20]          ; eax=0x19fe1c
 73  73 004046FB    50              push eax
 74  74 004046FC    8D4D 8C         lea ecx,dword ptr ss:[ebp-0x74]          ; ecx=0x19fe4c
 75  75 004046FF    E8 0CD9FFFF     call test.00402010
 76  76 00404704    8D8D 5CFFFFFF   lea ecx,dword ptr ss:[ebp-0xA4]          ; ecx=0x19fe1c
 77  77 0040470A    E8 C1D8FFFF     call test.00401FD0
 78  78 0040470F    83EC 18         sub esp,0x18                             ; esp=0x19fdec
 79  79 00404712    8BCC            mov ecx,esp
 80  80 00404714    8965 C4         mov dword ptr ss:[ebp-0x3C],esp          ; [0x19fe84]=0x19fdec
 81  81 00404717    8D95 74FFFFFF   lea edx,dword ptr ss:[ebp-0x8C]          ; edx="12345679"的地址0x19fe34
 82  82 0040471D    52              push edx                                 ; edx入栈
 83  83 0040471E    E8 CDD6FFFF     call test.00401DF0
 84  84 00404723    8945 C0         mov dword ptr ss:[ebp-0x40],eax          ; eax为"12345679"的地址,赋值到[0x19fe80]
 85  85 00404726    C645 FC 05      mov byte ptr ss:[ebp-0x4],0x5            ; [0x19febc]=0x5
 86  86 0040472A    6A 2A           push 0x2A                                ; 2a入栈
 87  87 0040472C    83EC 18         sub esp,0x18
 88  88 0040472F    8BCC            mov ecx,esp
 89  89 00404731    8965 BC         mov dword ptr ss:[ebp-0x44],esp          ; [0x19fe7c]=0x19fdd0
 90  90 00404734    8D45 8C         lea eax,dword ptr ss:[ebp-0x74]          ; 取")*0990510578848262884380342813696"的地址0x19fe4c存入eax
 91  91 00404737    50              push eax
 92  92 00404738    E8 B3D6FFFF     call test.00401DF0
 93  93 0040473D    8D8D 44FFFFFF   lea ecx,dword ptr ss:[ebp-0xBC]          ; ecx=0x19fe04
 94  94 00404743    51              push ecx
 95  95 00404744    C645 FC 03      mov byte ptr ss:[ebp-0x4],0x3            ; [0x19febc]=0x3
 96  96 00404748    8D4D F3         lea ecx,dword ptr ss:[ebp-0xD]           ; ecx=0x19feb3
 97  97 0040474B    E8 F0EFFFFF     call test.00403740                       ; 与123456789相乘
 98  98 00404750    8945 DC         mov dword ptr ss:[ebp-0x24],eax          ; "'-+4823339700468499618579595434614979584"的地址eax=0x19fe04
 99  99 00404753    8B55 DC         mov edx,dword ptr ss:[ebp-0x24]          ; edx=0x19fe04
100 100 00404756    8955 D8         mov dword ptr ss:[ebp-0x28],edx          ; [0x19fe98]=0x19fe04
101 101 00404759    8B45 D8         mov eax,dword ptr ss:[ebp-0x28]          ; eax=0x19fe04
102 102 0040475C    50              push eax                                 ; eax入栈
103 103 0040475D    8D4D A4         lea ecx,dword ptr ss:[ebp-0x5C]          ; ecx=0x19fe64
104 104 00404760    E8 ABD8FFFF     call test.00402010
105 105 00404765    8D8D 44FFFFFF   lea ecx,dword ptr ss:[ebp-0xBC]          ; ecx=0x19fe04
106 106 0040476B    E8 60D8FFFF     call test.00401FD0
107 107 00404770    8D4D A4         lea ecx,dword ptr ss:[ebp-0x5C]          ; ecx=0x19fe64
108 108 00404773    E8 48FEFFFF     call test.004045C0
109 109 00404778    8945 D4         mov dword ptr ss:[ebp-0x2C],eax          ; 将"'-+4823339700468499618579595434614979584"的地址0x5d68d0存入0x19fe94
110 110 0040477B    8B4D D4         mov ecx,dword ptr ss:[ebp-0x2C]          ; ecx=0x19fe94
111 111 0040477E    51              push ecx                                 ; s2="'-+4823339700468499618579595434614979584"
112 112 0040477F    68 78624000     push test.00406278                       ; s1="667339003789000121539302795007135856775"地址入栈
113 113 00404784    E8 0B150000     call <jmp.&api-ms-win-crt-string-l1-1-0.>; strcmp
114 114 00404789    83C4 08         add esp,0x8
115 115 0040478C    85C0            test eax,eax
116 116 0040478E    75 41           jnz Xtest.004047D1
View Code

 

地址004046EA ,调用test.00403740,进入之后可以找到一段平方的代码

 1 0040287B    8B55 F0         mov edx,dword ptr ss:[ebp-0x10]          ; 循环跳转位置
 2 0040287E    83EA 01         sub edx,0x1
 3 00402881    8955 F0         mov dword ptr ss:[ebp-0x10],edx
 4 00402884    837D F0 00      cmp dword ptr ss:[ebp-0x10],0x0
 5 00402888    0F8C 83000000   jl test.00402911                         ; 循环结束条件
 6 0040288E    8B45 F0         mov eax,dword ptr ss:[ebp-0x10]
 7 00402891    50              push eax
 8 00402892    8D4D 0C         lea ecx,dword ptr ss:[ebp+0xC]
 9 00402895    E8 16F8FFFF     call test.004020B0
10 0040289A    0FBE08          movsx ecx,byte ptr ds:[eax]              ; 将低位的一字节移动到ecx
11 0040289D    83E9 30         sub ecx,0x30
12 004028A0    8BC1            mov eax,ecx
13 004028A2    0FAF45 E0       imul eax,dword ptr ss:[ebp-0x20]
14 004028A6    0345 E8         add eax,dword ptr ss:[ebp-0x18]
15 004028A9    99              cdq
16 004028AA    B9 0A000000     mov ecx,0xA
17 004028AF    F7F9            idiv ecx
18 004028B1    8955 D8         mov dword ptr ss:[ebp-0x28],edx
19 004028B4    8B55 F0         mov edx,dword ptr ss:[ebp-0x10]
20 004028B7    52              push edx
21 004028B8    8D4D 0C         lea ecx,dword ptr ss:[ebp+0xC]
22 004028BB    E8 F0F7FFFF     call test.004020B0
23 004028C0    0FBE00          movsx eax,byte ptr ds:[eax]              ; 将低位的一字节移动到eax
24 004028C3    83E8 30         sub eax,0x30                             ; 将字符转换为整型数据
25 004028C6    0FAF45 E0       imul eax,dword ptr ss:[ebp-0x20]         ; 从低位开始一位一位的自身相乘
26 004028CA    0345 E8         add eax,dword ptr ss:[ebp-0x18]
27 004028CD    99              cdq
28 004028CE    B9 0A000000     mov ecx,0xA
29 004028D3    F7F9            idiv ecx
30 004028D5    8945 E8         mov dword ptr ss:[ebp-0x18],eax
31 004028D8    8D55 84         lea edx,dword ptr ss:[ebp-0x7C]
32 004028DB    52              push edx
33 004028DC    8B45 D8         mov eax,dword ptr ss:[ebp-0x28]
34 004028DF    83C0 30         add eax,0x30                             ; 整型转换为字符
35 004028E2    50              push eax
36 004028E3    8D8D 48FFFFFF   lea ecx,dword ptr ss:[ebp-0xB8]
37 004028E9    51              push ecx
38 004028EA    E8 01E8FFFF     call test.004010F0
39 004028EF    83C4 0C         add esp,0xC
40 004028F2    8945 C8         mov dword ptr ss:[ebp-0x38],eax
41 004028F5    8B55 C8         mov edx,dword ptr ss:[ebp-0x38]
42 004028F8    52              push edx
43 004028F9    8D4D 84         lea ecx,dword ptr ss:[ebp-0x7C]
44 004028FC    E8 0FF7FFFF     call test.00402010
45 00402901    8D8D 48FFFFFF   lea ecx,dword ptr ss:[ebp-0xB8]
46 00402907    E8 C4F6FFFF     call test.00401FD0
47 0040290C  ^ E9 6AFFFFFF     jmp test.0040287B                        ; 进行下一个循环
View Code

 

同样的,第97行代码,对字符串乘12345679也是一样

3.2 处理总结

在第109行~第113行代码,这就是一个将输入字符串前16个字符处理之后(先异或"greatctf",再自身平方,最后乘以12345679),与"667339003789000121539302795007135856775"比较。

因此,我们只需要逆向处理,就能得到输入字符的前16个字符

 

4.脚本处理

str1 = "greatctf"
num2 = 667339003789000121539302795007135856775
flag=""

num2 = num2 // 12345679
num2 = pow(num2, 0.5)
str2 = str(num2)

for i in range(16):
    flag += chr(ord(str2[i]) ^ ord(str1[i%8]))
print(flag)

 

得到前16个字符

PAPSETGQ_FRRBQLS

 

5. sub_404860函数

 1   v33 = &v21;
 2   v32 = (int *)&v25;
 3   v31 = (int *)&v23;
 4   v30 = &v22;
 5   v21 = *a1;
 6   v25 = a1[1];
 7   v26 = 0;
 8   v23 = a1[2];
 9   v24 = 0;
10   LOWORD(v22) = *((_WORD *)a1 + 6);
11   BYTE2(v22) = *((_BYTE *)a1 + 14);
12   *(_DWORD *)((char *)&v22 + 3) = *((unsigned __int8 *)a1 + 15);
13   HIBYTE(v22) = 0;
14   srand(0xBC6146u);
15   v29 = rand() % 360;
16   v20 = rand() % 360;
17   v27 = rand() % 360;
18   v28 = rand() % 360;
19   v1 = sub_404FC0(v25, v26, 3, 0);
20   v3 = v2;
21   LODWORD(v4) = sub_404FC0(v29, HIDWORD(v29), 1000, 0);
22   if ( v21 + __PAIR__(v3, v1) - v4 != 0x1A06491E7i64 )
23     goto LABEL_9;
24   v5 = sub_404FC0(v27, HIDWORD(v27), v23, v24);
25   v7 = v6;
26   LODWORD(v8) = sub_404FC0(v25, v26, v20, HIDWORD(v20));
27   if ( __PAIR__(v7, v5) - v8 != 0x244BFD2B9Ci64
28     || (v9 = sub_404FC0(v23, v24, v28, HIDWORD(v28)),
29         v11 = v10,
30         LODWORD(v12) = sub_404FC0(v22 + 890, (unsigned __int64)(v22 + 890) >> 32, v29, HIDWORD(v29)),
31         v12 + __PAIR__(v11, v9) != 0x71CE119D5i64)
32     || (v13 = sub_404FC0(v28, HIDWORD(v28), 136, 0),
33         v15 = sub_404FC0(v13, v14, v22, HIDWORD(v22)),
34         v17 = v16,
35         LODWORD(v18) = sub_404FC0(v27, HIDWORD(v27), v21, HIDWORD(v21)),
36         __PAIR__(v17, v15) - v18 != 0x431E9A36840i64) )
37   {
38 LABEL_9:
39     result = 0;
40   }
41   else
42   {
43     result = 1;
44   }
45   return result;
46 }

 

5.1 代码分析

第14行代码~第18行代码,在生成随机数,这些数在后面也会用到,因此可以写一个生成随机数的程序。

#include <bits/stdc++.h>

using namespace std;

int main(){
        int v15,v8,v14,v13;
        
        srand(0xbc6146);
        v15 = rand() % 360;
        v8 = rand() % 360;
        v13 = rand() % 360;
        v14 = rand() % 360;
        
        cout << v15 << " " << v8 << " " << v13 << " " << v14 << endl;
        
        return 0;
}

输出

2 11 192 31

又因为这个函数要返回1,使得上一层的判断成立,因此我们要让27~36行代码不成立。则,利用z3包,我们能够写出脚本

 

5.2 脚本获取

引用官方的WP给出的脚本

from z3 import *
import struct
s = [Int('serial%d' % i) for i in range(4)]
z3 = Solver()


v1 = 2
v2 = 11
v3 = 192
v4 = 31


z3.add(3*s[1]-1000*v1+s[0] == 6985912807)
z3.add(v3*s[2]-s[1]*v2 == 155893705628)
z3.add(s[2]*v4+(890+s[3])*v1 == 30549285333)
z3.add(v4*136*s[3]-v3*s[0] == 4612419708992)


print(z3.check())
answer=z3.model()
res = ""
for d in s:
    num = answer.eval(d).as_long()
    res += struct.pack('<L', num)
print(repr(res))

得到

simpleRe__360CTF

 

6.get flag!

两段组合

PAPSETGQ_FRRBQLSsimpleRe__360CTF

 

参考

1.https://mp.weixin.qq.com/s?__biz=MzUzNjYxNjQ3Ng==&mid=2247487016&idx=5&sn=4661d0ce40c10ce97be8a62ea4e8386e&chksm=faf2c55bcd854c4dfd0e1ab15a5195f4e86856212aaa5d7541a5642cd9efd525a645e2683738&mpshare=1&scene=23&srcid=&sharer_sharetime=1572355740318&sharer_shareid=30036028ee2a193ffdd181bf24ece3f8#rd

2.https://www.cnblogs.com/harmonica11/p/11723241.html

posted @ 2019-10-30 21:18  Hk_Mayfly  阅读(755)  评论(0编辑  收藏  举报