L1F3.RU
   


Главная » Файлы » Статьи » Хакинг и безопасность

Как заблокировать Ctrl-Alt-Del
[ ] 08.05.2009, 19:00



Доброго времени суток. На многих форумах программистов очень часто встречается вопрос «Как заблокировать комбинацию клавиш Ctrl-Alt-Del?». В этой статье я расскажу, как можно реально заблокировать комбинацию клавиш Ctrl-Alt-Del без каких-либо извращений с заменой файлов и прочего. Статья не рассчитана на новичков, читатель этой статьи как минимум должен знать, что такое инжект и запуск удалённых потоков.

  Первое что хотелось бы сказать - это то, что комбинация клавиш Ctrl-Alt-Del предназначена не только для вызова диспетчера задач. В первую очередь она предназначена для вызова окна процесса Winlogon, в котором у нас имеется возможность завершить текущий сеанс, завершить работу компьютера, и, разумеется, вызвать диспетчер задач. Те, кто ставил в WinXP настройки повышенной безопасности, тем знакомо вот это окно.

  Итак, блокировка замена или удаление либо замена его на свой файл самого диспетчера задач Windows (файл taskmgr.exe в системной папке windows) просто делает невозможным его вызов, но по-прежнему (при определённых настройках) комбинация Ctrl-Alt-Del работает и вышеуказанное окно безопасности по-прежнему выводится. А вызвать диспетчер задач можно также через комбинацию клавиш Ctrl-Shift-Esc без вывода этого окна. 

  Сначала подумаем, как можно заблокировать диспетчер задач Windows. Многим сразу придёт в голову идея об удалении или замене файла taskmgr.exe. Во-первых это не так просто так как в Windows XP введена система защиты файлов и при любом изменении её системных файлов она их сразу восстановит. Резервные копии важных файлов находятся в папке system32dllcache. Папка system32 и system32dllcache взаимно связаны и восстанавливаются, друг от друга удаление из system32dllcache влечёт восстановление из system32. Поэтому надо удалять (или заменять) файл taskmgr.exe из обеих папок одновременно. Ладно, мы удалили (или заменили) этот файл, но радость не долгая, выводится сообщение о повреждении системных файлов Windows и просьба вставить диск с дистрибутивом для обновления системы. В принципе и это тоже можно обойти. К чему я веду? К тому, что замена или удаление файлов это не вариант, да и «через жопу» это получается.

  Более внимательные пользователи заметят, что диспетчер задач Windows не запускается два раза, т.е. если он уже запущен, то во второй раз он уже не запустится. И возникает идея о скрытии окна диспетчера, окно скрыто, а он работает и в результате, как ни нажимай Ctrl-Alt-Del или Ctrl-Shift-Esc мы ничего не получим. Следующий код блокирует и разблокирует диспетчер задач Windows.
uses shellapi;

procedure TForm1.Button1Click(Sender: TObject);
var
  TDWH:THandle;
begin
  TDWH:=FindWindow(nil,'Диспетчер задач Windows');
  if TDWH=0 then ShellExecute(0,'open','taskmgr.exe',nil,nil,SW_HIDE)
  else ShowWindow(TDWH,SW_HIDE);
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  TDWH:THandle;
begin
  TDWH:=FindWindow(nil, 'Диспетчер задач Windows');
  ShowWindow(TDWH,SW_SHOWNORMAL);
end;

