Anti StrongOD Kernel Mode

/**************************************
/* 作者:半斤八兩
/* 博客:http://cnblogs.com/bjblcracked
/* 日期:2013-12-11  00:00
/**************************************


只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!


  相信大家都有用过海风前辈写的strongod反反调试插件.用起来是十分方便的. strongod 是属于驱动级别的插件, 如果是我们自己写的应用层软件,如何来对付strongod呢? 

在strongod早些版本的时候,我们是可以通过符号链接来做检测的.早些版本符号链接是写死的.

名为 fengyue .但是到后来,符号链接,弄成自定义的了,缺省的,还是不变的. 大多数人都会通过strongod的ini配置文件来修改缺省的名字. 

它的INI配置是直接写入OD 的 ollydbg.ini 里面. 打开ollydbg.ini 直接搜索 strongod 就能搜到如下内容, 

[Plugin StrongOD]
CreateProcessMode=0
HidePEB=1
IsPatchFloat=1
IsAdvGoto=1
KernelMode=1
KillPEBug=1
SuperEnumMod=1
AdvAttach=1
SkipExpection=1
HideWindow=1
HideProcess=1
ProtectProcess=1
DriverKey=-82693034
DriverName=fengyue
OrdFirst=0
BreakOnLdr=0
BreakOnTls=0
RemoveEpOneShot=1
ShowBar=17
LoadSym=1
AutoUpdate=0
UpdateURL=http://sod.ibt.name/update.txt

其中 DriverName=fengyue 就是我们关心的. 虽然现在符号连接是"随机的" 但是我们还是有办法获取真实的符号链接名~ 具体的看源码吧. 

 

  1 DWORD IsEnumProcess()
  2 {
  3     DWORD dwPidTemp = 0;
  4     
  5     HANDLE procSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  6     if(procSnap == INVALID_HANDLE_VALUE)
  7     {
  8         return -1;
  9     }
 10     
 11     PROCESSENTRY32 procEntry = {0};
 12     
 13     procEntry.dwSize = sizeof(PROCESSENTRY32);
 14     
 15     BOOL bRet = Process32First(procSnap,&procEntry);
 16     
 17     while(bRet)
 18     {
 19         if(0 == strcmp(procEntry.szExeFile, "csrss.exe"))
 20         {
 21             dwPidTemp = procEntry.th32ProcessID;
 22             return TRUE;
 23         }
 24         
 25         bRet = Process32Next(procSnap, &procEntry);
 26     }
 27     
 28     CloseHandle(procSnap);
 29     
 30     return dwPidTemp;
 31 }
 32 
 33 
 34 BOOL CCheckStrongOD::IsDebugSymbolicLink()
 35 {
 36     UNICODE_STRING     strDirName;
 37     OBJECT_ATTRIBUTES  oba;
 38     NTSTATUS           ntStatus; 
 39     HANDLE             hDirectory;
 40     
 41     RtlInitUnicodeString(&strDirName, L"\\global??");
 42     InitializeObjectAttributes(&oba, &strDirName, OBJ_CASE_INSENSITIVE, NULL, NULL);
 43     
 44     ntStatus = ZwOpenDirectoryObject(&hDirectory, DIRECTORY_QUERY, &oba);
 45 
 46     if (ntStatus != STATUS_SUCCESS)
 47     {
 48         if (hDirectory != NULL)
 49         {
 50             ZwClose(hDirectory);
 51         }
 52         
 53         return NULL;
 54     }
 55     
 56     UNICODE_STRING symbolicLink;
 57     BYTE           buffer[2048] = {0};
 58     ULONG          ulLength  = 2048;
 59     ULONG          ulContext = 0;
 60     ULONG          ulRet     = 0;
 61 
 62     RtlInitUnicodeString(&symbolicLink, L"SymbolicLink");
 63     
 64     tagSTRONGOD tagStrongOD = {0};
 65     
 66     tagStrongOD.m_dwFlag = 123456789;
 67     tagStrongOD.m_dwCressPID = IsEnumProcess();
 68     tagStrongOD.m_wMePid = (WORD)GetCurrentProcessId();
 69 
 70     do{
 71         ntStatus = ZwQueryDirectoryObject(hDirectory, buffer, ulLength,
 72             TRUE, FALSE, &ulContext, &ulRet);
 73 
 74         if ((ntStatus != STATUS_SUCCESS) && (ntStatus != STATUS_NO_MORE_ENTRIES))
 75         {
 76             if (hDirectory != NULL)
 77             {
 78                 ZwClose(hDirectory);
 79             }
 80         }
 81         else if (STATUS_NO_MORE_ENTRIES == ntStatus)
 82         {
 83             if (hDirectory != NULL)
 84             {
 85                 ZwClose(hDirectory);
 86             }
 87             
 88             return NULL;
 89         }
 90 
 91         PDIRECTORY_BASIC_INFORMATION  directoryInfo = (PDIRECTORY_BASIC_INFORMATION)buffer;
 92        
 93         WCHAR szSymbolicLink[MAXBYTE] = L"\\\\.\\";
 94         wcscat(szSymbolicLink, directoryInfo->ObjectName.Buffer);
 95 
 96         int nLen = wcslen(szSymbolicLink);
 97 
 98         if(nLen > 0xc)
 99         {
100             continue;
101         }
102 
103         BYTE szControlCode1[MAXBYTE] = {0};
104         DWORD dwBytesReturned = 0;
105 
106         HANDLE hFile = 
107             CreateFileW(szSymbolicLink, GENERIC_READ|GENERIC_WRITE,
108             FILE_SHARE_READ|FILE_SHARE_WRITE,
109             NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
110 
111         if(hFile != (HANDLE)-1)
112         {
113 
114         }
115         else
116         {
117             continue;
118         }
119 
120         *(PDWORD)&szControlCode1[0] = tagStrongOD.m_dwFlag;
121         *(PDWORD)&szControlCode1[4] = tagStrongOD.m_dwCressPID;
122         *(PDWORD)&szControlCode1[8] = 1;
123         *(PDWORD)&szControlCode1[0xc] = 1;
124         *(PDWORD)&szControlCode1[0x10] = 1;
125         *(PDWORD)&szControlCode1[0x14] = 1;
126         *(PDWORD)&szControlCode1[0x18] = 1;
127         *(PDWORD)&szControlCode1[0x1c] = 0;
128         *(PWORD)&szControlCode1[0x20] = tagStrongOD.m_wMePid;
129         *(PWORD)&szControlCode1[0x22] = 0;
130 
131         BYTE szControlCode2[0x24] = {
132             0x42, 0xa3, 0x53, 0x04, 0x4D, 0x4B, 0xA3, 0xC4, 0xEC, 0xF8, 
133             0xE5, 0x41, 0x9D, 0xEF, 0xAE, 0x46, 0x95, 0x59, 0x7D, 0xF3, 
134             0x98, 0xBD, 0xDC, 0xD4, 0x1F, 0xE9, 0xC1, 0xD9, 0xFB, 0xF1, 
135             0xE9, 0x8D, 0x85, 0x0B, 0x7B, 0x14};
136 
137 
138         BYTE szOutBuffer[0x4] = {0xff, 0xff, 0xff, 0xff};
139 
140         for(int i = 0; i < 0x24; i++)
141         {
142             szControlCode1[i] ^= szControlCode2[i];
143         }
144 
145 
146         if(TRUE == DeviceIoControl(hFile, 0x22215c, 
147             szControlCode2, 0x24, NULL, 0, &dwBytesReturned, NULL))
148         {
149 
150         }
151         else
152         {
153             CloseHandle(hFile);
154             continue;
155         }
156 
157         *(PDWORD)&szControlCode1[0] = tagStrongOD.m_dwFlag;
158         *(PDWORD)&szControlCode1[4] = 0;
159         *(PDWORD)&szControlCode1[8] = 0;
160         *(PDWORD)&szControlCode1[0xc] = 0;
161         *(PDWORD)&szControlCode1[0x10] = 0;
162         *(PDWORD)&szControlCode1[0x14] = 0;
163         *(PDWORD)&szControlCode1[0x18] = 0;
164         *(PDWORD)&szControlCode1[0x1c] = 0;
165         *(PWORD)&szControlCode1[0x20] = 0;
166         *(PWORD)&szControlCode1[0x22] = 0;
167 
168 
169         for(i = 0; i < 0x24; i++)
170         {
171             szControlCode1[i] ^= szControlCode2[i];
172         }
173 
174         if(0 == DeviceIoControl(hFile, 0x222178, szControlCode1,
175             0x24, NULL, 0, &dwBytesReturned, NULL))
176         {
177             
178         }
179         else
180         {
181             CloseHandle(hFile);
182             continue;
183         }
184 
185         
186 
187         *(PDWORD)&szControlCode1[0] = tagStrongOD.m_dwFlag;
188         *(PDWORD)&szControlCode1[4] = 0;
189         *(PDWORD)&szControlCode1[8] = 0;
190         *(PDWORD)&szControlCode1[0xc] = 0;
191         *(PDWORD)&szControlCode1[0x10] = 0;
192         *(PDWORD)&szControlCode1[0x14] = 0;
193         *(PDWORD)&szControlCode1[0x18] = 0;
194         *(PDWORD)&szControlCode1[0x1c] = 0;
195         *(PWORD)&szControlCode1[0x20] = tagStrongOD.m_wMePid;
196         *(PWORD)&szControlCode1[0x22] = 0;
197 
198 
199         for(i = 0; i < 0x24; i++)
200         {
201             szControlCode1[i] ^= szControlCode2[i];
202         }
203 
204 
205 
206         if(TRUE == DeviceIoControl(hFile, 0x222160, szControlCode2,
207             0x24, szOutBuffer, 0x4, &dwBytesReturned, NULL))
208         {
209 //            MessageBox(0, 0, 0, 0);
210 
211             _putws(szSymbolicLink);
212 
213             return TRUE;
214         }
215         else
216         {
217             CloseHandle(hFile);
218             continue;
219         }
220 
221     }while(TRUE);
222 
223 
224     if (hDirectory != NULL)
225     {
226         ZwClose(hDirectory);
227     }
228 
229     return FALSE;
230 }
231 
232 
233 CCheckStrongOD::CCheckStrongOD()
234 {
235     system("chcp 936 & cls & color 0a & title 检测StrongOD Kernel Mode");
236 }
237 
238 CCheckStrongOD::~CCheckStrongOD()
239 {
240     system("pause");
241 }

 


本文没任何技术含量,只是一个思路~ 抛砖~ 

 

SRC和BIN下载地址:<<<看雪学院>>>

转载于:https://www.cnblogs.com/BjblCracked/p/3470351.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
OllyDBG v1.10 plugin - StrongOD v0.2.6 by 海风月影[CUG] ==================================================================== [2009.09.01 v0.2.6.413] 1,添加加载微软符号库的选项 2,Cmdbar增加命令MSG,显示消息号 [2009.08.26 v0.2.6.410] 1,集成Command Bar功能(快捷键改成ALT+F1),可以抛弃cmdbar插件了 2,Cmdbar和TBAR插件兼容 [2009.08.24 v0.2.6.405] 1,全面支持win7(7600以下版本不支持) 2,增强解析PE的稳定性 3,修复tmd壳某些时候attach上去无法下断点的漏洞 [2009.06.16 v0.2.5.388] 1,增加ring0稳定性 2,尝试杀掉NP线程 [2009.06.13 v0.2.5.384] 1,修复驱动几个bug,去掉字符串 2,稳定性增加,不再需要key [2009.04.24 v0.2.4.364] 1,驱动有很大改动,加了一些功能,与以前的StrongOD不兼容,更新后需要重启机器 2,启动时检查ollydbg中的可疑线程 3,继续修改attach功能 4,修复加壳后无法使用远程注入的功能 [2009.04.03 v0.2.4.350] 1,修复驱动在某些2000下蓝屏的BUG 2,修复驱动的几个BUG 3,加key验证,需要StrongOD.key才能运行 [2009.03.30 v0.2.4.347] 1,修复vista下attach异常的问题 2,增强attach的稳定性,Attach后需要F9,然后resume all thread 3,advenummod支持动态卷,网络映射盘 4,vista sp1下无法打开文件的bug 5,vista下父进程修改 [2009.03.17 v0.2.4.341] 1,退出OD去掉ZwOpenThread的hook 2,修复OD处理codebase会崩溃的BUG 3,驱动不会影响非OD调试程序的情况 [2009.03.09 v0.2.3.328] 1,增强进程保护(保护线程),省得老毛子麻烦 2,修复一个导入表分析的错误 3,修复处理重定位表的BUG 4,修复attach notepad.exe的BUG 5,修复处理导出表的bug 6,修复处理tls的BUG [2009.02.14 v0.2.3.314] 1,修复了2003 sp1下蓝屏bug(感谢cxh852456) 2,增强快捷键兼容性,支持简单修改版的OD [2009.02.10 v0.2.3.305] 1,修复几个小BUG 2,增强attach功能 3,修复某个BUG [2009.02.04 v0.2.3.301] 1,底部快捷栏自动记录是否隐藏 2,底部状态栏显示Memory窗口状态 3,修复驱动不加载的bug [2009.02.01 v0.2.3.299] 1,增加多个内存窗口的快速切换,快捷键 alt+1 ~ alt+5 2,增加切换堆栈窗口关联到ebp寄存器或者不关联任何寄存器,快捷键 alt+1 ~ alt+3 3,增加一个底部的快捷栏,上面有快速切换的按钮,Option里面可以取消创建这个快捷栏, 如果创建后可以用Alt+R来显示,隐藏快捷栏 4,底部的快捷栏是否创建,不影响上面快速切换的功能(没有按钮可以用快捷键来切换) [2009.01.14 v0.2.2.292] 1,修复一些解析PE的小bug 2,修复内存断点判断的一个小bug [2009.01.14 v0.2.2.283] 1,修复一些小bug 2,修复驱动一个bug [2009.01.11 v0.2.2.275] 1,增加选项删除入口点断点 2,增加选项中断在Tls入口(如果有的话),必须选上Kill Pe Bug 3,增加选项中断在进ring3的第一行代码(是否实现,待定) 4,配置文件中增加OrdFirst,决定mfc42中的导出函数是序号优先还是名字优先 5,修复处理重定位表的bug 6,Attach窗口的鼠标滚轮改成WM_VSCROLL消息 [2009.01.08 v0.2.1.273] 1,修正处理导出表和导入表的bug 2,修正处理重定位表的bug 3,修复Skip Some Expection选上的时候对内存段下F2断点无法正常断下的bug 4,修复Skip Some Expection选上的时候内存断点无法断下的BUG 5,修复IAT中序号找不到函数名的BUG [2009.01.06 v0.2.1.262] 1,增加Attach窗口的鼠标滚轮支持 2,重写od处理模块的代码 [2008.12.30 v0.2.1.252] 1,修复驱动BUG [2008.12.25 v0.2.1.235] 1,修复一个利用PAGE_GUARD的anti 2,修复Skip Some Expection选上的时候无法对内存段下F2断点 3,由于PAGE_GUARD的特殊性,无法完美处理od用PAGE_GUARD下断点的BUG,建议尽量不要对内存段下F2断点 4,加强进程保护功能,防止ring3下复制句柄打开od进程 5,修复驱动多处小bug 6,更新版本号 [2008.11.06 v0.20] 1,超长异常处理链导致OD打开太慢的BUG [2008.11.03 v0.19] 1,增加一个快捷键,cpudump 窗口 alt+左键双击 2,修复隐藏OD窗口后输入法有可能无法使用的BUG 3,修复了一个潜在的蓝屏BUG [2008.09.15 v0.18] 1,修复了Ctrl+G计算rva,offset时的一个小BUG 2,当程序不是运行的状态时,Detach前会先运行程序 3,修复原版OD的数据区复制BUG 4,修复od运行后CPU占用率很高的BUG 5,可以设置是否跳过一些异常处理 [2008.09.02 v0.17] 1,跳过不是OD设的Int 3中断,跳过STATUS_GUARD_PAGE,STATUS_INVALID_LOCK_SEQUENCE异常 2,正确处理int 2d指令 [2008.08.31 v0.16] 1,加入驱动,保护进程,隐藏窗口,过绝大部分反调试 2,驱动支持自定义设备名(ollydbg.ini中的DeviceName,设备名不超过8个字符) ollydbg.ini中的[StrongOD]中,可以自己设定 HideWindow=1 隐藏窗口 HideProcess=1 隐藏进程 ProtectProcess=1 保护进程 DriverKey=-82693034 和驱动通信的key DriverName=fengyue0 驱动设备名(不超过8个字符) 3,将OD创建进程的父进程改成explorer.exe (抄自shoooo的代码) [2008.08.10 v0.15] 1,增强查找模块功能(能正确查找处理过peb的模块,比如ring3的隐藏模块) 2,增强OD对文件Pe头的分析(如Upack壳等) 3,anti anti attach (一种极端的attach方式) 4,脱离目标程序不再调试(DebugActiveProcessStop)功能,xp系统以上 5,注入dll到被调试的进程 a) Remote Thread(使用CreateRemoteThread注入) b) Current Thread(shellcode,不增加线程方式注入,当前线程必须暂停) [2008.07.04 v0.14] 1,过VMP 1.64邪恶anti 下载地址:http://www.unpack.cn/viewthread.php?tid=26870 [2008.01.20 v0.13] 1,Advanced Ctrl + G 功能可以输入API名(已经和OD自带的功能一摸一样了) 2,修复了当没有断点的时候会有删除所有断点的选项的BUG 3,修复了删除所有断点,有可能删不完的BUG 4,当线程小于或等于1的时候,不会有Resume all thread 和 Suspend all thread选项 5,并不兼容看雪9.21版本(因为这个版本修改了ACPUASM等类名,如果自己修改的版本请不要修改ACPU这样的类名) 6,和加壳版的OD有一定的兼容性(载入时将导入表写回PE头和相应的位置,但还是不支持TheODBG) [2008.01.15 v0.12] 1,增加了Advanced Ctrl + G 功能 2,将浮点bug作为选项(patch代码的,需要重启才能保存选项) 3,将原本patch的代码都取消,全部改成hook形式,增加兼容性(后续的功能将都用patch的形式做) [2007.11.15 v0.11] 去除了2个BUG: 1,启动程序时,如果目录有空格会有个出错信息 2,CPU DUMP 窗口,如果选中一个内存块的第一个字节,Infoline会显示异常 增加: 如果断点窗口没有任何断点,则不显示菜单 [2007.11.14 v0.10] 增加创建进程模式 本插件提供了3种方式来启动进程: 1,Normal 和原来的启动方式相同,清掉了STARTINFO里面不干净的数据 2,CreateAsUser 用一个User权限的用户来启动进程,使进程运行在User权限下,无法对Admin建立的进程进行操作 运行这个需要在本地安全策略-用户权利指派里面将你的用户加入2个权限: 1,替换进程级记号(SeAssignPrimaryTokenPrivilege) 2,以操作系统方式操作(SeTcbPrivilege) 如果是home版的windows,无法设置,那么可以试试使用SuperMode,重启OD来提升权限,强烈不建议使用这个选项 3,CreateAsRestrict 第二个选项用User权限的用户来启动进程限制的地方比较多,所以,增加第三个功能,以一个限制级的Admin用户来启动程序 启动的程序是以Admin的用户,不过权限只剩下默认User用户有的权限,一些危险权限全部删除(包括SeDebugPrivilege,SeLoadDriverPrivilege等),这样运行的程序不会对OD造成很大的伤害。建议用这个方式启动程序。 注意: 1,新增加的这2个启动方式,不一定能运行所有的程序(比如OllyDbg)!不过在调试木马的时候会有不错的效果。 2,和 Olly Advanced 插件冲突,加载了Olly Advanced 插件,此功能失效! 隐藏调试器功能 HidePEB,去掉PEB中的调试标记,并且从根本上解决了HeapMagic的问题(参考的Phant0m.dll) 此功能的选项选不选都自动隐藏 快捷键功能 1. 增加CPU ASM,CPU DUMP,CPU STACK窗口中增加Enter相关的一系列快捷键 CPU ASM窗口中 例如 1000481A |. A3 F48E0010 mov dword ptr ds:[10008EF4], eax 选中这行时,按Enter, 表示在 CPU DUMP窗口显示10008EF4位置 按Shift+Enter, 表示在 CPU ASM 窗口显示10008EF4位置 按Ctrl+Enter, 表示在CPU DUMP窗口显示这行的地址1000481A位置 如果有2个立即数,比如 1000481A mov dword ptr ds:[10001000],40304C 这样的语句,如果要切换另一个立即数,就加上Alt,进行切换 选中这行时,按Enter, 表示在 CPU DUMP窗口显示40304C位置 按Shift+Enter, 表示在 CPU ASM 窗口显示40304C位置 按Ctrl+Enter, 表示在 CPU DUMP窗口显示这行的地址1000481A位置 按Alt+Enter, 表示在 CPU DUMP窗口显示10001000位置 按Alt+Shift+Enter, 表示在 CPU ASM 窗口显示10001000位置 CPU DUMP窗口中 按Enter,表示在CPU ASM窗口显示选中的第一个字节开始的数据内容 按Shift+Enter,表示在CPU DUMP窗口显示选中的第一个字节开始的数据内容 按Ctrl+Enter,表示在CPU ASM窗口显示选中的第一个字节的地址 CPU STACK窗口中 按Enter,表示在CPU ASM窗口显示选中行的数据 按Shift+Enter,表示在CPU DUMP窗口显示选中行的数据 按Ctrl+Enter,表示在CPU ASM窗口显示选中行的地址 按Alt+Enter,表示在CPU DUMP窗口显示选中行的地址 2. 增加CPU ASM , CPU DUMP , CPU STACK窗口快捷键ESC和`(注:ESC下面的),此按键功能同在CPU窗口按-(减号)+(加号)功能.(方便笔记本,因为笔记本没有小键盘) 3. 增加CPU REG窗口快捷键ESC和`(注:ESC下面的)实现View FPU,View MMX,View 3D Now!,View Debug的快速翻页. 4. 增加CPU STACK窗口快捷键ESC和`(注:ESC下面的),ESC表示在CPU STACK窗口显示ESP值,`表示显示EBP的值 5. 增加CPU REG窗口快捷键CTRL+数字键1至8(分别对应EAX,ECX,EDX,EBX,ESP,EBP,ESI,EDI)将其内容显示在CPUASM窗口中 增加CPU REG窗口快捷键SHIFT+数字键1至8(分别对应EAX,ECX,EDX,EBX,ESP,EBP,ESI,EDI)将其内容显示在CPUDUMP窗口中 6. 增加CPU ASM,CPU DUMP窗口快捷键Shift+C,Shift+V,Shift+X,Ctrl+X.分别对应二进制复制,二进制粘贴,无空格二进制复制(方便写OD脚本的兄弟),复制选中的第一个字节的地址 注:Shift+V 只需要选中起始地址即可. Shift+C与Shift+X的区别如下: 55 8B EC 8B 45 0C 48 74 42 48 74 37 83 E8 0D 74 558BEC8B450C48744248743783E80D74 Ctrl+X功能是复制选中的第一个字节的地址,如选中的第一行是 1000481A mov dword ptr ds:[10001000],40304C 按Ctrl+X,则地址01000481A 复制到剪贴板 7. 增加在CPU ASM 和CPU DUMP窗口增加快捷键Insert ,Delete Insert 将选中的区域以0x90填充 Delete 将选中的区域以0x00填充 先选中一块区域,然后按键,填充完后可以用OD的恢复功能恢复(Alt + Backspace) 8. 增加状态栏显示CPU DUMP窗口中选中区域的起始地址,结束地址,选中区域大小,及当前值. 注:如CPU DUMP窗口数据为00401000 00 10 40 00 69 6E 67 20 鼠标选中地址00401000后面的00时,状态栏窗口显示Value为401000,按Ctrl+双击鼠标左键复制Value到剪切板. 9. 增加断点窗口(ALT+B呼出)Delete All BreakPoints功能.实现删除全部断点. 10. 增加线程窗口Suspend All Threads,Resume All Threads功能.实现挂起和恢复全部线程. 特别感谢:fly,sucsor,lifeengines,shoooo,foxabu,hellsp@wn,okdodo,kanxue,a__p,微笑一刀,goldsun
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值