Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

TaskManeger [D5, D6, NT4, Win2k]


Страницы:   1 2 3

TOLTEC ©   (2002-03-01 17:17:00) 

Как отловить событие отрубание моей программы TaskMeneger - ом


paul_shmakov   (2002-03-15 07:12:00) [21]

Ну и несколько исходников (в кладовке inject1.rar и inject2.rar). Они на с++. Первый файл содержит
простенький пример к пункту 1.1.; второй - к пункту 2.1.
Первый пример настроен на присоединение к Notepad. Поэтому перед
запуском loader.exe следует запустить Notepad.
Насчет второго: это очень ограниченная по функциональности версия
автоматического патчера - например, патчер сработает только если
программа импортирует функцию LoadLibrary, кроме того, в основном
патчит только майкрософтовские программы (скомпанованные ms линкером)
- про остальные говорит, что не может. Для ее тестирования рекомендую
использовать internat.exe.
В общем, это простая версия, призванная показать концепцию. Сейчас
работаю над куда более совершенной.


paul_shmakov   (2002-03-15 07:11:00) [22]

2.2. Изменение таблицы импорта. Идея состоит в том, чтобы заставить
стандартный виндовый загрузчик подумать, что программа статически
использует вашу dll. Для этого необходимо, чтобы ваша dll
экспортировала хотя бы одну произвольную функцию (функция может быть
абсолютно любая, т.к. никто и никогда ее на самом деле вызывать не
будет). Добавляем в таблицу импорта pe-файла новую запись, имя вашей
dll, количество импортируемых функций равное 1, имя или ординал
импортируемой функции и поле для адреса этой функции. У этого
способа есть достоинства и, к сожалению, недостатки. Загружать вашу
dll будет уже не какой-то loader.exe, а стандартный виндусовый
загрузчик pe-файлов, что конечно очень хорошо. А недостатки, опять
же, технические: в секции импорта должно быть достаточно места для
вышеназванных данных, что не всегда так. Если я не ошибаюсь, то на
эту тему очень хорошо писал Крис Касперски.
2.3. Подмена стандартной dll. Берем какую-нить стандартную dll с
небольшим кол-вом экспортируемых функций, подменяем ее своей с
такими же функциями. А в наших функциях просто перенаправляем вызов
к оригинальным функциям.

Мне способы 2.1 и 2.2. кажутся наиболее удобными.
Во всех способах исользуются достаточно низкоуровневые возможности
windows. Рекомендую, прежде, чем начинать, почитать Джефри Рихтера
(обязательно), Мэта Питрека (хотя бы частично) и несколько статей по
pe-формату из интернета. Несколько, потому что есть различия в
описании формата как в статьях, так и в exe-шниках(!), получаемых от
линкеров различных производителей. Ну а для проверки знаний -
одназначно hiew.exe (особенно хороша самая последняя версия 6.76).


paul_shmakov   (2002-03-15 07:10:00) [23]

