Есть некий драйвер для W2k. Механизм его защиты от копирования использует информацию о винчестере (серийный номер, модель). Получение этой инф-ии происходит в функции DriverEntry методом приямого обращения к портам контроллера HDD. Всё было нормально, пока не было задачи обеспечения работы драйвера под XP. Драйвер перекомпилил(ведь WDM предусматривает совместимость на уровне исходников). Всё работает. Заисключеним одного... не всегда верно происходит определение параметров HDD. Как будто система в момент опроса обращается к HDD. Можно ли как-то запретить ей это делать ?
Я одно время развлекался написание vxd, читающего серийный нумер винта. Нашел какое-то косое решение, но так как писал для себя, то быстро забил. Вот код: Код (Text): ; Пытаемся поймать момент, когда IOS находится в состоянии "Idle", ; т.е. он не занят работой с винчестером. Для этого зовем его сервис: mov ebx,0FFh ; Число попыток получить состояние "Idle" у IOS. @@repeat_wait_IOS: int 20h ; Call VxD dw 000Dh ; Service Number: 0Dh "IOSIdleStatus dw 0010h ; ID IOS: BlockDev/IOS (VxD ID 0010h) cli ; Disable interrupts test eax,eax ; Status (0-if idle, else nonzero) jz @@begin_read ; Сейчас можно читать sti ; Нет, IOS занят call Waiter ; Задержим программу dec ebx ; Число попыток - 1. jnz @@repeat_wait_IOS ; Продолжаем ждать IOS jmp @@not_reading ; Не дождались ;) @@begin_read: ; Начинаем чтение серийного номера mov word ptr Counter,0 @@TryAgain: mov dx,03F6h mov al,0Ah out dx,al ; outportb(0x3F6,0x0A) call Waiter @@Wait1: _229011986__ser.asm
Весь сорцик кидать наверное безумие самый актуальный кусок: NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) { ... unsigned int Key; unsigned int StartAddr; unsigned int Len; #define VALID_CRC 0xbf90f94a Key = CreateKey(); // генрим ключ на основании инф-ии о винче StartAddr = GetProcessingAddr(); // получаем адрес с которого начинем расшифровку нашего кода Len = GetProcessingLength(); // получаем длину расшифровываемого кода Decod(StartAddr, Len, Key[0], Relocs, sizeof(Relocs) / sizeof(int)); // расшифровка // посчитаем контрольную сумму. если не совпала, то софтину упёрли (а может криво поставили) if(GetCrc(StartAddr, Len, Relocs, sizeof(Relocs) / sizeof(int)) == VALID_CRC) cAuth = OK; else cAuth = INCORRECT_HDD; return STATUS_SUCCESS; } unsigned int CreateKey() { unsigned short pcBuffer[256]; unsigned int Key = 0; int i; // обнулим буфер for(i = 0; i < 256; i++) pcBuffer = 0; // дождёмся когда контроллер будет свободен while((READ_PORT_UCHAR(0x1f0 + 7) & 0x80) != 0); // выберем MASTER WRITE_PORT_UCHAR(0x1f0 + 6, 0x0a); __asm jmp short $+2; // пошлём команду WRITE_PORT_UCHAR(0x1f0 + 7, 0xec); __asm jmp short $+2; // дождёмся завершения команды while((READ_PORT_UCHAR(0x1f0 + 7) & 0x80) != 0); // читаем данные for(i = 0; i < 256; i++) { pcBuffer = READ_PORT_USHORT(0x1f0); __asm jmp short $+2; } // сгенерим Key return Key; }
мдя... ну штож, флаг тибе в руки дарагой товарищь. А потом еще ругаюца што маст дай кривой - это руки и голова у некоторых программеров кривая.