Всё очень просто. Также вдобавок можно перемещать окно диспетчера далеко за пределы экрана. Итак, задача блокировки диспетчера задач успешно решена. Но наша цель это комбинация клавиш Ctrl-Alt-Del или Ctrl-Shift-Esc. 

  Первая идея, которая возникает, когда надо перехватить комбинации клавиш Ctrl-Alt-Del или Ctrl-Shift-Esc - это воспользоваться стандартным механизмом хуков. Но те, кто уже пытался так сделать, скажут, что через стандартный механизм хуков нельзя перехватить ни одну из важных комбинаций. И возникает такое ощущение, что эти комбинации можно перехватить разве что, написав драйвер-фильтр режима ядра. Но есть другой способ.

  Итак, наша цель - это процесс winlogon.exe, этот процесс управляет входом пользователей в систему и выходом из нее. Процесс winlogon.exe один из основных процессов отвечающих за безопасность системы. Этот процесс нельзя завершить из диспетчера задач, но можно завершить любой другой сторонней программой. Вот только после завершения winlogon.exe сразу буден сгенерирован BSOD. 

  Итак, процесс winlogon.exe очень важен. В нём находится окно с заголовком «SAS window» и классом «SAS Window class» именно этому и только этому окну посылается сообщение WM_HOTKEY, когда были нажаты комбинации Ctrl-Alt-Del или Ctrl-Shift-Esc и ещё несколько важных комбинаций. Найти это окно через функцию FindWindow нельзя, вернее можно, но только будучи в контексте процесса winlogon. Из обычной программы найти это окно нельзя.

  Итак, наша задача подменить оконную функцию окна «SAS window» и отлавливать в нём сообщения WM_HOTKEY, если нажаты эти волшебные комбинации, то просто не вызываем оригинальную оконную функцию. Но чтобы, всё это сделать, нам надо быть в контексте процесса winlogon. Самый простой способ - это внедрить в него нашу DLL. Вот собственно и код этой DLL
library HookDLL;

uses
  Windows,Messages;

var
  OldWndProc: pointer;
  ThreadID:DWORD;

const
  CtrlAltDel_CODE = (VK_DELETE shl 16) or (MOD_CONTROL or MOD_ALT);
  CtrlShiftEsc_CODE = (VK_ESCAPE shl 16) or (MOD_CONTROL or MOD_SHIFT);

function GethWnd: HWND;
begin
  result:= FindWindow('SAS Window class','SAS window');
end;  