2. Статическое внедрение. Именно этот способ я предпочитаю
использовать - лучше чтобы не было никаких loader-ов, а только
жертва и наша dll. Я уже притомился писать ;) и поэтому опишу
коротко.
2.1. Добавление в pe-файла нескольких инструкций:
call loadlib
db "МояЛюбимая.dll", 0
loadlib:
call LoadLibraryA
jmp OriginalEntryPoint
Этот код можно добавить либо в существующую секцию с кодом (обычно
.text) (если там есть свободное место, либо создать свою секцию.
После этого подправить несколько полей в pe-заголовке, в частности
EntryPoint, чтобы он указывал на новый код. Этот способ (который,
кстати я и использую) имеет свои достоинства и недостатки. Если в
предыдущем варианте требовалось, чтобы запускался loader.exe , что
дает пользователю возможность проследить по реестру и автозагрузке,
что какой-то loader.exe запускается, то в этом варианте запускается
только программа-жертва и все. Недостатки же чисто технические. Во
первых требуется, чтобы программа-жертва импортировала функцию
LoadLibraryA (или LoadLibraryW, или по ординалу). Если не
импортирует, то читай 2.2. Далее, способ не универсальный, т.е. в
случае с internat.exe придется делать версию под каждую версию
виндов. Хотя это не так сложно, если написать автоматический патчер.


paul_shmakov   (2002-03-15 07:09:00) [24]

1.4. Еще один способ, очень похожий на 1.2., но куда более
универсальный. Так же требует знаний ассемблера. Самому писать
лениво :), поэтому отсканирую Рихтера. Он, правда, очень примерные инструкции
дает. Но если заинтересует именно этот метод, то я могу подробно
описать (вроде даже я это в какой-то проге использовал).
--- cut ---
Внедрение кода через функцию CreateProcess
Если Ваш процесс порождает дочерний, в который надо внедрить
какой-то код, то задача значительно упрощается. Родительский
процесс может создать новый процесс и сразу же приостановить его.
Это позволит изменить состояние дочернего процесса до начала его
выполнения. В то же время родительский процесс получает описатель
первичного потока дочернего процесса. Зная его, Вы можете
модифицировать код, который будет выполняться этим потоком. Тем
самым Вы решите проблему, упомянутую в предыдущем разделе: в данном
случае нетрудно установить регистр указателя команд, принадлежащий
потоку, на код в проекции файла.
Вот один из способов-контроля за тем, какой код выполняется
первичным потоком дочернего процесса:
1. Создайте дочерний процесс в приостановленном состоянии.
2. Получите стартовый адрес его первичного потока, считав его из
заголовка исполняемого модуля.
3. Сохраните где-нибудь машинные команды, находящиеся по этому
адресу памяти.
4. Введите на их место свои команды. Этот код должен вызывать
LoadLibrary для загрузки DLL
5. Разрешите выполнение первичного потока дочернего процесса.
6. Восстановите ранее сохраненные команды по стартовому адресу
первичного потока.
7. Пусть процесс продолжает выполнение со стартового адреса так,
будто ничего и не было.
Этапы 6 и 7 довольно трудны, но реализовать их можно — такое уже делалось.
У этого метода масса преимуществ. Во-первых, мы получаем адресное
пространство до выполнения приложения. Во-вторых, данный метод
применим как в Windows 98, так и в Windows 2000. В третьих, ...
--- cut ---


paul_shmakov   (2002-03-15 07:08:00) [25]

2) внедрение dll в адресное пространство
чужого процесса: 2.1) внедрение динамически, 2.2) внедрение статически
(т.е. физический patch файла).

На второй вопрос, а особенно на 2.1, можно найти очень много
информации. _Кратко_ опишу основные методы (пусть Ваша dll называется
mydll.dll):
1. Динамическое внедрение, т.е. когда программа-жертва ужу запущена. В
этом случае требуется программа загрузчик (пусть loader.exe).

1.1. внедрение с помощью ловушек. Последовательность действий следующая:
а) loader.exe установливает глобальный хук. Функция обработчик хука
реализована в некой dll (пусть inject.dll).
б) основному окну программы-жертвы посылаеться любое сообщение.
в) для перехвата этого сообщения в программу-жертву автоматически
подгружаеться inject.dll, и вызывается функция-обработчик хука.
г) функция-обработчик хука загружает нашу библиотеку, т.е.
LoadLibrary("mydll.dll").
д) loader.exe снимает глобальный хук, чтобы inject.dll не грузилась
еще и во все остальные процессы.
е) из-за снятия хука inject.dll автоматически выгружается из
адресного пространства программы-жертвы, а вот mydll.dll
остается там работать! что и требовалось совершить.
Это универсальный способ, для всех версий виндов. Я считаю его
наиболее приемлемым из динамических.

1.2. Загрузка программы-жертвы в режиме отладки. Это более сложный и
менее универсальный способ, хотя тоже подходит для всех версий.
Главный недостаток в том, что loader.exe остаеться в памяти на все
время работы программы-жертвы, что не удовлетворяет условиям задачи
(никаких нащих процессов). Поэтому я не буду его здесь описывать.

