Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.135.246.193] |
|
Сообщ.
#1
,
|
|
|
Получение нулевого уровня привилегий Я не буду объяснять, что такое нулевой уровень привилегий (нулевое кольцо, ring 0), т.к. если Вы этого не знаете, значит Вам там (в ring 0) делать нечего. Но если Вам всё же интересно, почитайте про защищённый режим . Самый простой, на мой взгляд, способ попасть в ring 0 под Windows 9X - это перехватить обработку прерывания и вызвать это прерывание. Т.к. все прерывания выполняются в ring 0, то и наш обработчик будет выполняться в нём же. Реализовать это очень просто: достаточно подправить таблицу дескрипторов прерываний IDT. Однако проделать такое можно только под Windows 9X, т.к. Windows NT не разрешит нам редактировать IDT, но это совсем не означает, что под Windows NT попасть в ring 0 невозможно (только описывать эту процедуру я даже не буду пытаться, и не просите!). Но есть ещё один вопрос: какое прерывание выбрать? Я предлагаю int 3. Кстати говоря, в примере Как написать резидентную программу (под Windows)? обработчик прерывания работает как раз в ring 0. Итак, вот простой пример программы попадания в ring 0: ; ml /c /coff /Ic:\masm32\include ring0.asm ; link /subsystem:console /libpath:c:\masm32\lib ring0.obj .586P .MODEL Flat,StdCall OPTION CASEMAP:NONE INCLUDE WINDOWS.INC INCLUDE KERNEL32.INC INCLUDE USER32.INC INCLUDELIB KERNEL32.LIB INCLUDELIB USER32.LIB ; Номер перехватываемого прерывания Intr = 3 .DATA Text db 'Эта прога не пашет в Windows NT/2K/XP :(',0 Caption db 'Облом, да?',0 .CODE ; Вызов процедуры, которая должная выполниться в Ring 0 ; В качестве параметра передаётся адрес процедуры CallInRing0 proc R0Proc: DWORD pushf ; Сохраняем флаги cli ; Запрещаем аппаратные прерывания ; Получаем адрес IDT push eax ; Сохраняем в стеке что-нибудь (*) sidt [esp-2] ; Записываем в стек предел и адрес (на место (*)) IDT pop eax ; Записываем в EAX адрес IDT из (*) ; Сохраняем адрес старого обработчика и устанавливаем новый add eax,Intr*8 ; EAX = адрес дескриптора нужного прерывания mov ebx,R0Proc ; EBX = адрес нашей процедуры xchg [eax+0],bx ; Читаем и записываем младшее слово адреса обработчика ror ebx,16 xchg [eax+6],bx ; Читаем и записываем старшее слово адреса обработчика int Intr ; Вызываем нашу процедуру popf ; Восстанавливаем флаги ret ; Выходим из процедуры CallInRing0 endp ; Процедура восстановления прерывания (см. ниже) RestInt proc mov [eax+6],bx ; Восстанавливаем старшее слово адреса обработчика ror ebx,16 mov [eax+0],bx ; Восстанавливаем младшее слово адреса обработчика sti ; Разрешаем аппаратные прерывания ret ; Выходим из процедуры RestInt endp ;----------------------------------------------------------------------------; ; Процедура, выполняемая в Ring 0 Ring0Proc proc ; Восстанавливаем дескриптор прерывания (эту процедуру необходимо вызывать ; всегда в самом начале процедуры, которая вызывается в нулевом кольце!!!) call RestInt ;----------------------------------------; ; ВСЁ, МЫ В НУЛЕВОМ КОЛЬЦЕ, УРА!!! ; ; ЗДЕСЬ МОЖНО ДЕЛАТЬ ВСЁ, ЧТО УГОДНО! ;) ; ;----------------------------------------; ; Выходим из процедуры (а также из обработчика прерывания и из Ring 0) ; Выходить из такой процедуры нужно через iretd, (никаких ret и retf!) iretd Ring0Proc endp ;----------------------------------------------------------------------------; ; Начало основной программы ; ;----------------------------------------------------------------------------; Start: ; Проверяем платформу (Windows 9X или NT) invoke GetVersion ; Узнаем номер версии or eax,eax ; Старший бит установлен? js @@Continue ; Да, это Windows 9X, ура! :) invoke MessageBox, NULL, offset Text, offset Caption, MB_OK+MB_ICONERROR jmp @@Exit ; Выходим @@Continue: ; Запускаем процедуру в Ring 0 invoke CallInRing0, offset Ring0Proc @@Exit: ; Выходим из программы invoke ExitProcess, NULL ; Goodbye! END Start |
Сообщ.
#2
,
|
|
|
Продолжив тему получения R-0 привилегий, рассмотрим пример для win2000/xp/2003.
(Во всех примерах компилятор fasm 1.62) Самый простой способ это, естественно написание кода в драйвере: format PE native 4.0 include "%fasminc%/win32a.inc" proc main,object,regpath ;здесь мог бы быть ваш код mov eax,STATUS_DEVICE_CONFIGURATION_ERROR ret mov eax,main section '.reloc' data fixups readable discardable но, такой способ требует хорошего знания архитектуры Windows, т.к. использование "обычных"(ring-3) api функций из ring-0 проблематично. По этому удобней использовать драйвера, "пробивающие бреж" в ring-0 для обычных приложений ring-3. Например: format PE native 4.0 include "%fasminc%/win32a.inc" ;***************main********************** proc main,pDriverObject,pDriverPath pushfd ; сохраняем флаги pushad ; сохраняем регистры mov eax,[pDriverObject] ; получаем указатель на DriverObject add eax,34h ;смещение на адрес для функции выгрузки драйвера mov dword[eax],UnloadDriver ; записываем адрес выгрузки mov eax,[INTnum] ; номер прерывания stdcall SetInt,INT_Service,eax,ioldhandler,11101110b ; установим обработчик прерываний для R-3, сохранив старый в ioldhandler ; INT_Service - новый обработчик прерывания popad popfd mov eax,0 ret endp ;***************unload********************** proc UnloadDriver,pDriverObject pushad mov eax,[INTnum] ; номер прерывания stdcall RestoreInt,eax,ioldhandler ; восстановим обработчик прерываний popad mov eax,0 ret endp ;*******************proc***************** include 'setints.inc' ;******************service*************** INT_Service: cli ; сбросим флаг прерываний call eax ; перейдём на код, который должен выполнится в R-0 sti ; восстановим флаг прерываний iret ; выйдем из обработчика прерываний ;********************************************* ;******************data*********************** PADR dd 0h INTnum dd 20h ioldhandler dd 0 ;********************************************* ;********************************************* mov eax,main ;********************************************* section '.reloc' data fixups readable discardable Файл setints.inc: proc SetInt,INT_ADR,IntNum,Int_alt,option pushad ;********************************************* ;*********** установка обработчика прерывания* ;********************************************* cli mov eax,cr0 push eax and eax,0xFFFEFFFF ; clear WP mov cr0,eax mov al,byte[option] mov byte[.opt+1],al ; вычисление адреса mov eax,[INT_ADR] mov [.IAdressAll],eax mov ax,word[.IAdressAll] mov [.ladr],ax mov ax,word[.IAdressAll+2] mov [.hadr],ax mov [.seg],cs push ebx ; получить адрес IDT sidt [esp-2] pop ebx xor eax,eax mov al,byte[IntNum] ; номер прерывания mov ah,8h mul ah add ebx,eax ;8*ints ; адрес int xx ;сохраним старый адрес Exception mov edi, [Int_alt] mov esi, ebx movsd movsd ;установим новый адрес Exception mov edi, ebx mov esi, .Int_new movsd movsd sti pop eax mov cr0,eax ; restore WP popad ret ;********************************************* ;********************************************* ;********************************************* .IAdressAll dd 0 .Int_new: .ladr dw 0 .seg dw 0 ; p AC Type .opt db 00000000b,11101110b; 1|11|0|1110| ;Type GrapG16 -0111; GrapG32 -1111; IntG32 -1110; CallG32 - 1100; .hadr dw 0 endp proc RestoreInt,IntNum,Int_alt pushad ;********************************************************** ;*****************восстановим обработчик прерывания********* ;********************************************************** cli mov eax,cr0 push eax and eax,0xFFFEFFFF ; clear WP mov cr0,eax mov [.seg],cs push ebx ; получить адрес IDT sidt [esp-2] pop ebx xor eax,eax mov al,byte[IntNum] ; номер прерывания mov ah,8h mul ah add ebx,eax ;8*ints ; адрес int xx ;восстановим старый адрес Exception mov edi, ebx mov esi, [Int_alt] movsd movsd sti pop eax mov cr0,eax ; restore WP popad ret ;********************************************************** ;********************************************************** ;********************************************************** .IAdressAll dd 0 .Int_new: .ladr dw 0 .seg dw 0 ; p AC Type .opt db 00000000b,11101110b; 1|11|0|1110| ;Type GrapG16 -0111; GrapG32 -1111; IntG32 -1110; CallG32 - 1100; .hadr dw 0 endp Загруженный драйвер использовать так: include '%fasminc%/win32ax.inc' .data StrMsgBoxText DB 'CR0=%08XH',0DH,0AH DB 'CR2=%08XH',0DH,0AH DB 'CR3=%08XH',0DH,0AH,0 StrTemp RB 128 .code proc ExceptCallBack invoke MessageBox,0,"Not Ring-0!","Test Ring-0 Programm",0 invoke ExitProcess, -1 ret endp start: invoke SetUnhandledExceptionFilter,ExceptCallBack ; установим обработчик ошибок mov eax,tests ; адрес функции для R-0 int 20h ; вызов драйвера invoke wsprintf,StrTemp,StrMsgBoxText,eax,ebx,edx ; конвертируем значения invoke MessageBox,HWND_DESKTOP,StrTemp,"Ring-0!",MB_OK invoke ExitProcess,0 proc tests ; считываем регистры, доступные только в R-0 mov eax,cr0 mov ebx,cr2 mov edx,cr3 ret endp .end start |
Сообщ.
#3
,
|
|
|
Загрузить драйвер можно например так:
; example of simplified Win32 programming using complex macro features include '%fasminc%/win32ax.inc' ; Server Constant SC_MANAGER_CONNECT = 01h SC_MANAGER_CREATE_SERVICE = 02h SC_MANAGER_ENUMERATE_SERVICE = 04h SC_MANAGER_LOCK = 08h SC_MANAGER_QUERY_LOCK_STATUS = 10h SC_MANAGER_MODIFY_BOOT_CONFIG = 20h SERVICE_DEMAND_START = 03h SERVICE_KERNEL_DRIVER = 01h DELETE = 10000h SERVICE_QUERY_CONFIG equ 0001h SERVICE_CHANGE_CONFIG equ 0002h SERVICE_QUERY_STATUS equ 0004h SERVICE_ENUMERATE_DEPENDENTS equ 0008h SERVICE_START equ 0010h SERVICE_STOP equ 0020h SERVICE_PAUSE_CONTINUE equ 0040h SERVICE_INTERROGATE equ 0080h SERVICE_USER_DEFINED_CONTROL equ 0100h SERVICE_ERROR_IGNORE equ 00000000 SERVICE_ERROR_NORMAL equ 00000001 SERVICE_ERROR_SEVERE equ 00000002 SERVICE_ERROR_CRITICAL equ 00000003 SERVICE_CONTROL_STOP equ 00000001h SERVICE_CONTROL_PAUSE equ 00000002h SERVICE_CONTROL_CONTINUE equ 00000003h SERVICE_CONTROL_INTERROGATE equ 00000004h SERVICE_CONTROL_SHUTDOWN equ 00000005h SERVICE_CONTROL_PARAMCHANGE equ 00000006h SERVICE_CONTROL_NETBINDADD equ 00000007h SERVICE_CONTROL_NETBINDREMOVE equ 00000008h SERVICE_CONTROL_NETBINDENABLE equ 00000009h SERVICE_CONTROL_NETBINDDISABLE equ 0000000Ah .data szFileNamerb200h FileNamedb 'DriverNT.sys',0 ServiceNamedb '!Driver',0 DisplayNamedb 'Äðàéâ',0 shndd 0 chndd 0 Errrb 6 ;*********************************** ; SERVICE_STATUS _ss: .dwServiceType dw ? .dwCurrentState dw ? .dwControlsAccepted dw ? .dwWin32ExitCode dw ? .dwServiceSpecificExitCode dw ? .dwCheckPoint dw ? .dwWaitHint dw ? db 0 ;*********************************** .code start: mov Dword[Err],'ER-1' invoke OpenSCManager,0,0,SC_MANAGER_CREATE_SERVICE mov [chn],eax test eax,eax je ERR invoke GetFullPathName,FileName ,200h,szFileName,esp ;xor eax,eax ;and [esp],eax mov Dword[Err],'ER-2' invoke CreateService,[chn],ServiceName ,DisplayName , \ SERVICE_START + SERVICE_STOP + DELETE,\ SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, \ SERVICE_ERROR_IGNORE,szFileName, NULL, NULL, NULL, NULL,NULL test eax,eax je ERR mov [shn],eax mov Dword[Err],'ER-3' invokeStartService,[shn],0,0 test eax,eax je ERR invokeMessageBox,HWND_DESKTOP,"Выгрузить драйвер?","DRIVER",MB_OK mov Dword[Err],'ER-4' invoke ControlService,[shn], SERVICE_CONTROL_STOP,_ss test eax,eax je ERR mov Dword[Err],'ER-5' invokeDeleteService,[shn] test eax,eax je ERR invokeCloseServiceHandle,[shn] invokeExitProcess,0 ERR: invokeMessageBox,HWND_DESKTOP,Err,"DRIVER",MB_OK invokeDeleteService,[shn] invokeCloseServiceHandle,[shn] invokeExitProcess,0 .end start |