Блин-комом номер шесть. Драйвер написан по мотивам UserPort.sys 1.1 by Tomas Franzon. Как завещал великий Dale Roberts корректируем указатель на карту ввода/вывода, который по умолчанию указывал за границу TSS, и устанавливаем начало IOPM на TSS+0x88. В отличии от UserPort.sys 1.0 драйвер поддерживает Hyper-Threading Technology ("UserPort 1.0 did not run stable on Hyperthreading machined (rebooted without bluescreen).") В аттаче драйвер, user-mode приложение, которое его запускает и исходники to be continued...
Блин-комом номер семь. Вариация драйвера scp2, но получает адрес user-mode процедуры не через WriteFile "\\.\driver", а через DeviceIoControl. В аттаче драйвер, user-mode приложение, которое его запускает и исходники to be continued...
2All Можно ли в user-mode приложениях использовать IN, OUT если драйвером установить флажки IOPL равными 3? Ведь в "Instruction Set Reference" псевдокод команды IN, выглядит так: IF ((PE = 1) and ((CPL > IOPL) or (VM = 1))) THEN (* Protected mode with CPL > IOPL or virtual-8086 mode *) IF (Any I/O Permission Bit for I/O port being accessed = 1) THEN (* I/O operation is not allowed *) #GP(0); ELSE ( * I/O operation is allowed *) DEST ← SRC; (* Read from selected I/O port *) Если у кого-то есть удачный опыт поделитесь исходником...
Mikl___ Можно, это кстати шедулер поддерживает и инфокласс есть - ProcessUserModeIOPL для NtSetInformationProcess. Кстати при этом cli и sti инструкции робят.
Clerk Если можно ссылочку на код... А разве CLI и STI в user-mode нельзя через pushf /and dword ptr [esp],0FFFFFDFFh/popf ?
для работы с портами ввода/вывода обходимся без драйвера. В аттаче исходник и user-mode приложение...
Улучшаем DirectIO. В аттаче подправленный ехе и исходный текст... может быть есть еще какие-нибудь идеи о "ring0 access from ring3"?
Два варианта доступа к In/Out через установку IOPL=3. Драйвер scp09 при открытии через CreateFile("\\.\scp09") получает адрес процесса из IoGetCurrentProcess. Драйвер scp10 идентификатор процесса ProcessId получает через DeviceIoControl или из реестра или через WriteFile("\\.\scp10"). В функцию PsLookupProcessByProcessId передаем ProcessId и получаем указатель на KPROCESS. Устанавливаем поле KPROCESS.Iopl равным TRUE, в user-mode приложении создаем и запускаем поток, содержащий команды In/Out. Огромное спасибо TSS за подсказку. В аттаче драйвера, user-mode приложения и исходники. to be continued...
Mikl___ Зачем, если есть текущий, трап-фрейм которого сформирован и его не нужно ждать ? Кстате при свопинге поле IOPL не используется, эти флаги загружаются при инициализации обьекта.
Пока делаю обзор написанного.... Доступ к командам In/Out через kernel-mode драйвера 1) scp00 просто переделанный beeper. Содержит внутри outbs, синхронизация через KeStallExecutionProcessor. Вызывается из scp00-00. Неполнофункциональный драйвер 2) scp01 передает управление на фрагмент кода из scp01-00 в котором содержится outsb, синхронизация через предварительный подсчет тиков. Адрес процедуры передается через DeviceIoControl. Полнофункциональный драйвер. 3) scp02 написано на основе r0pc.sys by @L.chemist (Andrey A. Meshkov). передает управление на фрагмент кода из scp02-00 в котором содержится outsb, синхронизация через предварительный подсчет тиков. Адрес процедуры передается через WriteFile("\\.\scp02"). Полнофункциональный драйвер. 4) scp03 передает управление на фрагмент кода из scp03-00 в котором содержится outsb, синхронизация через предварительный подсчет тиков. Адрес процедуры передается через реестр. Недописан... 5) scp?? передает управление на фрагмент кода из scp??-00 в котором содержится outsb, синхронизация через предварительный подсчет тиков. Адрес процедуры подсчитан заранее и передан при создании sys. Недописан... Доступ к командам In/Out через изменение карты IOPM 6) scp04 написано на основе giveio by Four-F открывает порты IOPM и использует Ke386SetIoAccessMap, Ke386QueryIoAccessMap, Ke386IoSetAccessProcess. ProcessId получает через реестр. Сочетание команд outsb и WinAPI функции Sleep. Неполнофункциональный драйвер. 7) scp05 написано на основе драйвера режима ядра PortTalk 2.0 by Craig Peacock. Открывает порты IOPM и использует Ke386SetIoAccessMap, Ke386QueryIoAccessMap, Ke386IoSetAccessProcess. ProcessId получает через DeviceIoControl. Сочетание команд outsb и WinAPI функции Sleep. Полнофункциональный драйвер. 8) scp06 написано на основе драйвера режима ядра UserPort 2.0 by Tomas Franzon changed to PsSetCreateProcessNotifyRoutin method. адресный диаппазон расширен до 0x7A80 для всех процессов и до 0xFFFF для \\.\scp06 процессов. Выполнение Ke386IoSetAccessProcess, сопровождается вызовом функции ZwYieldExecution, которая форсирует процесс переключения. Сочетание команд outsb и WinAPI функции Sleep. Полнофункциональный драйвер. 9) scp07 написано на основе драйвера режима ядра UserPort 1.0 by Tomas Franzon изменение адреса начала IOPM в TSS расширяет размер TSS до 0x2135. адресный диаппазон расширен до 0x7A80 для всех процессов и до 0xFFFF для \\.\scp07 процессов. Сочетание команд outsb и WinAPI функции Sleep. Для многопроцессорной или гипертрейдинговой машины может вызвать перезагрузку без BSOD. Полнофункциональный драйвер. 10) scp08 написано на основе драйвера режима ядра UserPort 1.1 by Tomas Franzon изменение адреса начала IOPM в TSS расширяет размер TSS до 0x2FFF работает с гипертрейдинговыми и многопроцессорными системами. Полнофункциональный драйвер. Доступ к командам In/Out через установку user-mode приложению IOPL=3 11) my_directio делает CPL = IOPL из user-mode. Повышаем привелегию SeTcbPrivilege через функцию ZwSetInformationProcess(GetCurrentProcess(), ProcessUserModeIOPL, 0, 0) устанавливает IOPL=3. User-mode приложение, драйвер не нужен. 12) my_directio1 усовершенствованный my_directio. Упростил заполнение структуры TOKEN_PRIVILEGES, избавился от функций GetCurrentProcess и ExitProcess, вызываю функции NtOpenProcessToken, NtAdjustPrivilegesToken, NtSetInformationProcess через int 2Eh. User-mode приложение, драйвер не нужен. 13) scp09 при открытии драйвера через CreateFile("\\.\scp09") получаем адрес процесса через IoGetCurrentProcess. Устанавливаем поле KPROCESS.Iopl равным TRUE, в user-mode приложении создаем и запускаем поток, содержащий команды In/Out, для этого нового потока IOPL обновится, следом, после переключения задач, обновится EFLAGS. Полнофункциональный драйвер. 14) scp10 ProcessId получает через DeviceIoControl, реестр или через WriteFile("\\.\scp10"). Передадим в функцию PsLookupProcessByProcessId полученный идентификатор процесса ProcessId, получаем указатель на KPROCESS. Устанавливаем поле KPROCESS.Iopl равным TRUE, в user-mode приложении создаем и запускаем поток, содержащий команды In/Out. Полнофункциональный драйвер. 15) scp11 в драйвере получаем текущий поток и процесс, функция PsGetContextThread извлекает из стека ядра KTRAP_FRAME и преобразует его в структуру CONTEXT. В поле CONTEXT.RegEFlags устанавливаем флаги IOPL=3 и функция PsSetContextThread копирует переданный CONTEXT в KTRAP_FRAME. В user-mode приложении создаем и запускаем поток, содержащий команды In/Out. Полнофункциональный драйвер. Дай мне боже силы собраться и дописать статью!
Mikl___ Базовые способы анализа кода: o Парсинг фиксапов. Например имеется ссылка на переменную, для этой ссылки определён фиксап, в ядре секция релоков выгружена. o Дизассемблирование. Для этого необходим дизасм длин(ldasm). Инструкции последовательно разбираются, например: Код (Text): ; o KeEnterKernelDebugger ; o KdInitSystem ; o KiHardwareTrigger ; o KeBugCheckCount ; o KiDebugRoutine ; o KdpStub KDEBUG_ENVIRONMENT struct pKeEnterKernelDebugger PVOID ? pKdInitSystem PVOID ? pKiHardwareTrigger PVOID ? pKeBugCheckCount PVOID ? pKiDebugRoutine PVOID ? pKdpStub PVOID ? KDEBUG_ENVIRONMENT ends PKDEBUG_ENVIRONMENT typedef ptr KDEBUG_ENVIRONMENT xQueryDebugEnvironment proc uses ebx esi edi NtImageBase:PVOID, DbgEnv:PKDEBUG_ENVIRONMENT Local ImageHeader:PIMAGE_NT_HEADERS, ImageLimit:PVOID Local Fn:KDEBUG_ENVIRONMENT Call SEH_Epilog_Reference Call SEH_Prolog mov edi,NtImageBase invoke LdrImageNtHeader, Edi, addr ImageHeader test eax,eax mov Fn.pKeEnterKernelDebugger,6DED839AH ; HASH("KeEnterKernelDebugger") mov Fn.pKeEnterKernelDebugger[4],eax jnz Exit invoke LdrEncodeEntriesList, Edi, 0, addr Fn.pKeEnterKernelDebugger test eax,eax mov esi,Fn.pKeEnterKernelDebugger jnz Exit mov edi,8 ; IP's xor ebx,ebx KiHardwareTrigger@Step: movzx eax,word ptr [esi] cmp al,33H ; 33 /r (xor r32,r/m32) jne KiHardwareTrigger@IsImm comment ' 33F6 xor esi,esi 46 inc esi 8935 XXXXXXXX mov dword ptr ds:[_KiHardwareTrigger],esi ' mov cl,ah ; ModR/M mov al,ah and cl,MODRM_MOD_MASK and al,MODRM_REG_MASK cmp cl,MODRM_MOD_MASK jne KiHardwareTrigger@Next shr al,3 ; Reg and ah,MODRM_RM_MASK cmp al,ah movzx ebx,al jne KiHardwareTrigger@Next add al,40H ; 40 + rd (inc r32) cmp byte ptr [esi + 2],al jne KiHardwareTrigger@Next cmp byte ptr [esi + 3],89H ; 89 /r (mov r/m32,r32) mov al,byte ptr [esi + 4] ; ModR/M jne KiHardwareTrigger@Next ror al,3 mov ah,al ; (011B:EBX, 110B:ESI, 111B:EDI) and al,(MODRM_REG_MASK shr 3) and ah,NOT(MODRM_REG_MASK shr 3) cmp ah,10100000B movzx eax,al jne KiHardwareTrigger@Next cmp eax,ebx jne KiHardwareTrigger@Next mov eax,dword ptr [esi + 5] ; _KiHardwareTrigger add esi,9 jmp KeBugCheckCount@Scan KiHardwareTrigger@Next: Call VirXasm32 add esi,eax dec edi jnz KiHardwareTrigger@Step jmp Error KiHardwareTrigger@IsImm: cmp ax,05C7H ; mov dword ptr ds:[_KiHardwareTrigger],1 jne KiHardwareTrigger@Next cmp dword ptr [esi + 6],1 jne KiHardwareTrigger@Next mov eax,dword ptr [esi + 2] ; _KiHardwareTrigger ; _KeBugCheckCount add esi,10 KeBugCheckCount@Scan: mov Fn.pKiHardwareTrigger,eax lea edi,[esi + 60H] KeBugCheckCount@Step: mov ax,word ptr [esi] cmp al,0C3H ; ret je Error cmp al,0CCH ; int 3 je Error sub al,0B8H ; B8 + rb (mov r32,imm32) jb KeBugCheckCount@Next cmp al,7 ; Reg ja KeBugCheckCount@Next mov ecx,dword ptr [esi + 1] ; _KeBugCheckCount movzx eax,al add esi,5 test ebx,ebx mov Fn.pKdInitSystem,eax ; /Reg mov Fn.pKeBugCheckCount,ecx jz KeBugCheckCount@Xadd KeBugCheckCount@Xchg: ; xchg mov eax,dword ptr [esi] .if al == 0F0H ; Pfx lock shr eax,8 .endif cmp al,087H ; 87 /r (xchg r/m32,r32) jne Error mov al,ah test ah,MODRM_MOD_MASK jnz Error and eax,(MODRM_RM_MASK or (MODRM_REG_MASK shl 8)) cmp byte ptr [Fn.pKdInitSystem],al jne Error shr ah,3 cmp ah,bl jne Error jmp KdInitSystem@Scan KeBugCheckCount@Xadd: Call VirXasm32 add esi,eax ; xadd mov eax,dword ptr [esi] .if al == 0F0H ; Pfx lock shr eax,8 .endif cmp ax,0C10FH ; 0FC1 /r (xadd r/m32,r32) jne Error shr eax,16 movzx eax,al test al,MODRM_MOD_MASK jnz Error and eax,MODRM_RM_MASK cmp Fn.pKdInitSystem,eax ; /Reg jne Error jmp KdInitSystem@Scan KeBugCheckCount@Next: Call VirXasm32 add esi,eax cmp esi,edi jb KeBugCheckCount@Step jmp Error KdInitSystem@Scan: ; _KdInitSystem lea ebx,[esi + 50H] mov edi,NtImageBase KdInitSystem@Step: Call VirXasm32 add esi,eax cmp byte ptr [esi],OPCODE_CALL ; call _KdInitSystem jne KdInitSystem@Next cmp word ptr [esi + 5],056AH ; push DBG_STATUS_FATAL(5) jne KdInitSystem@Next cmp byte ptr [esi + 7],OPCODE_CALL ; call _KiBugCheckDebugBreak jne KdInitSystem@Next mov eax,ImageHeader add esi,dword ptr [esi + 1] mov eax,IMAGE_NT_HEADERS.OptionalHeader.SizeOfImage[eax] add esi,5 ; _KdInitSystem add eax,edi mov Fn.pKdInitSystem,esi lea ebx,[esi + 80H] mov ImageLimit,eax cmp esi,edi jna Error cmp esi,eax jae Error KiDebugRoutine@Step: Call VirXasm32 add esi,eax cmp word ptr [esi],05C7H ; mov dword ptr ds:[_KiDebugRoutine],@KdpStub jne KiDebugRoutine@Next mov ecx,dword ptr [esi + 2] ; @KiDebugRoutine mov edx,dword ptr [esi + 6] ; @KdpStub cmp ecx,edi jna Error cmp edx,edi jna Error cmp ImageLimit,ecx jbe Error cmp ImageLimit,edx jbe Error cld mov Fn.pKiDebugRoutine,ecx lea esi,Fn mov edi,DbgEnv mov ecx,sizeof(KDEBUG_ENVIRONMENT)/4 mov Fn.pKdpStub,edx xor eax,eax rep movsd jmp Exit KiDebugRoutine@Next: cmp byte ptr [esi],OPCODE_CALL je Error cmp esi,ebx jc KiDebugRoutine@Step jmp Error KdInitSystem@Next: cmp byte ptr [esi],0C3H ; ret je Error cmp esi,ebx jc KdInitSystem@Step Error: mov eax,STATUS_NOT_FOUND jmp Exit SEH_Epilog_Reference: %GET_CURRENT_GRAPH_ENTRY Exit: Call SEH_Epilog ret xQueryDebugEnvironment endp o Использование масок. На код налаживается маска, где смещения обнулены и выполняется сравнение с этой маской, например: Код (Text): ; o WRMSR ; o KiLoadFastSyscallMachineSpecificRegisters ; o KiFastCallEntry ; o KPRCB.DpcStack comment ' _KiLoadFastSyscallMachineSpecificRegisters: $ 6A 00 push 0 $+2 6A 08 push 8 ; KGDT_R0_CODE $+4 68 74010000 push 174 ; IA32_SYSENTER_CS $+9 E8 XXXXXXXX call _WRMSR $+E 6A 00 push 0 $+10 68 XXXXXXXX push offset KiFastCallEntry ; Fixup.. $+15 68 76010000 push 176 $+1A E8 XXXXXXXX call _WRMSR $+1F 6A 00 push 0 $+21 FFB6 XXXXXXXX push dword ptr ds:[esi + DIS] ; KPRCB.DpcStack $+27 68 75010000 push 175 ; IA32_SYSENTER_ESP $+2C E8 XXXXXXXX call _WRMSR _WRMSR: $ 8B4C24 04 mov ecx,dword ptr ss:[esp + 4] $+4 8B4424 08 mov eax,dword ptr ss:[esp + 8] $+8 8B5424 0C mov edx,dword ptr ss:[esp + C] $+C 0F30 wrmsr $+E C2 0C00 ret 0C' SIGN_LENGTH equ 30H ; Align! FIX_WRMSR_1 equ 09H FIX_WRMSR_2 equ 1AH FIX_WRMSR_3 equ 2CH FIX_EIP equ 10H FIX_ESP equ 22H MSR_ENVIRONMENT struct pWRMSR PVOID ? pKiLoadFastSyscallX PVOID ? pKiFastCallEntry PVOID ? PrcbDpcStack ULONG ? ; Смещение в KPRCB. MSR_ENVIRONMENT ends PMSR_ENVIRONMENT typedef ptr MSR_ENVIRONMENT xQueryMsrEnvironment proc uses ebx esi edi NtImageBase:PVOID, MsrEnv:PMSR_ENVIRONMENT Local ImageHeader:PIMAGE_NT_HEADERS Local SectionHeader:PIMAGE_SECTION_HEADER Local Environment:MSR_ENVIRONMENT Local Buffer[SIGN_LENGTH]:BYTE Call SEH_Epilog_Reference Call SEH_Prolog ; Mask. push 000000000H push 0E8000001H push 075680000H push 00000B6FFH push 0006A0000H push 00000E800H push 000017668H push 000000000H push 068006A00H push 0000000E8H push 000000174H push 068086A00H mov ebx,esp invoke LdrImageNtHeader, NtImageBase, addr ImageHeader test eax,eax mov edx,ImageHeader jnz Exit mov edi,IMAGE_SECTION_HEADER.VirtualAddress[edx + sizeof(IMAGE_NT_HEADERS)] ; .text mov ecx,IMAGE_SECTION_HEADER.VirtualSize[edx + sizeof(IMAGE_NT_HEADERS)] add edi,NtImageBase sub ecx,SIGN_LENGTH cld @@: mov eax,6AH ;push # repne scasb mov esi,edi jne Error push ecx push esi mov ecx,(SIGN_LENGTH/4) lea edi,Buffer xor eax,eax rep movsd mov ecx,(SIGN_LENGTH/4) lea edi,Buffer mov esi,ebx mov dword ptr [Buffer + FIX_WRMSR_1],eax mov dword ptr [Buffer + FIX_WRMSR_2],eax mov dword ptr [Buffer + FIX_WRMSR_3],eax mov dword ptr [Buffer + FIX_EIP],eax mov dword ptr [Buffer + FIX_ESP],eax repe cmpsd pop edi pop ecx jne @b mov eax,dword ptr [edi + FIX_WRMSR_1] lea ecx,[eax + edi + FIX_WRMSR_1 + 5 - 1] ; _WRMSR sub eax,11H mov Environment.pWRMSR,ecx cmp dword ptr [edi + FIX_WRMSR_2],eax jne @b sub eax,12H mov edx,dword ptr [edi + FIX_ESP] cmp dword ptr [edi + FIX_WRMSR_3],eax jne @b mov Environment.PrcbDpcStack,edx cmp word ptr [ecx + 0CH],300FH ; wrmsr mov eax,dword ptr [edi + FIX_EIP] ; _KiFastCallEntry jne Error sub edi,5 mov ecx,40H @@: cmp dword ptr [edi],0FF8B9090H ; nop/nop/mov edi,edi je @f Step: dec edi loop @b Error: mov eax,STATUS_NOT_FOUND jmp Exit @@: cmp dword ptr [edi - 3],90909090H jne Step add edi,2 ; _KiLoadFastSyscallMachineSpecificRegisters lea esi,Environment mov Environment.pKiLoadFastSyscallX,edi mov Environment.pKiFastCallEntry,eax mov edi,MsrEnv xor eax,eax movsd movsd movsd movsd jmp Exit SEH_Epilog_Reference: %GET_CURRENT_GRAPH_ENTRY Exit: add esp,SIGN_LENGTH Call SEH_Epilog ret xQueryMsrEnvironment endp ; Ref. KiIpiGenericCall(): ; _KiAdjustInterruptTime@8 ; _KeSetIntervalProfile@8 ; _KiRestoreFastSyscallReturnState@0 ; xQueryMsrEnvironmentEx proc uses ebx esi edi NtImageBase:PVOID, pKiIpiGenericCall:PVOID, MsrEnv:PMSR_ENVIRONMENT Local ImageHeader:PIMAGE_NT_HEADERS Local SectionHeader:PIMAGE_SECTION_HEADER Local Environment:MSR_ENVIRONMENT Call SEH_Epilog_Reference Call SEH_Prolog invoke LdrImageNtHeader, NtImageBase, addr ImageHeader test eax,eax jnz Exit invoke xQueryMsrEnvironment, NtImageBase, addr Environment test eax,eax mov edx,ImageHeader jnz Exit mov edi,IMAGE_SECTION_HEADER.VirtualAddress[edx + sizeof(IMAGE_NT_HEADERS)] ; .text mov ecx,IMAGE_SECTION_HEADER.VirtualSize[edx + sizeof(IMAGE_NT_HEADERS)] add edi,NtImageBase cld mov ebx,ecx mov esi,edi mov edx,Environment.pKiLoadFastSyscallX add ebx,edi Scan: mov eax,68H ; push offset _KiFastCallEntry @@: repne scasb jne Error cmp dword ptr [edi],edx jne @b cmp byte ptr [edi + 4],OPCODE_CALL jne @b cmp word ptr [edi - 3],006AH ; push 0 jne @b mov eax,dword ptr [edi + 5] lea eax,[eax + edi + 4 + 5] ; _KiIpiGenericCall cmp esi,eax jae Scan cmp ebx,eax jna Scan cmp dword ptr [eax],8B55FF8BH ; mov edi,edi/push ebp.. jne Scan mov ecx,pKiIpiGenericCall mov dword ptr [ecx],eax mov edi,MsrEnv lea esi,Environment movsd movsd movsd movsd xor eax,eax jmp Exit SEH_Epilog_Reference: %GET_CURRENT_GRAPH_ENTRY Exit: Call SEH_Epilog ret Error: mov eax,STATUS_NOT_FOUND jmp Exit xQueryMsrEnvironmentEx endp o Сигнатурный поиск. Ищется последовательность байт в пределах секций модуля. o Парсинг сервисов. Для некоторых сервисов разность их ID является константой. o Использование графа. Это весьма сложные способы, но эффективные. Для большинства не доступны. Строится граф, затем выполняется его анализ. o Динамические способы крайне не желательны. Это трассировка.
> Использование графа. Это весьма сложные способы, но эффективные. Для большинства не доступны. Строится граф, затем выполняется его анализ. дык всё просто вроде, избежать зацикливания и всё.
n0name Ну тут не могут тупо память просканить, а вы про графы. Мб несколько человек это смогут сделать.)
Блин-комом номер десять. В драйвере scp12 получаем текущий поток и процесс, устанавливаем Process->Iopl = TRUE, функция PsGetContextThread извлекает из стека ядра KTRAP_FRAME и преобразует его в структуру CONTEXT. Так как Process->Iopl = TRUE, функция PsSetContextThread устанавливает в поле CONTEXT.RegEFlags значение IOPL равным 3. Далее функция PsSetContextThread копирует переданный CONTEXT в KTRAP_FRAME. В user-mode приложении scp12-00 создаем и запускаем поток, содержащий команды In/Out. Полнофункциональный драйвер. В аттаче драйвер, user-mode приложение и исходники. Огромное спасибо Clerk за идею, терпение и помощь!
Блин-комом номер одиннадцать и двенадцать. Доступ к портам ввода-вывода из юзермодного приложения без драйвера. scp13-00 устанавливает IOPL=3 через SetInformationProcess еще одним способом. Проверено под WinXP SP3. Идея взята здесь. scp14-00 для доступа к портам создает CallGate. К сожалению, не на всех машинах с WinXP SP3 \Device\PhysicalMemory можно открыть с атрибутом SECTION_MAP_WRITE даже с правами Администратора (версия 5.1 сборка 2600.xpsp_sp3_qfe.080423-1303 service pack 3 позволяет, а версия 5.1 сборка 2600.xpsp.080413-2111 service pack 3 -- нет), но там, гда открывается -- код работает. Идея калгейта взята у Ms-Rem из Перехват API функций в Windows NT (часть 3). Нулевое кольцо.. В аттаче исходники и ехе. to be continued...
Mikl___ На счёт калгейтов. В NT их использовать нельзя, так как регистр флагов не изменяется. Тоесть не маскируются прерывания и не сбрасывается TF. Изза IF если произойдёт переключение задач, это может привести к опасным последствиям, так как контекст задачи не полностью инициализирован(переключен на ядерный). Изза TF возникнет не обработанное исключение(это при трассировке вызова шлюза) и будет сгенерирован багчек. Вдобавок следует использовать следующее: o Устанавливать калгейт на всех GDT, либо устанавливать необходимый аффинитет потоку. Иначе после переключений потока на другой процессор возникнет #GP при вызове шлюза. o Передавать управление на инструкцию вызывающую шлюз посредством сервиса NtContinue, заранее замаскировав TF в контексте. o Снизите вероятность свапконтекста можно повысив приоритет и/или обождав начало нового кванта: Код (Text): YIELD_NPX macro fnop @@: smsw eax ; 16i bt ax,1 ; Cr0.MP jnc @b endm http://files.virustech.org/indy/Teory/SwapContext/vt_smsw_npx.pdf Кстате такого типа бэкдоры нельзя в малваре юзать. Наиболее простой способ это использовать SST(запись ссылки в ETHREAD с последующим вызовом).
Для загрузки драйверов можно использовать три способа: 1) использовать API Service Control Manager'a. Для загрузки драйвера scpXX.sys здесь используется приложение scpXX-00.exe 2) прописывать драйвер в реестре вручную и загружать его с помощью функции ZwLoadDriver. Вы создаете в реестре минимум необходимых записей, запускаете драйвер и удаляете его раздел из реестра. Для загрузки драйвера scpXX.sys здесь используется приложение scpXX-01.exe 3) загрузить драйвер при помощи ZwSetSystemInformation. Для загрузки драйвера scp00.sys здесь используется приложение scp00-02.exe В аттаче сорцы приложений (от scp00-01 до scp12-01) и scp00-02 и сами ехе