using std::vector;
/
/
获取进程
ID
DWORD GetProcessPid(CString csProcessName)
{
PROCESSENTRY32 pStc;
pStc.dwSize
=
sizeof(pStc);
HANDLE nSnapShot
=
CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,
0
);
BOOL
bRet
=
Process32First(nSnapShot, &pStc);
while
(bRet)
{
if
(csProcessName
=
=
CString(pStc.szExeFile))
{
return
pStc.th32ProcessID;
}
bRet
=
Process32Next(nSnapShot, &pStc);
}
return
0
;
}
/
/
获取驱动器
vector<CStringA> GetDriverList()
{
vector<CStringA>nDiverList;
TCHAR nDrive[MAX_PATH];
GetLogicalDriveStrings(
100
, (LPWSTR)nDrive);
TCHAR
*
pName
=
nDrive;
/
/
指针指向的地方不为零(表示有盘符)
while
(
*
pName !
=
0
) {
/
/
添加到vector中
nDiverList.push_back(pName);
/
/
printf(
"%S\n"
, pName);
/
/
指向下一个盘符
pName
+
=
_tcslen(pName)
+
1
;
}
return
nDiverList;
/
/
返回vector
}
/
/
恢复文件
void RecoveryFile(CStringA csFilePath, CStringA csFileName)
{
int
nFileType
=
0
;
CStringA csFileType;
csFileType
=
PathFindExtensionA(csFileName);
csFileType.MakeUpper();
/
/
通过分析得知exe,scr,pif,com,htm,html,asp,php,jsp,aspx文件属于被感染类型
if
(csFileType
=
=
".EXE"
|| csFileType
=
=
".SCR"
|| csFileType
=
=
".PIF"
|| csFileType
=
=
".COM"
)
nFileType
=
1
;
else
if
(csFileType
=
=
".HTML"
|| csFileType
=
=
".HTM"
|| csFileType
=
=
".ASP"
|| csFileType
=
=
".ASPX"
|| csFileType
=
=
".JSP"
|| csFileType
=
=
".PHP"
)
nFileType
=
2
;
/
/
网络文件
else
return
;
/
/
不属于这些文件类型就没必要接下去的判断了
/
/
打开文件
FILE
*
pFile
=
nullptr;
char
*
cBuff
=
nullptr;
int
nFileSize
=
0
;
fopen_s(&pFile, csFilePath,
"rb"
);
/
/
读文件
fseek(pFile,
0
, SEEK_END);
/
/
将文件指针指向结尾
nFileSize
=
ftell(pFile);
/
/
返回文件的偏移量(文件大小)
rewind(pFile);
/
/
重新指向文件的开头
/
/
读出来
cBuff
=
new char[nFileSize] {};
fread(cBuff, nFileSize,
1
, pFile);
fclose(pFile);
if
(nFileType
=
=
1
)
{
int
i
=
0
;
/
/
感染特征,在文件的最后加上 .文件名.文件类型.文件类型.原文件大小.
/
/
文件类型.原文件大小.一边情况下不会超过
12
个字节
for
(; i <
13
; i
+
+
)
{
/
/
感染特征倒数第二个.的十六进制是
0x02
if
(
*
(cBuff
+
nFileSize
-
13
+
i)
=
=
(char)
0x02
)
break
;
}
/
/
特征的最后一个点的
16
进制是
0x01
if
(i
=
=
13
|| (
*
(cBuff
+
nFileSize
-
1
) !
=
(char)
0x01
))
{
delete[]cBuff;
return
;
}
char cTemp[
13
]{};
int
nExeSize
=
0
;
memcpy_s(cTemp,
13
, cBuff
+
nFileSize
-
13
+
i
+
1
,
13
-
i
-
2
);
/
/
得到源文件大小
sscanf_s(cTemp,
"%d"
, &nExeSize);
/
/
判断源文件大小
if
(nExeSize <
=
0
)
{
delete[]cBuff;
return
;
}
printf(
"被感染文件类型:%s\t被感染文件大小:%d \n"
, csFileType, nExeSize);
/
/
申请新的文件地址用于存放正确文件的缓冲区
char
*
pcNewFile
=
new char[nExeSize] {};
memcpy_s(pcNewFile, nExeSize, cBuff
+
0x1F000
, nExeSize);
/
/
删除被感染的文件
if
(!DeleteFileA(csFilePath))
{
printf(
"%s\t修复%s失败!\n"
, csFileType, csFilePath);
delete[]pcNewFile;
delete[]cBuff;
return
;
}
/
/
把正确的文件写入源地址
fopen_s(&pFile, csFilePath,
"wb"
);
fwrite(pcNewFile, nExeSize,
1
, pFile);
fclose(pFile);
delete[]pcNewFile;
printf(
"%s\t修复%s成功!\n"
, csFileType, csFilePath);
}
else
if
(nFileType
=
=
2
)
{
/
/
删除网络文件中加入的链接
CStringA csFileCode(cBuff);
if
(csFileCode.Find(
"www.ac86.cn/66/index.htm"
) !
=
-
1
)
{
int
nHtmlSize
=
nFileSize
-
76
;
char
*
NewFile
=
new char[nHtmlSize] {};
memcpy_s(NewFile, nHtmlSize, cBuff, nHtmlSize);
fopen_s(&pFile, csFilePath,
"wb"
);
fwrite(NewFile, nHtmlSize,
1
, pFile);
fclose(pFile);
delete[]NewFile;
printf(
"%s\t修复%s成功!\n"
, csFileType, csFilePath);
}
}
delete[]cBuff;
cBuff
=
nullptr;
}
/
/
遍历文件
void FindFile(CStringA csDir)
{
WIN32_FIND_DATAA stcFileData
=
{
0
};
HANDLE hFind
=
INVALID_HANDLE_VALUE;
hFind
=
FindFirstFileA(csDir
+
L
"\\*"
, &stcFileData);
if
(hFind
=
=
INVALID_HANDLE_VALUE)
return
;
do {
/
/
排除两个隐藏路径(当前目录,上级目录)
if
(CStringA(stcFileData.cFileName)
=
=
"."
|| CStringA(stcFileData.cFileName)
=
=
".."
)
{
continue
;
}
/
/
删除Desktop_.ini文件
if
(SetFileAttributesA(csDir
+
"\\Desktop_.ini"
, FILE_ATTRIBUTE_NORMAL))
{
DeleteFileA(csDir
+
"\\Desktop_.ini"
);
printf(
"%s\\Desktop_.ini\t删除成功\n"
, csDir );
}
if
(stcFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
FindFile(csDir
+
"\\"
+
stcFileData.cFileName);
/
/
目录拼接,递归查找
else
{
/
/
恢复文件
RecoveryFile(csDir
+
"\\"
+
stcFileData.cFileName, stcFileData.cFileName);
}
/
/
查找下一个文件
}
while
(FindNextFileA(hFind, &stcFileData));
}
/
/
结束进程(熊猫烧香)
void EndProcess()
{
DWORD
ID
=
GetProcessPid(
"spo0lsv.exe"
);
if
(
ID
!
=
0
)
{
DWORD Flag
=
TerminateProcess(OpenProcess(PROCESS_ALL_ACCESS, FALSE,
ID
),
0
);
if
(Flag
=
=
0
)
{
printf(
"熊猫烧香\t进程结束失败\n"
);
}
}
else
{
printf(
"熊猫烧香\t进程未找到\n"
);
}
}
/
/
删除熊猫烧香文件
void DeletePandaFile()
{
SetFileAttributesA(
"C:\\Windows\\System32\\drivers\\spo0lsv.exe"
, FILE_ATTRIBUTE_NORMAL);
/
/
去除属性
DWORD Flag
=
DeleteFileA(
"C:\\Windows\\System32\\drivers\\spo0lsv.exe"
);
if
(Flag
=
=
0
)
{
printf(
"C:\\Windows\\System32\\drivers\\spo0lsv.exe\t不存在\n"
);
}
}
/
/
修改注册表
void ChangeReg()
{
printf(
"注册表"
);
/
/
删除启动项svcshare
HKEY hKey
=
NULL;
int
nError
=
RegOpenKeyA(HKEY_CURRENT_USER,
"Software\\Microsoft\\Windows\\CurrentVersion\\Run\\"
, &hKey);
if
(nError !
=
ERROR_SUCCESS)printf(
"\t打开失败(启动项)\n"
);
RegDeleteValueA(hKey,
"svcshare"
);
RegCloseKey(hKey);
/
/
修改注册表 隐藏
nError
=
RegOpenKeyA(HKEY_LOCAL_MACHINE,
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced\\Folder\\Hidden\\SHOWALL\\"
, &hKey);
if
(nError !
=
ERROR_SUCCESS)printf(
"\t打开失败(隐藏)\n"
);
DWORD nVal
=
1
;
RegSetValueExA(hKey,
"CheckedValue"
,
0
, REG_DWORD, (CONST BYTE
*
)&nVal, sizeof(DWORD));
/
/
0
改为
1
,取消隐藏
RegCloseKey(hKey);
printf(
"\t清理成功\n"
);
}
/
/
查杀
void FindKill()
{
vector<CStringA>vecDiverList;
vecDiverList
=
GetDriverList();
/
/
返回驱动器列表(以盘符组成的数组)
for
(auto& vecDriverItem : vecDiverList)
{
SetFileAttributesA(vecDriverItem
+
"\\autorun.inf"
, FILE_ATTRIBUTE_NORMAL);
DeleteFileA(vecDriverItem
+
"\\autorun.inf"
);
printf(
"%s\\autorun.inf..已删除\n"
, vecDriverItem);
SetFileAttributesA(vecDriverItem
+
"\\setup.exe"
, FILE_ATTRIBUTE_NORMAL);
DeleteFileA(vecDriverItem
+
"\\setup.exe"
);
printf(
"%s\\setup.exe..已删除\n"
, vecDriverItem);
/
/
传入盘符遍历文件
FindFile(vecDriverItem);
};
}
/
/
主逻辑
int
main()
{
/
/
结束进程(熊猫烧香)
EndProcess();
/
/
删除熊猫烧香文件
DeletePandaFile();
/
/
修改注册表
ChangeReg();
/
/
查杀(删除熊猫产生的文件,修改被更改的文件)
FindKill();
system(
"pause"
);
return
0
;
}