Здравствуйте, уважаемые! Встала задача морозить процессы по желанию и на желанное время. Полезная штука оказалась (в задумках), а вот как на самом деле реализовать? Идея была такая: перехватываю KiSwapThread, правлю, где надо, чтобы следующая нить (если на очереди та, процесс которой морозим) была лишь Idle - нить. Но вот встала задача: как найти хотя бы KiSwapThread. Поглядел на KeTerminateThread, а там в самом конце - KiSwapThread. Оно вроде и логично, да вот в SoftIce смотрю - так нет ничего такого, ещё куча вызовов... Может быть кто-нить знает способ откопать эту ф-ю. Или может не надо это так делать. Может порозить можно и по-другому... ??? Заранее благодарен. ---===PavPS===---
Для этого не обязательно даже драйвер писать. Просто перебирай нити процесса и вызывай для каждой SuspendThread, а при запуске - ResumeThread а извращаться с планировщиком вовсе ненужно. Или стоит задача обязательно сделать именно так?
2 ProgramMan Чем я тока по ядру не ходил, но найти так и не нашел... пож и находил, но не уверен. Нужно для XP 2 Ms Rem. Это проосто, не стал бы српашивать, и ненедёжно. Нуж но насмерть и именно так. Ну пусть я дл ясвоей версии найду, а для других заново искать.Что мини-дазасм писать? Кто что посоветует? (Если я, допустим узнаю, что где-то 3 вызова ф-ии указывают на эту и её надо найти) ? ЗЫ И всё же вопрос остаётся....
KiSwapThread - не экспортируемая функция, поэтому с перехватом у Вас будут большие проблемы. 1)Почему SoftICe ее не видит? Поскольку по умолчанию у софтайса нет символьной информации ядра, он отобраает только экспортируемые имена. В принципе, в составе DS есть тулза для закачки символьной информации с сайта микрософта, но я не пробывал, да и много их (чего то в районе 500М) 2)Допустим Вы нашли KiSwapThread. Перехватить неэкспортируемую функцию можно только подправив ее пролог. Для этого нужно знать адрес функции. В каждом билде ядра с вероятностью 99% он будет менятся. Придется Вам исследовать все возможные ядра.
Перехват KiSwapThread ненадежная штука. У тебя он может заработать, а у других вызвать BSOD. В новой версии винды точно работать не будет. А если нужно остановить процесс наверняка, то получай в драйвере список нитей через ZwQuerySystemInformation сделай CLI и потом юзай NtSuspendThread (ее адрес можно найти в SDT). Это гарантирует, что остановка потоков не будет прервана и процесс будет 100% остановлен.
А на многопроцесорной системе придется запрещать прерывания на всех процессорах. По-моему лучше тогда далать это управляя контролером прерываний, это позволит вырубить сразу все процессоры. Может есть какие варианты получше. Если кто знает, как еще остановить все процессоры (может API какая есть) прошу написать, самому приходилось с многопроцессорными системами возиться.
Адрес KiSwapThread для конкретного SP можно в соответствующем ntoskrnl.pdb посмотреть (скачать можно symbol retriever'ом). Сайс его знает, если символы установлены table ntoskrnl u @KiSwapThread Для XPSP2 == 804dc66e
2 S_T_A_S_ Ага, знает, он по-моему его и хучит, чтобы всё тормозить. И работает не только на моём 2600 build а и на других... И как это он так? А по этому адресу у меня inc ebp int 3 Если поднять например:KiLockContextSwap, то это я сам встану на месте. А мой процесс должен жить. А определенные благородно одаривать Idle квантами тайма. Что касается опять, SuspendThread, то это кто-то может и Resume вызвать, а для меня это смертельно Да, ещё тут "вспомнил", что ещё дела свапа контекста идут от dispatch interrupt, вызывая вместе с KiSwapThread одну и туже ф-ю SwapContext@??? может её захучить... ЗЫ Ну, короче надо останавливать наверняка! И чтобы, как правильно подметил Ms Rem , BSOD не было ЗЗЫ Интересно, стоит ли дизасмить ntice.sys ? ... мож там чё найду... Сёдня весь день убил, а нового ничего
2 Dr.Golova CLI... ну вот при вызове DeviceIoControl я в драйвере вызову CLI и что? Вернувшись в user-оболочку что-нибудь измениться? Все процессы встанут? Или я остановлюсь? Что будет? Оч. кажется, что ничего.Совсем ничего...
Да, совсем забыл. Можно остановить все остальные процессоры, кроме своего. Смотри исходники IceExt для этого.
Да зачем гемор на многих процессорах. Именно на однопроцессорный пока что... Потом уж и на многопроцессорный посмотрим...
Короче, есть такая идея: Найти все потоки останавливаемого процесса, определить адреса их ETHREAD и поставить каждому в очередь Kernel Mode APC, который будет ждать на созданном событии. (KeWaitForSingleObject) и процесс 100% остановиться до момента установки события. Из User Mode запустить процесс будет невозможно, из Kernel Mode можно только зная адрес KEVENT. Я думаю, это то что тебе надо, если пойдет, то могу привести код это делающий.
А оно не будет слишком зависимым от операционки? То есть, ведь формат ETHREAD зависит от ОСы? Может, просто поднять приоритет своего треда до реалтайма- так оно проще будет. А на сырец было бы интересно посмотреть.....
Ms Rem, метод оригинальный - слов нет.... но вот вопрос - можно ли на 100% быть уверенным что переключения конекста на таргет-процесс не произойдет?
Надоело это беспочвенное обсуждение, сейчас делать нефиг, напишу остановку процесса описанным методом, и в следующем посте будет полный код для этого.