U盘病毒及其相关资源的分析(patch shell32.dll)

Kevins的天空 http://rootsec.cn

Security is life

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;
    //以下省略
}

你可能感兴趣的:(资源,病毒,void,休闲,天空)