
#include "windows.h"
#include "stdio.h"
#include "string.h"
int g_Count_File=0;
void list(char *cPath)
{
WIN32_FIND_DATA wfd;
HANDLE hFind;
char cDir[MAX_PATH];
char cSubDir[MAX_PATH];
::GetCurrentDirectory(sizeof(cDir),cDir);
::SetCurrentDirectory(cPath);
hFind=::FindFirstFile("*.*",&wfd);
if(hFind==INVALID_HANDLE_VALUE)
{
return ;
}
do
{ //判断是否是目录
if(wfd.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)
{
if(wfd.cFileName[0]!='.')
{
//将该目录名与当前路径合并成目录路径
::wsprintf(cSubDir,"%s\\%s",cPath,wfd.cFileName);
printf("%s\\%s\n",cPath,wfd.cFileName);
list(cSubDir);
}
}
else
{
HANDLE hFile=::CreateFile(
wfd.cFileName,
GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if(hFile==INVALID_HANDLE_VALUE)
continue ;
HANDLE hMap=::CreateFileMapping(
hFile,
NULL,
PAGE_READWRITE,
0,
0,
NULL);
void* pAdd=::MapViewOfFile(
hMap,
FILE_MAP_ALL_ACCESS,
0,
0,
0);
if(hMap==0)
continue ;
DWORD *pPe;
PIMAGE_SECTION_HEADER pSec;
WORD nSecNumber=0;
DWORD dNewFileSize=0;
DWORD *pNewFile;
DWORD *pOep;
DWORD flag;
//判断是否文件首字为'MZ'
if(*(WORD*)pAdd==0x5a4d)
{
pPe=(DWORD*)*((DWORD*)((char*)pAdd+0x3c));
pPe=(DWORD*)((DWORD)pAdd+(DWORD)pPe);
//获取文件大小,以免得到一些文件首字为'MZ'但偏移3C处的双字段值超出内存映像文件范围
dNewFileSize=::GetFileSize(hFile,&dNewFileSize);
printf("%s\t%d\n",wfd.cFileName,dNewFileSize);
//判断是否'PE\0\0'
if ((DWORD)pPe<=((DWORD)pAdd+dNewFileSize)&&*pPe==0x004550)
{
nSecNumber=*(WORD*)((char*)pPe+6);
pSec=(PIMAGE_SECTION_HEADER)((char*)pPe+248);
//定位到第一个块表,判断其区名是否为lw0x60若是则被感染
pOep=(DWORD*)((char*)pPe+40);
//判断入口点是否是30C96
if (*pOep==0x30C96)
{
//入口地址30C96对应的文件偏移为2E96
flag=*(DWORD*)((char*)pAdd+0x2E96);
//判断入口点的前四字节是否为74 03 75 01
if (flag==0x01750374)
{
//定位到最后一个区块
for(unsigned int i=1;i<nSecNumber;i++)
{
pSec=(PIMAGE_SECTION_HEADER)((char*)pSec+40);
}
//原文件大小为感染后的文件大小减去病毒体大小后的值
dNewFileSize=dNewFileSize-(pSec->PointerToRawData+pSec->SizeOfRawData);
pNewFile=(DWORD*)(pSec->SizeOfRawData+pSec->PointerToRawData+(char*)pAdd);
char *temp1,*temp2;
temp1=(char*)pAdd;
temp2=(char*)pNewFile;
//将原文件数据依次移到感染后文件的头部,以还原原文件
for (i=0;i<dNewFileSize;i++)
{
*(temp1++)=*(temp2++);
}
::FlushViewOfFile(pAdd,dNewFileSize);
::UnmapViewOfFile(pAdd);
::CloseHandle(hMap);
//修改文件大小
::SetFilePointer(hFile,dNewFileSize,NULL,FILE_BEGIN);
::SetEndOfFile(hFile);
g_Count_File++;
printf("%s\t被清除\n",wfd.cFileName);
}
}
}
}
::UnmapViewOfFile(pAdd);
::CloseHandle(hMap);
::CloseHandle(hFile);
}
}
while(::FindNextFile(hFind,&wfd)!=0);
::SetCurrentDirectory(cDir);
}
void main()
{
char cDrive[4]="D:\\";
char* p=cDrive;
UINT uDriveType;
for(;*p<='Z';(*p)++)
{
uDriveType=::GetDriveType(cDrive);
if(uDriveType==DRIVE_REMOVABLE||uDriveType==DRIVE_FIXED)
{
list(cDrive);
}
}
printf("共%d个文件被感染\n",g_Count_File);
system("pause");
}
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课