Я починаю писати цикл статей про те, як можна програмно поприколюватися в Windows. Привіт чукотським виримейкерам і троянописателям :). В принципі всі дії, які я буду описувати, не є самі по собі руйнівними, але можуть попсувати дуже багато нервів юзерам, особливо недосвідченим. Я сподіваюся зробити щось на зразок колекції приколів. Всі програми будуть писатися на Delphi. Якщо Ви хочете доповнити колекцію — пишіть мені на мило.

Почнемо з загальних питань.

1) Невидимка

Робимо свою програму невидимої в списку запущених програм Ctrl+Alt+Del

Для цього потрібно завантажити функцію RegisterServiceProcess з KERNEL32.DLL.

function RegisterServiceProcess (dwProcessID, dwType:DWord): DWORD

У цій функції 2 параметра Dword:

dwProcessID-ідентифікатор процесу, що викликає функцію.
dwType-0 або 1. Якщо 1, то невидимість включена, 0-виключена.
Пишемо код:

type
//тип завантажуваної процедури
TRegisterServiceProcess = function (dwProcessID, dwType:DWord): DWORD; stdcall;

// включення невидимості
procedure TForm1.Button1Click(Sender: TObject);
var hNdl :THandle; //хзндл DLL
R: TRegisterServiceProcess; //змінна процедурного типу
begin
if not(csDesigning in ComponentState) then //якщо знаходимося не в Delphi IDE
begin
hNdl:=дзвінки на loadlibrary(‘KERNEL32.DLL’); //завантажуємо DLL
R:=GetProcAddress(hNdl, ‘RegisterServiceProcess’); //отримуємо функцію з DLL
R(GetCurrentProcessID, 1); //викликаємо функцію
FreeLibrary(hNdl); //звільняємо DLL
end;
end;

//відключення невидимості
procedure TForm1.Button2Click(Sender: TObject);
var hNdl :THandle; // хзндл DLL
R: TRegisterServiceProcess; //змінна процедурного типу
begin
if not(csDesigning in ComponentState) then // якщо знаходимося не в Delphi IDE
begin
hNdl:=дзвінки на loadlibrary(‘KERNEL32.DLL’); // завантажуємо DLL
R:=GetProcAddress(hNdl, ‘RegisterServiceProcess’); // отримуємо функцію з DLL
R(GetCurrentProcessID, 0); // викликаємо функцію
FreeLibrary(hNdl); // звільняємо DLL
end;
end;

Я відключив невидимість при запуску програми в Delphi IDE, бо тоді стане невидимим сам Delphi.

Ця невидимість працює тільки по Ctrl-Alt-Del. Просунуті ж програми, які використовують перебирання всіх процесів, нашу програму побачать. Наприклад, я для обчислення троянів використовую CodeStuff Starter.

2) Відключення комбінацій клавіш Ctrl-Alt-Del, Alt-Tab, Ctrl-Esc:

Для цього ми скористаємося функцією SystemParametersInfo. Ця функція дозволяє переглядати і змінювати системні параметри.

BOOL SystemParametersInfo(
UINT uiAction, // системний параметр для зміни
UINT uiParam, // залежить від виробленого дії
PVOID pvParam, // залежить від виробленого дії
UINT fWinIni // оновлювати профіль юзера чи ні
);

Якщо функція спрацювала без помилок, то вона повертає ненульове значення, інакше — нуль.

У перший параметр передаємо SPI_SCREENSAVERRUNNING, у другій 1, якщо відключаємо клавіші, і 0, якщо включаємо, 3-ій і 4-ий параметри нулі.

Взагалі функція SystemParametersInfo дуже корисна і ми часто будемо використовувати.

//Відключення комбінацій клавіш Ctrl-Alt-Del, Alt-Tab, Ctrl-Esc
procedure TForm1.Button3Click(Sender: TObject);
begin
SystemParametersInfo(SPI_SCREENSAVERRUNNING,1,0,0);
end;

//Включення комбінації клавіш Ctrl-Alt-Del, Alt-Tab, Ctrl-Esc
procedure TForm1.Button4Click(Sender: TObject);
begin
SystemParametersInfo(SPI_SCREENSAVERRUNNING,0,0,0);
end;

3) Зміна напису на вікнах відкритих додатків

Пишемо код:

procedure TForm1.Button5Click(Sender: TObject);
Var Wnd:THandle; //хендл вікна
begin
Wnd:=findWindow(0,PChar(Edit1.text)); //шукаємо вікно за назвою
if (Wnd0) then SetWindowText(Wnd,PChar(Edit2.text)) //змінюємо назву вікна
else MessageBox(Application.handle,’Немає такого вікна’,’Помилка’,MB_OK);
end;

Тепер все по-порядку. Функція

HWND FindWindow(
LPCTSTR lpClassName, // Покажчик на рядок-назва класу вікна
LPCTSTR lpWindowName // Покажчик на рядок-заголовок вікна
);

Ця функція, якщо знаходить вікно, відповідає даній назві класу вікна і назві вікна, повертає його хендл. Якщо такого вікна немає, то функція повертає 0. Ми не знаємо назва класу вікна, тому в перший параметр ми передаємо 0.

Функція

BOOL SetWindowText(
HWND hWnd, //хендл вікна
LPCTSTR lpString // покажчик на рядок-нова назва вікна
);

Ця функція дозволяє змінити назву вікна, хендл якого передається в першому параметрі на рядок вказівник на яку передається у другому параметрі. Вона повертає ненульове число, якщо завершується успішно. У випадку помилки вона повертає 0. Щоб дізнатися інформацію про помилку потрібно викликати функцію GetLastError.

На сьогодні вистачить. Наступного разу я розповім про вікна, які неможливо закрити штатними засобами Windows і про цветомузыке на клавіатурі.