function NewWndProc(hWnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
begin
  if msg=WM_HOTKEY then
  begin
  if (lParam=CtrlAltDel_CODE) or (lParam = CtrlShiftEsc_CODE) then
  result:= 0 else
  result:= CallWindowProc(OldWndProc, hWnd, Msg, wParam, lParam);
  end else
  result:= CallWindowProc(OldWndProc, hWnd, Msg, wParam, lParam);
end;

procedure SetWndProc(hWnd: HWND);
begin
  OldWndProc:= pointer(SetWindowLong(hWnd, GWL_WNDPROC, cardinal(@NewWndProc)));
end;

procedure UnSetWndProc(hWnd: HWND);
begin
  SetWindowLong(hWnd, GWL_WNDPROC, cardinal(OldWndProc));
end;

function HookThread(PARAM1:DWORD):DWORD; stdcall;
var
  ThrID:DWORD;
begin
  Result:=0;
  SetWndProc(GethWnd);
  sleep(60*1000);
  UnSetWndProc(GethWnd);
  sleep(10);
  CreateThread(nil,0,GetProcAddress(GetModuleHandle('kernel32'),'FreeLibrary'),pointer(hInstance),0,ThrID);
end;

begin
  CreateThread(nil,0,@HookThread,nil,0,ThreadID);
end.

Код этой DLL блокирует комбинации ровно на минуту, потом DLL выгружается из памяти winlogon. Так же можно изменить функцию NewWndProc так чтобы перенаправить заблокированные комбинации на другие, также можно заблокировать любую комбинацию клавиш которую нельзя перехватить через стандартный механизм хуков. А вот и код, который загрузит нашу DLL в процесс winlogon.
function Start(ProcessID: Cardinal; DllFileName: string): Boolean;
var
  hProcess, hTh: THandle;
  BytesWritten, ThreadID, DllNameLen: Cardinal;
  LoadLibraryProc, MemPtr: Pointer;
  ExitCode: DWord;
begin
  Result := false;

  SetDebugPriv();

  hProcess := OpenProcess(PROCESS_CREATE_THREAD or PROCESS_VM_OPERATION or PROCESS_VM_WRITE,true, ProcessID);
  if hProcess = 0 then exit;

  DllNameLen := Length(DllFileName) + 1;
  MemPtr := VirtualAllocEx(hProcess, nil, DllNameLen, MEM_COMMIT, PAGE_READWRITE);
  if MemPtr nil then
  begin //3
  if WriteProcessMemory(hProcess, MemPtr, PChar(DllFileName), DllNameLen, BytesWritten) then
  begin //2
  LoadLibraryProc := GetProcAddress(GetModuleHandle('kernel32.dll'), 'LoadLibraryA');
  hTh := CreateRemoteThread(hProcess, nil, 0, LoadLibraryProc, MemPtr, 0, ThreadID);
  if hTh 0 then
  begin //1
  if (WaitForSingleObject(hTh, INFINITE) = WAIT_OBJECT_0) and GetExitCodeThread(hTh, ExitCode) then
  Result := ExitCode 0;
  CloseHandle(hTh);
  end; //1
  end; //2
  VirtualFreeEx(hProcess, MemPtr, 0, MEM_RELEASE);
  end; //3
  CloseHandle(hProcess);
end;

Эта процедура принимает ID процесса winlogon и путь к нашей DLL. Разумеется, до этого надо позаботиться о получении привилегии «SeDebugPrivilege» чтобы можно было открыть процесс winlogon c нужным нам доступом. Полный код программы и DLL смотрите в архиве с исходниками в конце статьи.
Итак, блокировка Ctrl-Alt-Del и Ctrl-Shift-Esc реализована. Но некоторым не нравится использование DLL. И как всегда возникает вопрос «А можно ли всё сделать без DLL». Ну, разумеется, можно все это сделать и без DLL, через инжект нашего кода в процесс winlogon. 

  Итак, приступим. Нам надо будет внедрить в процесс winlogon код, который будет находить окно и изменять оконную процедуру целевого окна и код самой оконной процедуры. Разумеется, внедряемый код должен быть базонезависимым, так как мы заранее не знаем, по какому адресу мы его скопируем, и ему нужны адреса используемых им API функций. На Delphi сделать это будет уже проблематично. И поэтому сделаем мы это на ассемблере, так как на нём проще всего написать базонезависимый код. Сначала приведу код, который будет выполняться в контексте процесса winlogon
section '.remcode' code executable readable writeable
;----------------------------------------
; REMOTE CODE START ---------------------
;----------------------------------------
RemoteCodeStart:
  call .delta
  .delta:
  pop ebp
  sub ebp, .delta

  lea eax, [ebp+SAS_WndTitle]
  push eax
  lea eax, [ebp+SAS_WndClass]
  push eax
  call [ebp+pFindWindowA]
  mov [ebp+SAS_WndHandle], eax

  test eax, eax
  jnz @f
  jmp .thrend
  @@:
  lea eax, [ebp+NewWindowProc]
  push eax
  push GWL_WNDPROC
  push [ebp+SAS_WndHandle]
  call [ebp+pSetWindowLongA]
  mov [ebp+OldWindowProc], eax

  push 10000
  call [ebp+pSleep]

  push [ebp+OldWindowProc]
  push GWL_WNDPROC
  push [ebp+SAS_WndHandle]
  call [ebp+pSetWindowLongA]

  .thrend:
  push 0
  call [ebp+pExitThread]

proc NewWindowProc hwnd, wmsg, wparam, lparam
  call .delta
  .delta:
  pop eax
  sub eax, .delta ; delta offset -> eax

  cmp [wmsg], WM_HOTKEY
  jnz .continue

  cmp [lparam], CtrlAltDel_CODE
  jz .exit_proc
  cmp [lparam], CtrlShiftEsc_CODE
  jz .exit_proc

  .continue:
  push [lparam]
  push [wparam]
  push [wmsg]
  push [hwnd]
  push [eax+OldWindowProc]
  call [eax+pCallWindowProcA]
  jmp .return
  .exit_proc:
  xor eax, eax
  .return:
  ret
endp
SAS_WndClass db 'SAS Window class',0
SAS_WndTitle db 'SAS window',0
SAS_WndHandle dd 0
OldWindowProc dd 0

pFindWindowA dd 0
pSetWindowLongA dd 0
pCallWindowProcA dd 0
pExitThread dd 0
pSleep dd 0

RemoteCodeEnd:
RemoteCodeSize equ RemoteCodeEnd-RemoteCodeStart
;----------------------------------------
; REMOTE CODE END -----------------------
;----------------------------------------

В начале обоих процедур мы сначала вычисляем дельта-смещение, дельта смещение нам нужно, для того чтобы узнать, на сколько отличаются адреса переменных перемещённых с нашим кодом от тех адресов, которые поставил нам компилятор во время компиляции. Зная, дельта-смещение мы можем спокойно обращаться к переменным, не боясь возникновения ошибок доступа к памяти. Приводить полный код программы, я думаю, смысла не имеет, поэтому только приведу код, который подготавливает переменные, копирует код и запускает поток в процессе winlogon
  invoke OpenProcess, PROCESS_CREATE_THREAD or PROCESS_VM_OPERATION or PROCESS_VM_WRITE, FALSE, [proc_entry.th32ProcessID]
  mov [WinlogonProcHandle], eax

  test eax, eax
  jnz @f
  jmp .exit
  @@:

  mov eax, [FindWindow]
  mov [pFindWindowA], eax
  mov eax, [SetWindowLong]
  mov [pSetWindowLongA], eax
  mov eax, [ExitThread]
  mov [pExitThread], eax
  mov eax, [CallWindowProc]
  mov [pCallWindowProcA], eax
  mov eax, [Sleep]
  mov [pSleep], eax

  invoke VirtualAllocEx, [WinlogonProcHandle], 0, RemoteCodeSize, MEM_COMMIT+MEM_RESERVE, PAGE_EXECUTE_READWRITE
  mov [RemoteThreadBaseAddress], eax
  invoke WriteProcessMemory, [WinlogonProcHandle], eax, RemoteCodeStart, RemoteCodeSize, Writed
  invoke CreateRemoteThread, [WinlogonProcHandle], 0, 0, [RemoteThreadBaseAddress], 0, 0, RemoteThreadID

  .exit:
  invoke ExitProcess, 0 

Сначала мы открываем процесс winlogon с нужным нам уровнем доступа (код получения привилегий и получения ID winlogon я не привёл). Потом заполняем переменные, в которых будут храниться адреса используемых API функций, потом выделяем кусок памяти в процессе winlogon, потом копируем туда код, который будет выполняться в его контексте, потом запускаем удалённый поток. Полный код программы приведён в архиве с исходниками к этой статье.

  Наступил статьи конец, кто дочитал тот молодец. Итог, мы написали две программы-каркаса, которые блокируют комбинацию Ctrl-Alt-Del.

Блокируем Ctrl-Alt-Del 

Доброго времени суток. На многих форумах программистов очень часто встречается вопрос «Как заблокировать комбинацию клавиш Ctrl-Alt-Del?». В этой статье я расскажу, как можно реально заблокировать комбинацию клавиш Ctrl-Alt-Del без каких-либо извращений с заменой файлов и прочего. Статья не рассчитана на новичков, читатель этой статьи как минимум должен знать, что такое инжект и запуск удалённых потоков.

  Первое что хотелось бы сказать - это то, что комбинация клавиш Ctrl-Alt-Del предназначена не только для вызова диспетчера задач. В первую очередь она предназначена для вызова окна процесса Winlogon, в котором у нас имеется возможность завершить текущий сеанс, завершить работу компьютера, и, разумеется, вызвать диспетчер задач. Те, кто ставил в WinXP настройки повышенной безопасности, тем знакомо вот это окно.

  Итак, блокировка замена или удаление либо замена его на свой файл самого диспетчера задач Windows (файл taskmgr.exe в системной папке windows) просто делает невозможным его вызов, но по-прежнему (при определённых настройках) комбинация Ctrl-Alt-Del работает и вышеуказанное окно безопасности по-прежнему выводится. А вызвать диспетчер задач можно также через комбинацию клавиш Ctrl-Shift-Esc без вывода этого окна. 

  Сначала подумаем, как можно заблокировать диспетчер задач Windows. Многим сразу придёт в голову идея об удалении или замене файла taskmgr.exe. Во-первых это не так просто так как в Windows XP введена система защиты файлов и при любом изменении её системных файлов она их сразу восстановит. Резервные копии важных файлов находятся в папке system32dllcache. Папка system32 и system32dllcache взаимно связаны и восстанавливаются, друг от друга удаление из system32dllcache влечёт восстановление из system32. Поэтому надо удалять (или заменять) файл taskmgr.exe из обеих папок одновременно. Ладно, мы удалили (или заменили) этот файл, но радость не долгая, выводится сообщение о повреждении системных файлов Windows и просьба вставить диск с дистрибутивом для обновления системы. В принципе и это тоже можно обойти. К чему я веду? К тому, что замена или удаление файлов это не вариант, да и «через жопу» это получается.

  Более внимательные пользователи заметят, что диспетчер задач Windows не запускается два раза, т.е. если он уже запущен, то во второй раз он уже не запустится. И возникает идея о скрытии окна диспетчера, окно скрыто, а он работает и в результате, как ни нажимай Ctrl-Alt-Del или Ctrl-Shift-Esc мы ничего не получим. Следующий код блокирует и разблокирует диспетчер задач Windows.
uses shellapi;

procedure TForm1.Button1Click(Sender: TObject);
var
  TDWH:THandle;
begin
  TDWH:=FindWindow(nil,'Диспетчер задач Windows');
  if TDWH=0 then ShellExecute(0,'open','taskmgr.exe',nil,nil,SW_HIDE)
  else ShowWindow(TDWH,SW_HIDE);
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  TDWH:THandle;
begin
  TDWH:=FindWindow(nil, 'Диспетчер задач Windows');
  ShowWindow(TDWH,SW_SHOWNORMAL);
end;

Всё очень просто. Также вдобавок можно перемещать окно диспетчера далеко за пределы экрана. Итак, задача блокировки диспетчера задач успешно решена. Но наша цель это комбинация клавиш Ctrl-Alt-Del или Ctrl-Shift-Esc. 

  Первая идея, которая возникает, когда надо перехватить комбинации клавиш Ctrl-Alt-Del или Ctrl-Shift-Esc - это воспользоваться стандартным механизмом хуков. Но те, кто уже пытался так сделать, скажут, что через стандартный механизм хуков нельзя перехватить ни одну из важных комбинаций. И возникает такое ощущение, что эти комбинации можно перехватить разве что, написав драйвер-фильтр режима ядра. Но есть другой способ.

  Итак, наша цель - это процесс winlogon.exe, этот процесс управляет входом пользователей в систему и выходом из нее. Процесс winlogon.exe один из основных процессов отвечающих за безопасность системы. Этот процесс нельзя завершить из диспетчера задач, но можно завершить любой другой сторонней программой. Вот только после завершения winlogon.exe сразу буден сгенерирован BSOD. 

  Итак, процесс winlogon.exe очень важен. В нём находится окно с заголовком «SAS window» и классом «SAS Window class» именно этому и только этому окну посылается сообщение WM_HOTKEY, когда были нажаты комбинации Ctrl-Alt-Del или Ctrl-Shift-Esc и ещё несколько важных комбинаций. Найти это окно через функцию FindWindow нельзя, вернее можно, но только будучи в контексте процесса winlogon. Из обычной программы найти это окно нельзя.

  Итак, наша задача подменить оконную функцию окна «SAS window» и отлавливать в нём сообщения WM_HOTKEY, если нажаты эти волшебные комбинации, то просто не вызываем оригинальную оконную функцию. Но чтобы, всё это сделать, нам надо быть в контексте процесса winlogon. Самый простой способ - это внедрить в него нашу DLL. Вот собственно и код этой DLL
library HookDLL;

uses
  Windows,Messages;

var
  OldWndProc: pointer;
  ThreadID:DWORD;

const
  CtrlAltDel_CODE = (VK_DELETE shl 16) or (MOD_CONTROL or MOD_ALT);
  CtrlShiftEsc_CODE = (VK_ESCAPE shl 16) or (MOD_CONTROL or MOD_SHIFT);

function GethWnd: HWND;
begin
  result:= FindWindow('SAS Window class','SAS window');
end;  

function NewWndProc(hWnd: HWND; Msg: UINT; wParam: WPARAM; lParam: LPARAM): LRESULT; stdcall;
begin
  if msg=WM_HOTKEY then
  begin
  if (lParam=CtrlAltDel_CODE) or (lParam = CtrlShiftEsc_CODE) then
  result:= 0 else
  result:= CallWindowProc(OldWndProc, hWnd, Msg, wParam, lParam);
  end else
  result:= CallWindowProc(OldWndProc, hWnd, Msg, wParam, lParam);
end;

procedure SetWndProc(hWnd: HWND);
begin
  OldWndProc:= pointer(SetWindowLong(hWnd, GWL_WNDPROC, cardinal(@NewWndProc)));
end;

procedure UnSetWndProc(hWnd: HWND);
begin
  SetWindowLong(hWnd, GWL_WNDPROC, cardinal(OldWndProc));
end;

function HookThread(PARAM1:DWORD):DWORD; stdcall;
var
  ThrID:DWORD;
begin
  Result:=0;
  SetWndProc(GethWnd);
  sleep(60*1000);
  UnSetWndProc(GethWnd);
  sleep(10);
  CreateThread(nil,0,GetProcAddress(GetModuleHandle('kernel32'),'FreeLibrary'),pointer(hInstance),0,ThrID);
end;

begin
  CreateThread(nil,0,@HookThread,nil,0,ThreadID);
end.

Код этой DLL блокирует комбинации ровно на минуту, потом DLL выгружается из памяти winlogon. Так же можно изменить функцию NewWndProc так чтобы перенаправить заблокированные комбинации на другие, также можно заблокировать любую комбинацию клавиш которую нельзя перехватить через стандартный механизм хуков. А вот и код, который загрузит нашу DLL в процесс winlogon.
function Start(ProcessID: Cardinal; DllFileName: string): Boolean;
var
  hProcess, hTh: THandle;
  BytesWritten, ThreadID, DllNameLen: Cardinal;
  LoadLibraryProc, MemPtr: Pointer;
  ExitCode: DWord;
begin
  Result := false;

  SetDebugPriv();

  hProcess := OpenProcess(PROCESS_CREATE_THREAD or PROCESS_VM_OPERATION or PROCESS_VM_WRITE,true, ProcessID);
  if hProcess = 0 then exit;

  DllNameLen := Length(DllFileName) + 1;
  MemPtr := VirtualAllocEx(hProcess, nil, DllNameLen, MEM_COMMIT, PAGE_READWRITE);
  if MemPtr nil then
  begin //3
  if WriteProcessMemory(hProcess, MemPtr, PChar(DllFileName), DllNameLen, BytesWritten) then
  begin //2
  LoadLibraryProc := GetProcAddress(GetModuleHandle('kernel32.dll'), 'LoadLibraryA');
  hTh := CreateRemoteThread(hProcess, nil, 0, LoadLibraryProc, MemPtr, 0, ThreadID);
  if hTh 0 then
  begin //1
  if (WaitForSingleObject(hTh, INFINITE) = WAIT_OBJECT_0) and GetExitCodeThread(hTh, ExitCode) then
  Result := ExitCode 0;
  CloseHandle(hTh);
  end; //1
  end; //2
  VirtualFreeEx(hProcess, MemPtr, 0, MEM_RELEASE);
  end; //3
  CloseHandle(hProcess);
end;

Эта процедура принимает ID процесса winlogon и путь к нашей DLL. Разумеется, до этого надо позаботиться о получении привилегии «SeDebugPrivilege» чтобы можно было открыть процесс winlogon c нужным нам доступом. Полный код программы и DLL смотрите в архиве с исходниками в конце статьи.
Итак, блокировка Ctrl-Alt-Del и Ctrl-Shift-Esc реализована. Но некоторым не нравится использование DLL. И как всегда возникает вопрос «А можно ли всё сделать без DLL». Ну, разумеется, можно все это сделать и без DLL, через инжект нашего кода в процесс winlogon. 

  Итак, приступим. Нам надо будет внедрить в процесс winlogon код, который будет находить окно и изменять оконную процедуру целевого окна и код самой оконной процедуры. Разумеется, внедряемый код должен быть базонезависимым, так как мы заранее не знаем, по какому адресу мы его скопируем, и ему нужны адреса используемых им API функций. На Delphi сделать это будет уже проблематично. И поэтому сделаем мы это на ассемблере, так как на нём проще всего написать базонезависимый код. Сначала приведу код, который будет выполняться в контексте процесса winlogon
section '.remcode' code executable readable writeable
;----------------------------------------
; REMOTE CODE START ---------------------
;----------------------------------------
RemoteCodeStart:
  call .delta
  .delta:
  pop ebp
  sub ebp, .delta

  lea eax, [ebp+SAS_WndTitle]
  push eax
  lea eax, [ebp+SAS_WndClass]
  push eax
  call [ebp+pFindWindowA]
  mov [ebp+SAS_WndHandle], eax

  test eax, eax
  jnz @f
  jmp .thrend
  @@:
  lea eax, [ebp+NewWindowProc]
  push eax
  push GWL_WNDPROC
  push [ebp+SAS_WndHandle]
  call [ebp+pSetWindowLongA]
  mov [ebp+OldWindowProc], eax

  push 10000
  call [ebp+pSleep]

  push [ebp+OldWindowProc]
  push GWL_WNDPROC
  push [ebp+SAS_WndHandle]
  call [ebp+pSetWindowLongA]

  .thrend:
  push 0
  call [ebp+pExitThread]

proc NewWindowProc hwnd, wmsg, wparam, lparam
  call .delta
  .delta:
  pop eax
  sub eax, .delta ; delta offset -> eax

  cmp [wmsg], WM_HOTKEY
  jnz .continue

  cmp [lparam], CtrlAltDel_CODE
  jz .exit_proc
  cmp [lparam], CtrlShiftEsc_CODE
  jz .exit_proc

  .continue:
  push [lparam]
  push [wparam]
  push [wmsg]
  push [hwnd]
  push [eax+OldWindowProc]
  call [eax+pCallWindowProcA]
  jmp .return
  .exit_proc:
  xor eax, eax
  .return:
  ret
endp
SAS_WndClass db 'SAS Window class',0
SAS_WndTitle db 'SAS window',0
SAS_WndHandle dd 0
OldWindowProc dd 0

pFindWindowA dd 0
pSetWindowLongA dd 0
pCallWindowProcA dd 0
pExitThread dd 0
pSleep dd 0

RemoteCodeEnd:
RemoteCodeSize equ RemoteCodeEnd-RemoteCodeStart
;----------------------------------------
; REMOTE CODE END -----------------------
;----------------------------------------

В начале обоих процедур мы сначала вычисляем дельта-смещение, дельта смещение нам нужно, для того чтобы узнать, на сколько отличаются адреса переменных перемещённых с нашим кодом от тех адресов, которые поставил нам компилятор во время компиляции. Зная, дельта-смещение мы можем спокойно обращаться к переменным, не боясь возникновения ошибок доступа к памяти. Приводить полный код программы, я думаю, смысла не имеет, поэтому только приведу код, который подготавливает переменные, копирует код и запускает поток в процессе winlogon
  invoke OpenProcess, PROCESS_CREATE_THREAD or PROCESS_VM_OPERATION or PROCESS_VM_WRITE, FALSE, [proc_entry.th32ProcessID]
  mov [WinlogonProcHandle], eax

  test eax, eax
  jnz @f
  jmp .exit
  @@:

  mov eax, [FindWindow]
  mov [pFindWindowA], eax
  mov eax, [SetWindowLong]
  mov [pSetWindowLongA], eax
  mov eax, [ExitThread]
  mov [pExitThread], eax
  mov eax, [CallWindowProc]
  mov [pCallWindowProcA], eax
  mov eax, [Sleep]
  mov [pSleep], eax

  invoke VirtualAllocEx, [WinlogonProcHandle], 0, RemoteCodeSize, MEM_COMMIT+MEM_RESERVE, PAGE_EXECUTE_READWRITE
  mov [RemoteThreadBaseAddress], eax
  invoke WriteProcessMemory, [WinlogonProcHandle], eax, RemoteCodeStart, RemoteCodeSize, Writed
  invoke CreateRemoteThread, [WinlogonProcHandle], 0, 0, [RemoteThreadBaseAddress], 0, 0, RemoteThreadID

  .exit:
  invoke ExitProcess, 0 

Сначала мы открываем процесс winlogon с нужным нам уровнем доступа (код получения привилегий и получения ID winlogon я не привёл). Потом заполняем переменные, в которых будут храниться адреса используемых API функций, потом выделяем кусок памяти в процессе winlogon, потом копируем туда код, который будет выполняться в его контексте, потом запускаем удалённый поток. Полный код программы приведён в архиве с исходниками к этой статье.
  Наступил статьи конец, кто дочитал тот молодец. Итог, мы написали две программы-каркаса, которые блокируют комбинацию Ctrl-Alt-Del.



Категория: Хакинг и безопасность | Добавил: p3ntum
Просмотров: 781 | Загрузок: 0 | Рейтинг: 0.0/0 |
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
|