Мне надо отключить клавиатуру с помощью Delphi. На каком-то форуме нашел что ее можно отключить так: с помощью
winexec(Pchar('rundll32 keyboard,disable' ) ,sw_Show);
или ассемблерного кода
Asm
in al,21h
or al,00000010b
out 21h,al
End;
В первом случае выдается ошибка:
"Ошибка при загрузке keyboard Не найден указанный модуль."
а во втором:
"Project Project1.exe raised exception class EPrivilege with message 'Privileged instruction'"
Помогите. Может кто знает или занимался этим.
P.S. сразу хочу сказать что я пишу не вирус. И про BlockInput знаю, но он мне не подходит т. к. можно отключить с помощью 3 веселых клавиш.
Уважаемые авторы вопросов! Большая просьба сообщить о результатах решения проблемы на этой странице. Иначе, следящие за обсуждением, возможно имеющие аналогичные проблемы, не получают ясного представления об их решении. А авторы ответов не получают обратной связи. Что можно расценивать, как проявление неуважения к отвечающим от автора вопроса.
31-10-2006 00:27
Специально для тех кто утверждает что Ctrl+Alt+Del могут победить BlockInput. Привожу свой код.
09-07-2006 06:30 | Комментарий к предыдущим ответам
Мне не совсем понятно стремление отключить Ctrl-Alt-Del. Если это делается с целью предотвратить запуск Диспетчера задач и соответственно предотвращения завершения работы программы, то это делается не так (в Windows XP это делается написанием сервиса, а под Windows 98 и, вероятно, Windows ME, это делается через вызов RegisterServiceProcess (только загружать надо динамически в зависимости от версии ОС)).
А от Ctrl-Shift-Esc можно избавиться установкой, скажем WH_CBT и блокировкой создания окна "Диспетчер задач" (только надо посмотреть класс).
А вот мне была раньше интересна блокировка клавиатуры целиком, т.к. никаие ухищрения не помогали против нажатия клавиши Sleep или Power - похоже, они отрабатываются до Windows и ничего не срабатывает. Решение было найдено лишь аппаратное - нажать Fn-F11, это блокирует контроллер клавиатуры на аппаратном уровне и никакие нажатия не отправляются в компьютер (очень удобно для протирания клавиатуры без отключения компьютера)
22-05-2006 13:30 | Комментарий к предыдущим ответам
ну да, забыл написать, что блок на все кроме CAD и CSE
CSE то он как раз ловит :)
мдя... порой у меня возникает подозрение, что PLatform SDK у вас вместо завтрака, обеда, ужина и сказки на ночь
Подозрение правильное, читаю книжки я обычно за едой и на ночь :)
представим ситуацию: две программы на компьютере подменяют GINA.DLL что тогда?
В моём примере этого нет (там кстати баг с удалением записи в реестре: удалять надо не ключ, а значение), но можно при установке своей Gina смотреть есть ли уже такой ключ в реестре, запоминать его и загружать (придётся динамически, а не статически как сейчас) не MSGina, а ту что прописалась в реестре, таким образом будет "очередь" из нескольких Gina. При этом возможны проблемы связанные с порядком удаления этих Gina, но при сабкласинге окон в WinLogon всё ещё хуже, так как правильно разрулить ситуацию, при наличии нескольких желающих словить WM_HOTKEY, невозможно. Если мы будет удалять хуки не в том порядке в котором ставили, то AV-и нам обеспечено, а в Winlogon-е оно приводит к смерти виндов.
Самый правильный и реально (SCADA системы например) используемый способ это написание драйвера (Upper Filter), но к сожалению готовых драйверов с открытым API мне не встречалось.
22-05-2006 07:02 | Комментарий к предыдущим ответам
>>>Ну во первых CAD это не отключает
ну да, забыл написать, что блок на все кроме CAD и CSE
>>>для установки глобального WH_KEYBOARD_LL DLL-ка не требуется
мдя... порой у меня возникает подозрение, что PLatform SDK у вас вместо завтрака, обеда, ужина и сказки на ночь *JOKINGLY*
>>>регистрация своей Gina в реестре рекомендована MS и хорошо описана в MSDN, конечно всё это придумано не для тупого блокирования CAD, но раз такая возможность есть, то почему бы и не воспользоваться
представим ситуацию: две программы на компьютере подменяют GINA.DLL что тогда?
внедрение DLL-ки в Winlogon это уже действительно что-то не очень хорошее.
хотя инжект DLL в winlogon не самое "чистое" решение, но пожалуй самое красивое.
22-05-2006 03:30 | Комментарий к предыдущим ответам
ну вообще, не очень хорошо gina.dll подменять, вам не кажется?
Нет не кажется, регистрация своей Gina в реестре рекомендована MS и хорошо описана в MSDN, конечно всё это придумано не для тупого блокирования CAD, но раз такая возможность есть, то почему бы и не воспользоваться. А вот внедрение DLL-ки в Winlogon это уже действительно что-то не очень хорошее.
вот железно работающий пример отключения клавиатуры
Ну во первых CAD это не отключает, а во вторых для установки глобального WH_KEYBOARD_LL DLL-ка не требуется.
И кстати, WH_KEYBOARD_LL = 13 в Windows.pas не определен...
Это и многое другое определено в Jedi API.
у меня даже есть рабочий код но на си++
Этот http://www.codeproject.com/win32/AntonioWinLock.asp ?
Если он, то я его как то переводил на Delphi, могу выслать.
а я просто сабклассил окно соответствующее
Ну именно так там и делается.
и кстати ctrl-shift-escape забыли, оно тоже так хватается
Угу, но это можно прикрыть через реестр, правда мессага будет выскакивать, что "у вас нет прав".
Вообще самое правильное назначить соответствующие административные политики и тогда сколько хочешь нажимай этот CAD, а всё равно ничего кроме кнопки "Отмена", на появившемся окне не будет.
function MyWlxLoggedOnSAS(pWlxContext:Pointer;dwSasType:DWORD;pReserved:Pointer):Integer; stdcall;
var
Mutex:THandle;
begin
if dwSasType=1 then begin
Mutex:=OpenMutex(MUTEX_ALL_ACCESS,False,MutexName);
if Mutex<>0 then begin
CloseHandle(Mutex);
Result:=2;
Exit;
end;
end;
Result:=WlxLoggedOnSAS(pWlxContext,dwSasType,pReserved);
end;
function UpdateRegistry(Delete:Boolean):HRESULT;
var
Key:HKEY;
DLLName:array[0..MAX_PATH] of Char;
const
KeyName='SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon';
begin
Result:=S_OK;
if Delete then
RegDeleteKey(HKEY_LOCAL_MACHINE,KeyName)
else begin
if (GetModuleFileName(hInstance,DLLName,SizeOf(DLLName))=0)
or(RegOpenKeyEx(HKEY_LOCAL_MACHINE,KeyName,0,KEY_ALL_ACCESS,Key)<>ERROR_SUCCESS)
or(RegSetValueEx(Key,'GinaDLL',0,REG_SZ,@DLLName,lStrLen(DLLName)+1)<>ERROR_SUCCESS) then
Result:=E_UNEXPECTED;
end;
end;
function DllRegisterServer:HRESULT;
begin
Result:=UpdateRegistry(False);
end;
function DllUnregisterServer:HRESULT;
begin
Result:=UpdateRegistry(True);
end;
Её надо скопировать например в System32 и зарегистрировать через "regsvr32 AntiCADGina.dll". Теперь в приложении которое хочет заблокировать CAD достаточно написать "CreateMutex(nil,True,'Global\4F3636FB-3620-478B-B5CE-9F1B158ED6F1');" и CAD работать перестанет (экран правда дёргается), после завершения приложения работа CAD восстановится.
20-05-2006 02:41 | Комментарий к предыдущим ответам
их "привилегированность" заложена на уровне процессора
В регистре EFLAGS есть поле (2 бита) IOPL задающее максимальный уровень привилегий (CPL) на котором можно выполнять ввод/вывод. Вообще почитайте спецификации, на самом деле есть довольно много вещей которыми можно управлять, например тот же RDTSC (тики процессора) можно сделать привилегированной командой.
19-05-2006 15:17 | Комментарий к предыдущим ответам
Нельзя вызывать привилегированные команды на 3-м кольце, а команды in и out - привилегированные
Не совсем так :)
Под 9x они тоже привилегированные, но вызывать всё таки можно, как впрочем и в NT. Результат вызова зависит от нескольких параметров: во первых можно действительно запретить любые попытки вызова этих функций из третьего кольца что и сделано под NT, а можно назначить специальную таблицу с помощью которой доступ к одним портам разрешён, а к другим нет. Второй способ реализован под 9x (там например запрещён доступ к портам IDE-контроллера), а под NT он включается отдельно для каждого процесса, чем и пользуются драйвера типа GiveIO.sys.
19-05-2006 12:10 | Комментарий к предыдущим ответам
'Privileged instruction' и правильно говорит. Нельзя использовать прямое управление контролером клавиатуры под NT даже с правами админа. Вот в режиме ядра - пожалуйста.
Не совсем так. Нельзя вызывать привилегированные команды на 3-м кольце, а команды in и out - привилегированные
А тут собственно нечего рассказывать, я таких драйверов не писал, сталкивался только с готовыми (без исходников). Основные идеи по написанию таких драйверов можно посмотреть у Руссиновича http://www.sysinternals.com/Utilities/Ctrl2Cap.html
Перед тем как оформите его как статью советую проверить весь список, так он фактически неработоспособен под NT (2000, XP).
Конкретно что работает:
WinExec('rundll32 shell32.dll,Control_RunDLL ',1); //Выводит панель управления
WinExec('rundll32 shell32.dll,Control_RunDLL desk.cpl',1); //Открыть свойства экранa
Неудивительно что работает так как используется оболочкой и имеется полное описание в MSDN, причём можно не RunDLL вызывать, а сразу control.exe с параметрами. Так же есть возможность через параметры задавать текущую закладку.
WinExec('rundll32 shell32.dll,OpenAs_RunDLL <FileName>',1); //Выводит окошко «Открыть с помощью...»
Работает и тоже упоминается в MSDN.
WinExec('rundll32 diskcopy,DiskCopyRunDll ',1); //Показать окно «Copy Disk>>
Работает, но по сути своей бесполезно.
ShellAboutA и SHFormatDrive конечно тоже работают, но вызывать их через RunDll глупо, так как это обычные API функции имеющие нормальное описание в справке.
А если автор хочет нормально заблокировать клаву, то ему надо писать драйвер, а если не очень нормально, то использовать BlockInput, а от CAD спасаться или подменой Gina.dll или внедрением DLL-ки и перехвата WM_HOTKEY в winlogon.
'Privileged instruction' и правильно говорит. Нельзя использовать прямое управление контролером клавиатуры под NT даже с правами админа. Вот в режиме ядра - пожалуйста.
У меня работал вот такой код
procedure BlockInput(ABlockInput: boolean); stdcall; external 'USER32.DLL';
// Вызываем функцию из DLL'ки
Пример использования:
procedure TForm1.N1Click(Sender: TObject);
begin
BlockInput(True);
// Вот собственно этим мы и блокируем клаву и мышь
// (для обратного исхода надо вместо True написать False)
end;
Насколько я понимаю, Windows не допускает нарушения своей работоспособности другими программами (по крайней мере, старается не допускать) и перехватывает все опасные действия. Так что, скорее всего, задача не решается, если не найти какую-нибудь дырку в Винде.
Если вы заметили орфографическую ошибку на этой странице, просто выделите ошибку мышью и нажмите Ctrl+Enter. Функция может не работать в некоторых версиях броузеров.