1.3. внедрение с помощью удаленных потоков. Этот способ только для
WinNT, т.к. используется функции CreateRemoteThread.
а) loader.exe открывает процесс-жертву с помощью OpenProcess.
б) выделяется область памяти в адресном пространстве
процесса-жертвы с помощью pMyDllName = VirtualAllocEx.
в) копирование в эту область строки с названием нашей dll, т.е.
"mydll.dll" (WriteProcessMemory).
г) создание удаленного процесса.
CreateRemoteThread(hProcess, NULL, 0,
GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA"),
pMyDllName,
0, &tid).
Поток создаеться, выполняется, загружая нашу dll, и завершаеться.
Все!


paul_shmakov   (2002-03-15 07:06:00) [26]

«Компонента»
Создание такой библиотеки ничуть не сложнее создания обычной dll или приложения с аналогичной функциональностью. Просто нужно придерживаться некоторых правил. Сразу предупрежу: я буду приводить примеры кода на С++, хотя для других языков код будет полностью аналогичным.
Выполнение вашего приложения должно начинаться с момента вызова функции DllMain с параметром dwReason равным DLL_PROCESS_ATTACH и заканчиваться в вызове той же функции с DLL_PROCESS_DETACH.
DLL_PROCESS_ATTACH
Код вашей библиотеки должен выполняться в отдельном собственном потоке. Поэтому в обработчике события DLL_PROCESS_ATTACH создаем новый поток функцией CreateThread. Кстати, как показывает практика здесь можно создать произвольное количество потоков, а не только один, как написано в некоторых источниках. Перед созданием потока следует вызвать DisableThreadLibraryCalls для того, чтобы предотвратить вызов DllMain при каждом создании и уничтожении потоков в процессе. Этот поток (или потоки) и будет выполнять главную функцию вашей библиотеки.
DLL_PROCESS_DETACH
При обработке этого события следует уведомить созданный поток(и) о завершении работы (например, установить объект-событие), дождаться их завершения и вернуть управление.

Функции потоков будут достаточно простыми. Единственное, что им нужно делать (помимо полезной работы) - это проверять объект-событие (а не пора ли завершиться).

Далее про внедрение в чужое адресное пространство.


paul_shmakov   (2002-03-15 07:02:00) [27]

Концепция контейнеров и компонент в последнее время становиться все моднее - компоненты Delphi, ActiveX, Enterprise JavaBeans, CORBAcomponents. И не случайно. Это действительно очень удобная парадигма, когда компонента занимается только своей бизнес-функцией, а остальные задачи ложаться на контейнер. Распространить эту концепцию можно и на традиционные приложения с несколько нетрадиционной стороны. В этой статье будет описан способ реализации приложения в виде динамической библиотеки (dll) (компонента), которая будет выполняться в контексте чужого процесса (контейнер).
Для чего все это нужно? Ответы могут быть различными. Например, ваше приложение выполняет не совсем «легальную» функцию, и вы, соответственно, не хотите, чтобы пользователь видел запущенный незнакомый процесс. В данном случае применяются всевозможные техники для скрытия процесса из списка работающих приложений (например, RegisterServiceProcess для Windows 9x), которые сильно ограничены в своих возможностях. И задача остается нерешенной (о чем свидетельствует статистика, по которой вопрос «Как скрыть процесс из списка работающих приложений?» появляется в форумах не реже, чем раз в две недели).
Вот здесь-то и может помочь техника реализации приложения в виде dll и внедрения ее в адресное пространство некоего процесса. Примером такого процесса может служить программа internat.exe, которая отвечает за переключение раскладки клавиатуры. Удобна она тем, что постоянно загружена, и не у кого из пользователей не вызывает никаких подозрений и желания ее выгрузить. Может быть использована и любая другая программа, отвечающая требованиям конкретной задачи, но в этой статье в качестве «жертвы» будет рассматриваться именно internat.exe.
Реализация этой идеи состоит из двух задач: 1) создать dll, которая будет способна выполняться в качестве «компоненты»; 2) заставить internat.exe против его желания стать «контейнером», т.е. загрузить вашу dll.


