下载地址:
ftp://195.23.131.73/.disk1/gamin ... nationalCueClub.exe
软件大小: 20.4 M
是Softwrap壳,只能试用3次
International CueClub.exe的代码基本没有被破坏,只是iat表的和跳转表被Softwrap壳修改到壳中解密。
这个壳的难度是壳的解密代码是壳运行时的申请空间里的,好在这个地址是由几个固定的段中组成的。
现在的问题是怎么把这些代码放的程序的运行时可见段中来运行,因为到入口处dump下的文件中没有了
申请的临时段,这时如果把临时段的代码复制到运行时可见段中也不能正确运行,因为解密的代码是根据
申请段的地址偏移量来计算的,如果简单的复制地址偏移量不正确就无法解密出来正确的iat跳转地址。
如何在程序的可见段中得到完全正确的解密代码就是脱壳的方向,下面就沿着这个思路来解决这个问题:
跟踪程序发现几个解密段分别是01050000、01060000、01070000、01080000、和01090000五个段,并且
发现前四个段是在壳的第一部分中完成的,最后一段是在壳的第二部分完成的。这个中间是壳的sdk方式连接的
anti_debug dll(Softwrap.dll),这个dll会检测调试器和跟踪工具,以及完成crc效验等。
在OD中计算这五个段的长度是1000+1000+6000+1000+1000=A000k,在程序的可见段中始终没有找到适合存放
这些代码的地方(我第一个脱的程序把他们放到了程序的data段中的后面发现程序运行时会修改data段是所有数据
程序无法运行),最后只好在壳的程序段后面用LordPE增加一个A000k的段,为了这个增加的段会增加许多的效验问题
需要逐步的解决。
下面具体来看看:
用OD加载International CueClub.exe主程序,在异常窗口中选择忽略 单步中断 、整数被零除异常。Alt+E打开模块
窗口,选择kernel32 (system)这个dll,Ctrl+N打开kernel32 (system)dll中的所以函数名称窗口,在这个窗口中
查找VirtualAlloc这个函数,双击来到这个函数的入口:
77E5AC72 >PUSH EBP
77E5AC73 MOV EBP,ESP
77E5AC75 PUSH DWORD PTR SS:[EBP+14]
77E5AC78 PUSH DWORD PTR SS:[EBP+10]
77E5AC7B PUSH DWORD PTR SS:[EBP+C]
77E5AC7E PUSH DWORD PTR SS:[EBP+8]
77E5AC81 PUSH -1
77E5AC83 CALL kernel32.VirtualAllocEx
77E5AC88 POP EBP
77E5AC89 RETN 10
在第一行下内存访问中断断点,记住不能用F2下断点。
为什么要对这个函数下断点?因为壳用这个函数来申请临时空间存放解密代码的所以必须对这个函数下断点。
F9运行程序,首先被中断在:
009D2ABF MOV AL,BYTE PTR DS:[EAX]
009D2AC1 ADD AL,0F
009D2AC3 JE SHORT Internat.009D2AD6
009D2AC5 NEG AL
009D2AC7 SUB AL,23
009D2AC9 JE SHORT Internat.009D2AD6
009D2ACB DEC AL
009D2ACD JE SHORT Internat.009D2AD6
009D2ACF DEC AL
009D2AD1 JE SHORT Internat.009D2AD6
009D2AD3 CLC
009D2AD4 JMP SHORT Internat.009D2AF7
这是可对这个函数的前几个字节验证,所以只能下内存访问断点。
F9继续运行,这次会中断在函数的入口中:
77E5AC72 >PUSH EBP ; Internat.009D1688
77E5AC73 MOV EBP,ESP
77E5AC75 PUSH DWORD PTR SS:[EBP+14]
77E5AC78 PUSH DWORD PTR SS:[EBP+10]
77E5AC7B PUSH DWORD PTR SS:[EBP+C]
77E5AC7E PUSH DWORD PTR SS:[EBP+8]
77E5AC81 PUSH -1
77E5AC83 CALL kernel32.VirtualAllocEx
77E5AC88 POP EBP
77E5AC89 RETN 10
壳现在用这个函数申请临时空间了。运行到RETN 10处时发现EAX=01050000,这就是申请的临时段地址,用鼠标双击EAX
修改这个值=009D6000 (增加的段中),继续运行再次被中断在这个函数中,发现EAX=01060000,这是申请的第二个临时
段,双击EAX修改这个值=009D7000,再次运行会再次中断在这个函数中,发现EAX=01070000,修改这个值=009D8000,又
一次运行中断后发现EAX=01080000,修改这个值=009DD000。现在申请的段地址全部被修改到增加的段中了。
F9运行,被中断在:
009D2ABF MOV AL,BYTE PTR DS:[EAX]
009D2AC1 ADD AL,0F
009D2AC3 JE SHORT Internat.009D2AD6
009D2AC5 NEG AL
009D2AC7 SUB AL,23
009D2AC9 JE SHORT Internat.009D2AD6
009D2ACB DEC AL
009D2ACD JE SHORT Internat.009D2AD6
009D2ACF DEC AL
009D2AD1 JE SHORT Internat.009D2AD6
009D2AD3 CLC
009D2AD4 JMP SHORT Internat.009D2AF7
壳又一次验证这个函数的代码了。
F9继续,到这里:
009D30FA MOV AL,BYTE PTR DS:[ECX]
009D30FC INC ECX
009D30FD OR EDX,DWORD PTR DS:[ESI+EAX*4]
009D3100 TEST DL,8
009D3103 JNZ SHORT Internat.009D30F7
009D3105 CMP AL,0F6
009D3107 JE SHORT Internat.009D313F
009D3109 CMP AL,0F7
009D310B JE SHORT Internat.009D313F
009D310D CMP AL,0CD
009D310F JE SHORT Internat.009D314C
009D3111 CMP AL,0F
009D3113 JE SHORT Internat.009D3159
009D3115 TEST DH,80
009D3118 JNZ SHORT Internat.009D316C
009D311A TEST DH,40
009D311D JNZ SHORT Internat.009D3192
009D311F TEST DL,20
009D3122 JNZ SHORT Internat.009D3178
009D3124 TEST DH,20
009D3127 JNZ SHORT Internat.009D3185
009D3129 MOV EAX,ECX
009D312B SUB EAX,DWORD PTR SS:[ESP+28]
009D312F AND EDX,707
009D3135 ADD AL,DL
009D3137 ADD AL,DH
009D3139 MOV DWORD PTR SS:[ESP+1C],EAX
009D313D POPAD
009D313E RETN
F9继续,到这里:
009D2CBF PUSH EBP
009D2CC0 MOV EBP,ESP
009D2CC2 ADD ESP,-11C
009D2CC8 PUSHAD
009D2CC9 MOV EAX,DWORD PTR SS:[EBP+10]
009D2CCC MOV DWORD PTR SS:[EBP-8],EAX
009D2CCF MOV EAX,DWORD PTR SS:[EBP+C]
009D2CD2 MOV DWORD PTR SS:[EBP-C],EAX
009D2CD5 SUB EAX,EAX
009D2CD7 LEA EDI,DWORD PTR SS:[EBP-11C]
009D2CDD MOV ECX,40
009D2CE2 REP STOS DWORD PTR ES:[EDI]
009D2CE4 LEA EDI,DWORD PTR SS:[EBP-18]
009D2CE7 STOS DWORD PTR ES:[EDI]
009D2CE8 LEA EDI,DWORD PTR SS:[EBP-1C]
009D2CEB STOS DWORD PTR ES:[EDI]
009D2CEC LEA EDI,DWORD PTR SS:[EBP-10]
009D2CEF STOS DWORD PTR ES:[EDI]
009D2CF0 XCHG EAX,EBX
009D2CF1 CMP DWORD PTR SS:[EBP+14],0
009D2CF5 JE Internat.009D2DBD
009D2CFB DEC DWORD PTR SS:[EBP+14]
009D2CFE PUSH DWORD PTR SS:[EBP-8]
009D2D01 PUSH DWORD PTR SS:[EBP+8]
009D2D04 CALL Internat.009D30EA
009D2D09 ADD ESP,8
009D2D0C CMP EAX,-1
009D2D0F ADD DWORD PTR SS:[EBP-1C],EAX
009D2D12 MOV DWORD PTR SS:[EBP-4],EAX
009D2D15 SUB EBX,EBX
009D2D17 MOV ESI,DWORD PTR SS:[EBP-8]
009D2D1A LODS WORD PTR DS:[ESI]
009D2D1C CMP AL,0E2
009D2D1E JE Internat.009D2DDD
009D2D24 CMP AL,0E1
009D2D26 JE Internat.009D2DDD
009D2D2C CMP AL,0E0
009D2D2E JE Internat.009D2DDD
009D2D34 CMP AL,0CC
009D2D36 CMP AL,0E8
009D2D38 JE Internat.009D2F40
009D2D3E CMP AL,0C3
009D2D40 JE Internat.009D2F25
009D2D46 CMP AL,0C2
009D2D48 JE Internat.009D2F25
009D2D4E CMP AX,15FF
009D2D52 JE Internat.009D2EE5
009D2D58 CMP AL,0E9
009D2D5A JE Internat.009D2ECF
009D2D60 CMP AX,25FF
009D2D64 JE Internat.009D2EB4
009D2D6A CMP AL,0EB
009D2D6C JE Internat.009D2E9D
009D2D72 CMP AL,0E3
009D2D74 JE Internat.009D2E01
009D2D7A MOV BX,AX
009D2D7D SHR BL,4
009D2D80 CMP BL,7
009D2D83 JE SHORT Internat.009D2E01
009D2D85 MOV BX,AX
009D2D88 CMP BL,0F
009D2D8B JNZ SHORT Internat.009D2D99
009D2D8D SHR EBX,0C
009D2D90 CMP BL,8
009D2D93 JE Internat.009D2E76
009D2D99 MOV EDI,DWORD PTR SS:[EBP-C]
009D2D9C MOV ESI,DWORD PTR SS:[EBP-8]
009D2D9F MOV ECX,DWORD PTR SS:[EBP-4]
009D2DA2 REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]
009D2DA4 CMP DWORD PTR SS:[EBP-10],0E
009D2DA8 JA SHORT Internat.009D2DAA
009D2DAA MOV EAX,DWORD PTR SS:[EBP-4]
009D2DAD SUB DWORD PTR SS:[EBP-10],EAX
009D2DB0 ADD DWORD PTR SS:[EBP-8],EAX
009D2DB3 ADD EAX,ECX
009D2DB5 ADD DWORD PTR SS:[EBP-C],EAX
009D2DB8 JMP Internat.009D2CF1
009D2DBD MOV EDX,DWORD PTR SS:[EBP-8]
009D2DC0 MOV EBX,DWORD PTR SS:[EBP-C]
009D2DC3 SUB EDX,5
009D2DC6 SUB EDX,EBX
009D2DC8 MOV BYTE PTR DS:[EBX],0E9
009D2DCB MOV DWORD PTR DS:[EBX+1],EDX
009D2DCE MOV EAX,DWORD PTR SS:[EBP-C]
009D2DD1 ADD EAX,5
009D2DD4 MOV DWORD PTR SS:[ESP+1C],EAX
009D2DD8 POPAD
009D2DD9 LEAVE
009D2DDA RETN 10
这个代码就是壳把函数的前面字节代码复制到壳的解密段中,然后程序运行时先在壳中运行一段API代码再jmp的
函数中,这样就避免了对API函数下中断了,因为API函数的前面几行代码不在函数中运行了。自然是不能中断了。
修改这段的代码可以得到完整的IAT表,这里就不说了。因为比较免费,且这个程序可以用壳的代码来直接解密
IAT表运行。
F4到 009D2DDA RETN 10
F8运行到:
009D33B9 MOV DWORD PTR SS:[EBP+1B6A],EAX ; Internat.009D8A96
009D33BF POP EAX
009D33C0 MOV EBX,DWORD PTR SS:[EBP+28D8]
009D33C6 LEA EDX,DWORD PTR DS:[ESI-8]
009D33C9 SUB EDX,DWORD PTR SS:[EBP+28EC]
009D33CF SHR EDX,1
009D33D1 ADD EBX,4
009D33D4 XOR EAX,186177C9
009D33D9 MOV DWORD PTR DS:[EBX+EDX],EAX
009D33DC JMP Internat.009D3334
继续:
009D3334 CMP ESI,DWORD PTR SS:[EBP+28BC] ; Internat.009D4FB0
009D333A JA Internat.009D33E1
009D3340 LODS DWORD PTR DS:[ESI]
009D3341 MOV EBX,EAX
009D3343 LODS DWORD PTR DS:[ESI]
009D3344 MOV DWORD PTR DS:[ESI-4],0
009D334B MOV DWORD PTR DS:[ESI-8],0
009D3352 TEST EAX,EAX
009D3354 JE Internat.009D33E1
009D335A TEST BL,1
009D335D JNZ SHORT Internat.009D337F
009D335F PUSH EAX
009D3360 PUSH DWORD PTR SS:[EBP+28A0]
009D3366 CALL Internat.009D2B71
009D336B XLAT BYTE PTR DS:[EBX+AL]
009D336C XOR CH,BYTE PTR DS:[ECX]
009D336E PUSH CS
009D336F IMUL ECX,EBP,736F14D7
009D3375 TEST EAX,EAX
009D3377 JE Internat.009D341A
009D337D JMP SHORT Internat.009D339A
如果要跟踪到没有解密的IAT表可以修改代码,我不想这样了,所以在
009D333A JA Internat.009D33E1 回车
009D33E1 INC ECX
009D33E2 JMP Internat.009D327D <--这里回车
到这里:
009D327D CMP ECX,DWORD PTR SS:[EBP+28C4]
009D3283 JE Internat.009D33E7 //修改这个跳转,到009D33E7
009D3289 MOV EDI,DWORD PTR SS:[EBP+28F0]
009D328F MOV EAX,DWORD PTR SS:[EBP+28F8]
009D3295 LEA EAX,DWORD PTR DS:[EAX+ECX*4]
009D3298 ADD EDI,DWORD PTR DS:[EAX]
009D329A PUSHAD
009D329B PUSH EDI
009D329C MOV EAX,ECX
009D329E SHL EAX,2
009D32A1 PUSH EAX
009D32A2 CALL Internat.009D2C39
然后运行到:
009D2720 CMP EAX,DWORD PTR DS:[EDX+C]
009D2723 JNZ Internat.009D1F0A
009D2729 PUSH ECX
009D272A PUSH EDI
009D272B XOR EAX,EAX
009D272D MOV EDI,EDX
009D272F MOV ECX,8
009D2734 REP STOS DWORD PTR ES:[EDI]
009D2736 POP EDI
009D2737 POP ECX
009D2738 DEC ECX
009D2739 LEA EDX,DWORD PTR DS:[EDX+20]
009D273C JNZ SHORT Internat.009D26EF
009D273E POPAD
009D273F ADD DWORD PTR SS:[ESP],6
009D2743 RETN
这个代码是壳对程序的CRC效验的地方,一共3次验证,修改JNZ Internat.009D1F0A 这个跳转就可以避免CRC验证。
F8运行:
009D3670 PUSH EBX
009D3671 MOV EBX,ESP
009D3673 SUB ESP,104
009D3679 PUSHAD
009D367A LEA EDI,DWORD PTR DS:[EBX-104]
009D3680 MOV DWORD PTR DS:[EDI],74666F73
009D3686 MOV DWORD PTR DS:[EDI+4],70617277
009D368D MOV DWORD PTR DS:[EDI+8],6C6C642E
009D3694 AND DWORD PTR DS:[EDI+C],0
009D3698 PUSH EDI
009D3699 PUSH EBX
009D369A PUSH EDI
009D369B CALL DWORD PTR SS:[EBP+2D7C]
009D36A1 POP EBX
009D36A2 POP EDI
009D36A3 MOV DWORD PTR DS:[EBX-4],EAX
009D36A6 PUSH EAX
009D36A7 CALL Internat.009D39F4
009D36AC TEST EAX,EAX
009D36AE JE Internat.009D1F0A
009D36B4 MOV WORD PTR SS:[EBP+20FC],AX
009D36BB MOV DWORD PTR DS:[EDI],63417773
009D36C1 MOV DWORD PTR DS:[EDI+4],73736563
009D36C8 MOV DWORD PTR DS:[EDI+8],72657551
009D36CF MOV DWORD PTR DS:[EDI+C],79
009D36D6 PUSH ESI
009D36D7 PUSH EDI
009D36D8 PUSH EBX
009D36D9 PUSH ECX
009D36DA PUSH EDX
009D36DB PUSH EDI
009D36DC PUSH DWORD PTR DS:[EBX-4]
009D36DF CALL DWORD PTR SS:[EBP+2D74]
009D36E5 POP EDX
009D36E6 POP ECX
009D36E7 POP EBX
009D36E8 POP EDI
009D36E9 POP ESI
009D36EA TEST EAX,EAX
009D36EC JE Internat.009D1F0A
009D36F2 MOV EDX,EAX
009D36F4 MOV EAX,DWORD PTR SS:[EBP+C7E]
009D36FA XOR EAX,FA179D15
009D36FF ADD EAX,DWORD PTR SS:[EBP+C7E]
009D3705 MOV DWORD PTR SS:[EBP+2100],EAX
009D370B LEA ESI,DWORD PTR SS:[EBP+210C]
009D3711 MOV EDI,ESI
009D3713 MOV ECX,40
009D3718 REP STOS DWORD PTR ES:[EDI]
009D371A PUSH EBX
009D371B PUSH EDI
009D371C PUSH ESI
009D371D PUSH DWORD PTR DS:[EBX+8]
009D3720 PUSH ESI
009D3721 PUSH EAX
009D3722 CALL EDX
009D3724 ADD ESP,0C
009D3727 MOV DWORD PTR SS:[EBP+20F8],EAX
009D372D POP ESI
009D372E POP EDI
009D372F POP EBX
009D3730 LEA EAX,DWORD PTR SS:[EBP+20F8]
009D3736 PUSH EAX
009D3737 PUSH ESI
009D3738 CALL Internat.009D3894
009D373D ADD ESI,8
009D3740 CMP ESI,EDI
009D3742 JNZ SHORT Internat.009D3730
009D3744 MOV EDX,DWORD PTR SS:[EBP+2100]
009D374A MOV ECX,40
009D374F SUB ESI,100
009D3755 XOR EDX,EDX
009D3757 LODS DWORD PTR DS:[ESI]
009D3758 ADD EDX,EAX
009D375A DEC ECX
009D375B JNZ SHORT Internat.009D3757
009D375D SUB EDX,DWORD PTR SS:[EBP+2108]
009D3763 JNZ SHORT Internat.009D3779
009D3765 PUSH DWORD PTR DS:[EBX-4]
009D3768 CALL DWORD PTR SS:[EBP+2B9F]
009D376E POPAD
009D376F MOV ESP,EBX
009D3771 POP EBX
009D3772 ADD DWORD PTR SS:[ESP],5
009D3776 RETN 4
这个段就是壳的sdk接口代码,分析发现这个代码是以PUSHAD 入口到 POPAD 结束的接口,就是说这个接口是
可以越过的。(如果不越过,后面的壳效验太麻烦了)
运行到009D367A LEA EDI,DWORD PTR DS:[EBX-104],这时PUSHAD有效了,然后光标移动到009D376E POPAD
右击现在选择 在此处新建EIP,呵呵这样躲过了sdk的验证了。
第一部分完成了。
下面到了第二部分
F9运行,中断到异常:
009D23B1 UD2
009D23B3 POPAD
009D23B4 ADD DWORD PTR SS:[ESP],6
009D23B8 RETN
Shift+F9运行,被中断在:
77E5AC72 PUSH EBP ; Internat.009D1688
77E5AC73 MOV EBP,ESP
77E5AC75 PUSH DWORD PTR SS:[EBP+14]
77E5AC78 PUSH DWORD PTR SS:[EBP+10]
77E5AC7B PUSH DWORD PTR SS:[EBP+C]
77E5AC7E PUSH DWORD PTR SS:[EBP+8]
77E5AC81 PUSH -1
77E5AC83 CALL kernel32.VirtualAllocEx
77E5AC88 POP EBP
77E5AC89 RETN 10
呵呵又到VirtualAlloc函数中了,最后一个解密的临时段申请的时候到了,运行到RETN 10 发现EAX=01090000
修改这个值=009DE000 到这里解密段的修改全部完成了。按我的愿望修改到了增加的段中了。
F9运行到异常:
009D1D15 UD2
009D1D17 CALL Internat.009D3499
009D1D1C LOCK PFCMPGE MM0,QWORD PTR SS:[EBP+ECX*8+E80B0F2F] ; 锁定前缀是不允许的
009D1D26 PUSH ES
009D1D27 ADD BYTE PTR DS:[EAX],AL
009D1D29 JE SHORT Internat.009D1D11
和:
009D1D22 UD2
009D1D24 CALL Internat.009D23B9
009D1D29 JE SHORT Internat.009D1D11
009D1D2B CMP BYTE PTR DS:[3471516C],CH
009D1D31 PUSHAD
下面到了计算入口的地方了。这个入口的计算竟然用到了CRC值,所以继续运行会异常退出,为了这个异常退出,我化了近一天的时间来解决,原因是这个代码的运行是靠单步中断异常运行的。次数大得惊人,单步可能要一天也不一定能运行完。现在说来简单些了:
先Ctrl+G到:
009D1DFC MOV AH,92
009D1DFE JMP 1CBA08A0
009D1E03 NOP ; 多余的前缀
009D1E05 JECXZ SHORT Internat.009D1DC6
009D1E07 MOV BH,0B9
009D1E09 JNO SHORT Internat.009D1DBC
009D1E0B XCHG EAX,ECX
009D1E0C JMP FAR 7D64:62C17C7C ; 远距跳转
009D1E13 SHR ECX,0E9 ; 移动常数超出 1..31 的范围
009D1E16 JMP FAR B9E7:95F96228 ; 远距跳转
009D1E1D MOV EBX,75B1B370
009D1E22 JE SHORT Internat.009D1DB8
009D1E24 IN AL,DX ; I/O 命令
009D1E25 MOV EDI,33B71C62
009D1E2A XCHG EAX,ESI
009D1E2B STD
009D1E2C ADD ECX,EBP
009D1E2E JMP FE0C081C
009D1E33 INT 0B3
009D1E35 JLE SHORT Internat.009D1EB5
009D1E37 XCHG EAX,EDI
009D1E38 OUT DX,AL ; I/O 命令
009D1E39 OUTS DX,BYTE PTR ES:[EDI] ; I/O 命令
009D1E3A AAD 0CD
009D1E3C OUTS DX,BYTE PTR ES:[EDI] ; I/O 命令
009D1E3D AAD 0CD
009D1E3F XOR EAX,E9EC668D
009D1E44 JMP 2E080832
在上面的代码中下访问中断,运行中断在:
009D1D64 LODS BYTE PTR DS:[ESI]
009D1D65 FADDP ST(3),ST
009D1D67 INC EDI
009D1D68 MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]
009D1D69 CWDE
009D1D6A DIV DWORD PTR DS:[EAX-73]
009D1D6D MOV EBP,533
009D1D72 MOV ECX,1BC
009D1D77 REP STOS BYTE PTR ES:[EDI]
009D1D79 JPE SHORT Internat.009D1D87
009D1D7B JNS SHORT Internat.009D1D7D
这是单步异常对上面段的解密代码,运行直到:
009D1E08 PUSH EAX
009D1E09 CWDE
009D1E0A POP EAX
009D1E0B JS SHORT Internat.009D1E10 //断点
上面的代码完成了解码,在
009D1E0B JS SHORT Internat.009D1E10 下中断,取消原来的断点,运行到这个地方,发现EAX=896817BD这个是因为程序增加了段长度和时间等改变了,所以这个入口值是错误的,要修改为正确的值EAX=0003C66C
然后可以在内存窗口中对程序的代码段下访问中断,运行就会停在程序的OEP处:
0043C66C >PUSH EBP
0043C66D MOV EBP,ESP
0043C66F PUSH -1
0043C671 PUSH Internat.00446AB0
0043C676 PUSH Internat.00440FBC ; SE handler installation
0043C67B MOV EAX,DWORD PTR FS:[0]
0043C681 PUSH EAX
0043C682 MOV DWORD PTR FS:[0],ESP
0043C689 SUB ESP,58
0043C68C PUSH EBX
0043C68D PUSH ESI
0043C68E PUSH EDI
0043C68F MOV DWORD PTR SS:[EBP-18],ESP
0043C692 CALL DWORD PTR DS:[9D1200] ; Internat.009D3B90
另外这样脱出来的程序代码有问题,可以用直接dump下的代码来修复。然后用LordPE增加iat表中的函数就可以运行了。
fxyang
2004.9.3 晚
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课