http://blog.csdn.net/iiprogram/article/details/2205018
U盘病毒让很多人很郁闷,不过说起来也没什么高深的东西
autorun.inf在shell32.dll里面,超级巡警的工具里面的一项强力废除就是patch了shell32.dll,部分代码如下:
void KillSFC()
{
WCHAR shell32file[100]={0};
GetSystemDirectoryW(shell32file,sizeof(shell32file));
lstrcatW(shell32file,L"//shell32.dll");
HMODULE hLib = LoadLibrary("SFC.DLL");
SfcFileException *se = (SfcFileException (__stdcall *))GetProcAddress(hLib,(LPCSTR)5);
se(0,shell32file,-1);
FreeLibrary(hLib);
return;
}
bool MapCacheFileToPatch()
{
CHAR Mapfile[50]={0},anotherfile[50]={0};
HANDLE hfile,hmapfile;
//LARGE_INTEGER filesize;
PVOID Mappingbegin=NULL;
WCHAR* ppt;
GetSystemDirectory(Mapfile,sizeof(Mapfile));
lstrcat(Mapfile,"//dllcache//shell32.dll");
SetFileAttributes(Mapfile,FILE_ATTRIBUTE_NORMAL);
hfile=CreateFile(Mapfile, GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
if (hfile==INVALID_HANDLE_VALUE)
{
ZeroMemory(Mapfile,sizeof(Mapfile));
GetSystemDirectory(Mapfile,sizeof(Mapfile));
lstrcpy(anotherfile,Mapfile);
lstrcat(anotherfile,"//shell32.tmp");
lstrcat(Mapfile,"//shell32.dll");
CopyFile(Mapfile,anotherfile,FALSE);
SetFileAttributes(anotherfile,FILE_ATTRIBUTE_NORMAL);
hfile=CreateFile(anotherfile, GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
if (hfile==INVALID_HANDLE_VALUE)
{
return FALSE;
}
}
//GetFileSizeEx(hfile,&filesize);
hmapfile=CreateFileMapping(hfile,0,PAGE_READWRITE,0,0,0);
if (hmapfile==INVALID_HANDLE_VALUE)
{
CloseHandle(hfile);
return FALSE;
}
Mappingbegin=MapViewOfFile(hmapfile,FILE_MAP_READ|FILE_MAP_WRITE,0,0,0);
if (!Mappingbegin)
{
CloseHandle(hfile);
CloseHandle(hmapfile);
return false;
}
else
{
for (long i=0;i<0x300000;i++)//0x300000可以
{
__try
{
ppt=(WCHAR *)Mappingbegin+i;
if( wcscmp(ppt,L"AutoRun.x86")==0 && wcscmp(ppt+12,L"AutoRun.inf")==0 )//XP/2003
{
//AfxMessageBox("45patch~~~~");
ZeroMemory((PCHAR)ppt,45);
*ppt=(WCHAR)L"NUL";
*(ppt+12)=(WCHAR)L"NUL";
}
else if ( wcscmp(ppt,L"autorun.inf")==0 || wcscmp(ppt,L"AutoRun.inf")==0)//前面XP后面2000
{
//AfxMessageBox("21patch~~~~");
ZeroMemory((PCHAR)ppt,21);
*ppt=(WCHAR)L"NUL";
}
}
__except(EXCEPTION_EXECUTE_HANDLER){}
}
//暴力搜索内存patch %system%/dllcacahe/shell32.dll
UnmapViewOfFile(Mappingbegin);
CloseHandle(hfile);
CloseHandle(hmapfile);
return TRUE;
}
}
void DelShell32()
{
CHAR Oldfile[50]={0},Newfile[50]={0},CopyName[50]={0};
GetSystemDirectory(Oldfile,sizeof(Oldfile));
lstrcpy(Newfile,Oldfile);
lstrcat(Oldfile,"//shell32.dll");
lstrcat(Newfile,"//shell32.bak");
SetFileAttributes(Newfile,FILE_ATTRIBUTE_NORMAL);
MoveFileEx(Oldfile,Newfile,MOVEFILE_REPLACE_EXISTING);//shell32.dll->shell32.bak
MoveFileEx(Newfile,NULL,MOVEFILE_DELAY_UNTIL_REBOOT);//shell32.bak->NULL
GetSystemDirectory(CopyName,sizeof(CopyName));
lstrcat(CopyName,"//dllcache//shell32.dll");
if (MoveFileEx(CopyName,Oldfile,MOVEFILE_REPLACE_EXISTING))
{
//dllcache move to shell32.dll
CopyFile(Oldfile,CopyName,FALSE);//shell32.dll move to dllcache
}
else
{
GetSystemDirectory(CopyName,sizeof(CopyName));
lstrcat(CopyName,"//shell32.tmp");
MoveFileEx(CopyName,Oldfile,MOVEFILE_REPLACE_EXISTING);
}
return;
}
当然,现代病毒还会结合U盘插入,自动感染的方式,基本原理就是当闪存插入时会给每一个窗口发送WM_DEVICECHANGE消息,其中wParam里是Event,包含了当前的事件。我们注册一个窗口类,Wndproc里面检测如下:
void OnDeviceChange(HWND hWnd,WPARAM wParam,LPARAM lParam)
{
PDEV_BROADCAST_HDR lpdb = (PDEV_BROADCAST_HDR)lParam;
switch(wParam)
{
case DBT_DEVICEARRIVAL:
if (lpdb -> dbch_devicetype == DBT_DEVTYP_VOLUME)
{
PDEV_BROADCAST_VOLUME lpdbv = (PDEV_BROADCAST_VOLUME)lpdb;
ULONG unitmask=lpdbv ->dbcv_unitmask;
for (int i = 0; i < 26; ++i)
{
//取得设备的盘号
if (unitmask & 0x1)
{
//这里我们加入你要做的事
//其中i+'A'表示当前的盘符
}
unitmask = unitmask >> 1;
}
}
}
return;
}
MADN中定义的事件如下:
DBT_CONFIGCHANGECANCELED A request to change the current configuration (dock or undock) has been canceled.
DBT_CONFIGCHANGED The current configuration has changed, due to a dock or undock.
DBT_DEVICEARRIVAL A device has been inserted and is now available.
DBT_DEVICEQUERYREMOVE Permission is requested to remove a device. Any application can deny this request and cancel the removal.
DBT_DEVICEQUERYREMOVEFAILED A request to remove a device has been canceled.
DBT_DEVICEREMOVECOMPLETE A device has been removed.
DBT_DEVICEREMOVEPENDING A device is about to be removed. Cannot be denied.
DBT_DEVICETYPESPECIFIC A device-specific event has occurred.
DBT_QUERYCHANGECONFIG Permission is requested to change the current configuration (dock or undock).
从底层的角度,U盘插入,设备总线会收到pnp消息,在其间检测/Driver/USBSTOR驱动对象,过滤即可禁止USB
NTSTATUS
FilterDispatchPnp (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
PDEVICE_EXTENSION deviceExtension;
PIO_STACK_LOCATION irpStack;
NTSTATUS status;
KEVENT event;
PAGED_CODE();
deviceExtension = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
irpStack = IoGetCurrentIrpStackLocation(Irp);
status = IoAcquireRemoveLock (&deviceExtension->RemoveLock, Irp);
if (!NT_SUCCESS (status)) {
Irp->IoStatus.Status = status;
IoCompleteRequest (Irp, IO_NO_INCREMENT);
return status;
}
switch (irpStack->MinorFunction) {
case IRP_MN_QUERY_DEVICE_RELATIONS:
//SET_NEW_PNP_STATE(deviceExtension, RemovePending);
//AttachedDevice (Upper) 81aac0f8 /Driver/USBSTOR
//通过检测Upper Filters来检测是不是Mass Storage,是就STATUS_ACCESS_DENIED
//DbgPrint("Device is %x/t",DeviceObject);
//DbgPrint("Upper Filter is %ws/n",
//DeviceObject->AttachedDevice->DriverObject->DriverName.Buffer);
if (_wcsnicmp(DeviceObject->AttachedDevice->DriverObject->DriverName.Buffer,
L"//Driver//USBSTOR",15)==0)
{
DbgPrint("Cmp Result is %d/n",
_wcsnicmp(DeviceObject->AttachedDevice->DriverObject->DriverName.Buffer,
L"//Driver//USBSTOR",15));
status = STATUS_ACCESS_DENIED;
break;
}
status = STATUS_SUCCESS;
break;
//以下省略
}