Из SMM режима в Windows XP загружается драйвер, при попытке перехватить IRP_MJ_CLOSE или IRP_MJ_WRITE из Ntfs.sys компьютер перезагружается, на экране пусто, из-за нестандартной загрузки драйвера, не знаю, как подцепить к нему отладчик. В коде жирным отмечены инструкции вызывающие сбой в работе. Код (Text): INT InstallFilter (VOID) { NTSTATUS status = STATUS_SUCCESS; UNICODE_STRING devName; INT err = 0; ULONG cr0Val = 0; ULONG pImageSize = 0; DWORD pNtfsSys = 0; if ( g_filterEnabled ) { IFDEBUG(WriteLogMessage( "Filter already installed\r\n" )); return -1; } pNtfsSys = FindImageBaseAddress("ntfs.sys", NULL); if (pNtfsSys == 0) { IFDEBUG(WriteLogMessage( "Can`t get ntfs.sys image base address\r\n" )); return -2; } IFDEBUG(WriteLogMessage( "Ntfs.sys image base address finded\r\n" )); g_filesCopyCountInQueue = 0; RtlInitUnicodeString(&devName, L"\\FileSystem\\Ntfs"); status = ObReferenceObjectByName( &devName, OBJ_CASE_INSENSITIVE, NULL, 0, (POBJECT_TYPE)IoDriverObjectType, KernelMode, NULL, (PVOID*)&g_TargetDrvObj ); if (!NT_SUCCESS(status)) { IFDEBUG( WriteLogMessage ("Cannot get DriverObject of NTFS\r\n")); return -1; } /* if ( *NtBuildNumber == WINXP ) { g_freeMem = (ULONG) pNtfsSys + RVA_FREEDATA_XP; } else if ( *NtBuildNumber == WINVISTA ) { g_freeMem = (ULONG) pNtfsSys + RVA_FREEDATA_VISTA; } else if ( *NtBuildNumber >= WINVISTASP1 && *NtBuildNumber <= WINVISTASP2 ) { g_freeMem = (ULONG) pNtfsSys + RVA_FREEDATA_VISTA_SP; } else { IFDEBUG( WriteLogMessage ("Unsupported Windows Build in InstallFilter\r\n")); return -1; }*/ //IFDEBUG( WriteLogMessage ("g_freeMem Defined\r\n")); // InitializeListHead( &g_filesCopyQueueList ); KeInitializeSpinLock( &g_filesCopyQueueListLock ); KeInitializeEvent( &g_filesCopyCloseThreadSignalEvent, NotificationEvent, FALSE ); KeInitializeEvent( &g_filesCopyEvent, NotificationEvent, FALSE ); g_filesCopyThread = NULL; err = CrCreateThread( FilterCopyFilesThread, NULL, &g_filesCopyThread); if ( err < THREAD_OK ) { IFDEBUG( WriteLogMessage ( "Can't create files copy thread\r\n")); return -3; } // Сохраняем адрес оригинальной функции g_OldMJClose = g_TargetDrvObj->MajorFunction[IRP_MJ_CLOSE]; g_OldMJWrite = g_TargetDrvObj->MajorFunction[IRP_MJ_WRITE]; // Сохраняем данные из области памяти //RtlCopyMemory ( g_oldData, (PUCHAR) g_freeMem, sizeof(g_oldData) ); // Записываем код перехода на нашу функцию MJClose ((pfar_jmp) g_MyData)->PushOp = 0x68; ((pfar_jmp) g_MyData)->PushArg = NewMJClose; ((pfar_jmp) g_MyData)->RetOp = 0xC3; // Записываем код перехода на нашу функцию MJWrite ((pfar_jmp) (g_MyData + 6))->PushOp = 0x68; ((pfar_jmp) (g_MyData + 6))->PushArg = NewMJWrite; ((pfar_jmp) (g_MyData + 6))->RetOp = 0xC3; // Отключаем защиту записи в память CommonEnableGlobalMemoryWR ( &cr0Val ); // Записываем указатель на наш код в секции data, вместо оригинального IRP_MJ_CLOSE [b] g_TargetDrvObj->MajorFunction[IRP_MJ_CLOSE] = (PDRIVER_DISPATCH) g_MyData;[/b] [b] // Записываем указатель на наш код в секции data, вместо оригинального IRP_MJ_WRITE g_TargetDrvObj->MajorFunction[IRP_MJ_WRITE] = (PDRIVER_DISPATCH) (g_MyData+6);[/b] // Возвращаем обратно защиту памяти от записи CommonDisableGlobalMemoryWR ( cr0Val ); IFDEBUG(DbgPrint( "IRP_MJ_CLOSE Old func 0x%.8x; New func 0x%.8x (free mem)\n", g_OldMJClose, g_freeMem )); IFDEBUG(DbgPrint( "IRP_MJ_WRITE Old func 0x%.8x; New func 0x%.8x (free mem)\n", g_OldMJWrite, g_freeMem + 6 )); // Устанавливаем флаг активности фильтра g_filterEnabled = TRUE; IFDEBUG(WriteLogMessage("FileHooking is Enabled\r\n" )); return 0; } INT UninstallFilter ( VOID ) { ULONG CR0Reg; PLIST_ENTRY pEnt = NULL; PFILTER_FILE_ENTRY fileEnt = NULL; KIRQL oldIrql; if ( !g_filterEnabled ) { IFDEBUG(WriteLogMessage ( "Filter not installed yet\r\n" )); return 0; } // Отключаем защиту записи в память CommonEnableGlobalMemoryWR ( &CR0Reg ); // Удаляем наш код перехода из секции data модуля ntfs.sys, возвращая старые данные // RtlCopyMemory ( (PUCHAR) g_freeMem, g_oldData, sizeof(g_oldData) ); // Возвращаем оригинальный обработчик IRP_MJ_CLOSE g_TargetDrvObj->MajorFunction[IRP_MJ_CLOSE] = g_OldMJClose; // Возвращаем оригинальный обработчик IRP_MJ_WRITE g_TargetDrvObj->MajorFunction[IRP_MJ_WRITE] = g_OldMJWrite; // Возвращаем обратно защиту памяти от записи*/ CommonDisableGlobalMemoryWR ( CR0Reg ); IFDEBUG(WriteLogMessage("IRP_MJ_CLOSE and IRP_MJ_WRITE restored\n")); if(g_filesCopyThread) { CrCloseAndWaitThread(g_filesCopyThread, &g_filesCopyCloseThreadSignalEvent, NULL); g_filesCopyThread = NULL; } /* // Если в очереди на копирование присутствуют файлы, то необходимо очистить очередь if( g_filesCopyCountInQueue ) { KeAcquireSpinLock( &g_filesCopyQueueListLock, &oldIrql ); while ( TRUE ) { if ( IsListEmpty(&g_filesCopyQueueList) || !g_filesCopyCountInQueue ) { KeReleaseSpinLock( &g_filesCopyQueueListLock, oldIrql ); break; } pEnt = g_filesCopyQueueList.Flink; fileEnt = NULL; fileEnt = CONTAINING_RECORD( pEnt, FILTER_FILE_ENTRY, le ); if ( fileEnt ) { RemoveEntryList(&fileEnt->le ); if ( g_filesCopyCountInQueue > 0 ) { g_filesCopyCountInQueue--; } if ( fileEnt->fileName ) { ExFreePoolWithTag( fileEnt->fileName, SNU_ALLOC_TAG); } ExFreePoolWithTag( fileEnt , SNU_ALLOC_TAG); } } KeReleaseSpinLock ( &g_filesCopyQueueListLock, oldIrql ); } */ // Сбрасываем флаг активности фильтра g_filterEnabled = FALSE; IFDEBUG(WriteLogMessage ( "FileHooking is Disabled\r\n" )); return 0; } void CommonEnableGlobalMemoryWR ( unsigned long *cr0Value ) { unsigned long val = 0; IFDEBUG( WriteLogMessage ("CommonEnableGlobalMemoryWR start\r\n")); _asm { cli mov eax,cr0 mov val,eax and eax,0xfffEffff mov cr0,eax } *cr0Value = val; //IFDEBUG( WriteLogMessage ("CommonEnableGlobalMemoryWR stop\r\n")); } void CommonDisableGlobalMemoryWR ( unsigned long cr0Value ) { //IFDEBUG( WriteLogMessage ("CommonDisableGlobalMemoryWR start\r\n")); _asm { mov eax,cr0Value mov cr0,eax sti } IFDEBUG( WriteLogMessage ("CommonDisableGlobalMemoryWR stop\r\n")); } DWORD FindImageBaseAddress( char *szImageName, ULONG *pLength ) { PSYSTEM_MODULE_INFORMATION pItem; PVOID buf = 0; ULONG len; ULONG count; DWORD addr = 0; if( ZwQuerySystemInformation( SystemModuleInformation, buf, 0, &len ) == STATUS_INFO_LENGTH_MISMATCH ) { buf = MmAllocateNonCachedMemory( len ); IFDEBUG( WriteLogMessage ("STATUS_INFO_LENGTH_MISMATCH\r\n")); if( buf ) { if( ZwQuerySystemInformation( SystemModuleInformation, buf, len, NULL ) == STATUS_SUCCESS ) { IFDEBUG( WriteLogMessage ("STATUS_SUCCESS\r\n")); count = *(ULONG*)buf; pItem = (PSYSTEM_MODULE_INFORMATION)((UCHAR*)buf + 4); do { if( _stricmp( pItem->ImageName + pItem->ModuleNameOffset, szImageName ) == 0 ) { addr = (DWORD)(pItem->Base); if( pLength ) *pLength = pItem->Size; IFDEBUG( WriteLogMessage ("Module finded!\r\n")); break; } pItem ++; count --; } while( count > 0 ); } MmFreeNonCachedMemory( buf, len ); } } return addr; }