paul_shmakov   (2002-03-15 07:02:00) [28]

насчет скрытия процессов. я об этом писал уже здесь в сообщениях и многим по почте, собирался оформить в виде статьи - но видать не судьба... здесь я запостю отдельные части всего этого.
итак, смысл в том, чтобы реализовать все свое приложение в виде dll, потом подгрузить эту dll в чужой процесс, и пусть она там делает все, что надо. и никаких лишних процессов.


VuDZ   (2002-03-15 03:53:00) [29]

ещё вариант - пишем некое подобие вируса, который следит - шансы, что его убьют - очень малы.

кстати - делаем у проги окно, нивидимое - тогда taskMan, по правилам посылает ему WM_QUIT - запускаем другой экземпляр приложения-монитора и закрываемся. Как мысль?


Алексей Петров   (2002-03-14 23:35:00) [30]

> VuDZ © (14.03.02 18:46)
> можно CreateRemoteThread - но это сложнее
Это не проще и не сложнее. Я написал что делать, не уточняя как.
CreateRemoteThread - это один из вариантов "как"..
Другой вариант - с помощью hook-ов - он попроще и более универсальный (он и под Win9x работать будет).


VuDZ   (2002-03-14 18:46:00) [31]

можно CreateRemoteThread - но это сложнее


Алексей Петров   (2002-03-14 08:47:00) [32]

Нет не "закосить" и не спрятать, а именно чтоб не было :)

Т.е. запускаешь программу, она влезает в соседний процесс и выгружается. А все работу делает уже "там".


Gluka   (2002-03-14 01:04:00) [33]

For Alex_LG (13.03.02 23:42)

Если сможешь перехватить вызовы функции, то можешь
идти далее:
http://delphi.mastak.ru/cgi-bin/forum.pl?look=1&id=1011513000&n=5


Alex_LG   (2002-03-13 23:42:00) [34]


> Алексей Петров © (04.03.02 14:23)
> Единственный способ гарантировать невозможность убийства
> процесса - сделать так, чтоб процесса не было. Это не шутка,
> а вполне рабочая рекомендация.

можно чуть расшифровать, плз? то есть "закосить" под чужой процесс или как?


Tosov   (2002-03-06 19:39:00) [35]

В общем - какая разница - вырубить можно практически любой процесс, в т.ч. и winlogon и services. Правда с последствиями, но можно.


VuDZ   (2002-03-06 19:27:00) [36]

мне проще набрать at 7:28PM /INTERACTIVE taskmgr.exe :>


Tosov   (2002-03-06 00:37:00) [37]

>да, только для этого надо запустить taskman с привилегиями системы
Да вроде не обязательно.. Из своей проги - SeDebugPrivilege + TermitateProcess. Из чужих,например, Far (версия 1.70) очень легко грохает почти все системные процессы.

>со своей программой установки
И ведь установят же :)


VuDZ   (2002-03-04 23:07:00) [38]


> Процесс под SYSTEM может убить и админ.

да, только для этого надо запустить taskman с привилегиями системы, а это не каждый могёт :>


> Может расскажешь зачем надо? Интересно стало..

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


Tosov   (2002-03-04 18:17:00) [39]

Алексей Петров
Процесс под SYSTEM может убить и админ.

TOLTEC
Может расскажешь зачем надо? Интересно стало..


Алексей Петров   (2002-03-04 14:23:00) [40]

Правда, если процесс работает под "SYSTEM" его можно убить TaskManager-ом работающим из под "SYSTEM"

Единственный способ гарантировать невозможность убийства процесса - сделать так, чтоб процесса не было. Это не шутка, а вполне рабочая рекомендация.


Страницы:   1 2 3

Наверх

Титульная страница Поиск, карта сайта Написать письмо