Издательский дом ООО "Гейм Лэнд"ЖУРНАЛ ХАКЕР #75, МАРТ 2005 г.

Программа-невидимка

Николай "GorluM" Андреев

Хакер, номер #075, стр. 075-110-4


Функция перечислит все модули для текущего процесса и в каждом поправит таблицу импорта, заменив адрес функцию CreateProcessA на наш обработчик (запускать эту функцию надо из уже внедренного кода), после чего все создающиеся процессы будут перехватываться. Таким же образом нам надо перехватить и обработать функции CreateProcessW (т.е. уникод-версию) и все семейство LoadLibrary, на случай, если какой-нибудь процесс захочет в процессе работы подгрузить к себе библиотеку. Простой пример: если включить уже готовую невидимку без перехвата загрузки DLL, то файл программы будет легко обнаружить - нужно будет всего лишь загрузить Internet Explorer, а затем зайти им не на сайт, а в системную директорию, при этом подгрузится shell32, работающий с файлами, но не будет перехвачен.

Скрываем наш файл

В Windows для работы с файлами есть несколько функций, которые и следует перехватить и немного обработать. Это функции получения первого файла и хэндла поиска - FindFirstFile(A\W), и функции получения всех следующих за ним файлов FindNextFile(A\W). Нужно написать свои версии этих функций так, чтобы они выводили все файлы, кроме нашего. Делается это достаточно легко. Как и в случае с CreateProcess, создается функция объявленная также как и перехватываемая, в которой вызывается оригинал. Он возвращает, согласно MSDN, в структуру WIN32_FIND_DATA все данные о файле, которые мы сверяем с данными о файле, который мы хотим скрыть. Если они не совпадают - оставляем все как есть, если совпадают - просто вызываем функцию для получения следующего файла. Если же файл последний в списке и следующего нет - возвращаем ошибку ERROR_NO_MORE_FILES.

HANDLE WINAPI xFindFirstFileA (PCSTR lpFileName, PWIN32_FIND_DATAA lpFindFileData)

{

HANDLE ret = FindFirstFileA(lpFileName, lpFindFileData);

if (lstrcmpiA(lpFindFileData->cFileName,FILENAME) == 0)

{

if (!FindNextFileA(ret, lpFindFileData)) {

SetLastError(ERROR_NO_MORE_FILES);

return INVALID_HANDLE_VALUE;

}

}

return ret;

}

Функций похожего содержания еще 3, все лежат аккуратненько на диске и ждут момента, когда ты на них посмотришь. Работают, как я уже сказал, по одному и тому же принципу - подсовывают, если имя файла совпало с FILENAME, другой файл. Стоит внедрить такие функции во все процессы и модифицировать соответствующим образом таблицу импорта, как сразу все приложения (вроде far'а или explorer'а) забывают о существовании твоей программы.

Скрываем запись в реестре

Для перечисления всех ключей в реестре служит функция RegEnumValue(A\W). Поэтому, если мы хотим, чтобы о ключах, созданных нашей программой система забыла нужно эту функцию перехватить и немного подкорректировать ее вывод. Пусть, скажем, если имя возвращаемого ключа равно имени нашего файла, этот ключ выводиться не будет, а функция вернет ошибку. Нет проблем, реализуется легко.

LONG WINAPI xRegEnumValueA(HKEY hKey, DWORD dwIndex, LPSTR lpValueName, LPDWORD lpcValueName, LPDWORD lpReserved, LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData)

{

LONG ret = RegEnumValueA(hKey, dwIndex, lpValueName, lpcValueName, lpReserved, lpType, lpData, lpcbData);

Назад на стр. 075-110-3  Содержание  Вперед на стр. 075-110-5