![]() |
Проблемы с написанием драйвера
Вот сталкнулся с такой проблемой:
Програма должна постоянно считывать через из драйвера через: ReadFile струткуру следующего типа: typedef struct _TMySTRUC // структура описывающая запрос к драйверу { HANDLE z1; HANDLE z2; } TMySTRUC, *PMySTRUC; ВОт не могу написать как именно осуществить запись со стороны драйвера. к примеру: Код:
TMySTRUC mystruc;КАк я понял irpStack->MajorFunction == IRP_MJ_READ будет тогда когда програма будет читать данные из драйвера т.е. readfile, а IRP_MJ_WRITE - когда будет писать чтото драйверу. Перебрал кучу документаций так толком и не понял как осуществить чтение и запись. |
какой тип ввода-вывода?
1) если buffered (DO_BUFFERED_IO), тогда Irp->AssotiatedIrp.SystemBuffer указывает на системный буффер, который потом будет скопирован в пользовательский выходной (если это IRP_MJ_READ) или в который уже скопирован входной (если это IRP_MJ_WRITE) другие типы тебе пока не нужны.. запутаешься нафиг. тебе нужно лишь проверить длину буффера и скопировать туда структуру |
Чтото начал делать в этоге при копировании идет BSOD
Вообще драйвер должен перехватывать запуск процессов. И потом по требованию возвращать PID и PARENT последнего запущенного процесса. Код функции обработчика: Код:
if (irpStack->MajorFunction == IRP_MJ_READ)TRUNPROC RUNPROC typedef struct _TRUNPROC { HANDLE parent; HANDLE PID; } TRUNPROC, *PRUNPROC; И вот вопрос еще один. Как мне получать то, что выводится через DbgPrint? Юзаю WinDbg. Т.е. я запускаю через него прогу, которая общается с драйвером, но почемуто сообщения от DbgPrint на экране они не появляются :( |
Путаешь. Для просмотра сообщений от DbgPrint тебе нужен DebugView от Sysinternals.
Сейчас посмотрю код. |
Если я не ошибаюсь, то для передачи информации драйвер<->программа драйвер должен создать устройство, через которое будет передаваться инфа. Вот тебе:
http://www.wasm.ru/article.php?article=apihook_3 (см.Взаимодействие драйвера с приложением) И вот: http://wasm.ru/article.php?article=drvw2k04 |
не с устройсвом всё ок. всё создано отлично. И пашет отлично. А вот тока как именно драйвер должен передать ответ - хз.
На счет васма - процел всё - толком там не описано. |
Да сделай ты через DeviceIoControl, проще будет, один из аргументов функции - буфер для обратного ответа. Будешь передавать драйверу IOCTL коды.
Код:
#define IOCTL_GETPID CTL_CODE(FILE_DEVICE_UNKNOWN, 0x01, \Код:
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = MyIrp; |
с DbgPrint разобрался +
---------- Суть в том, что я юзаю DeviceIoControl для чуть другйо функции. а именно - защита процесса. Чтобы его не могли выкинуть стандартными методами. у меня он заюзан вот так: if (irpStack->MajorFunction == IRP_MJ_DEVICE_CONTROL) ProtectedPid = (HANDLE)irpStack->Parameters.DeviceIoControl.IoControlCode; |
2 Ni0x В принципе можно былобы и сделать как ты говоришь, но тогда таже проблема - чтение и запись.
|
И в чем проблема использовать DeviceIoControl для всего?
|
переписал на DeviceIoControl
но чуть не допер как получить параметр. сделал вот что. но тут чегото не хватает. А именно знаний в С: Код:
if (irpStack->MajorFunction == IRP_MJ_DEVICE_CONTROL) |
Тут указаны примеры для разных методов:
Код:
stack = IoGetCurrentlrpStackLocation (Irp); Цитата:
|
Цитата:
|
подскажите что я делаю не так. почему BSOD?
При установке ProtectedPid - ставится всё нормально и пашет отлично. А при чтении его - BSOD. читаю через PID,TrId:dword; DeviceIoControl(hDriver, $23456, nil, 0, @PID, 4, TrId, nil); Вот код обработчика Код:
HANDLE ProtectedPid; |
Кто тебе сказал что ты можешь какие угодно io control code задавать?
Юзай макрос IOCTL_CODE() Самое главное - тип ввода-вывода (младшие 2 бита), у тебя видно тип не buffered во втором случае (да и в первом тоже) |
2 _Great_ Ты имеешь ввиду что именно через CTL_CODE и истанавливаются прва на запись, чтение и мето ввода-вывод?
Вот еще сталкнулся с такой проблемой. Иногда почемуто програма не может связаться с драйвером. Драйвер у меня как сервис. Поэтому я делаю: net stop MyDRV потом перекомпиливаю драйвер затем: net start MyDRV Все пахало нормально. но потом через несколько перезагрузок почемуто из програмы не возможно связаться с драйвером. т.е. CreateFile('\\.\MyDRVS', GENERIC_ALL, 0, nil, OPEN_EXISTING, 0, 0); возвращает INVALID_HANDLE_VALUE Хотя драйвер пашет нормально - по дебаговым сообщением видно что создания процессов перехватываются. НО связи по сей час нет. уже перезагружался пару раз - дохлое дело. Также заметил один интерестный факт. Вроде все програмы и DLL ки виндовые отображаются на память, а драйвера получается что нет? потому что при запущенном драйвере можно спакойно удалить файл драйвара. |
А самому лень посмотреть?
winioctl.h Код:
#define CTL_CODE( DeviceType, Function, Method, Access ) ( |
Цитата:
И DLL и EXE любую можно удалить без проблем как и драйвер. Просто после загрузки драйвера винда не лочит попытки удаления его файла на диске, а для user-mode модулей - лочит. Т.е. файл остается открытым для user-mode модулей и закрывается сразу после загрузки для драйверов (а нахер ему быть открытым). Но, ИМХО, одно из двух писал НЕ ты. Либо "драйвер не отображается на память", либо сам драйвер ; ) Учитесь как надо кодить http://img216.imageshack.us/img216/2995/dibzb7.jpg всё хотел кому-нибудь показать чтоб оценили гыгыг |
Цитата:
Цитата:
|
2 _Great_ спасибо за разъяснение. Переписал все через CTL_CODE.
Но всеже также осталась проблема с доступом к драйверу. GetLastError дает код ошибки - 317 |
Хм.. у меня описания к нему вобще нет.
Давай полный сорс драйвера в студию + кусок сорса программы управления, которая пытается открыть девайс, созданный драйвером Кстати, когда открываешь девайс, надо задавать флаги общего доступа FILE_SHARE_READ|FILE_SHARE_WRITE, а у тебя там ноль. Иначе будут проблемы. С этой вряд ли связано, но на будущее учти |
Зачем открывать с GENERIC_ALL ? У нее GENERIC_EXECUTE вообще-то ещё стоит. GENERIC_READ|GENERIC_WRITE используй
Кстати, зачем тебе вообще все это, ты же пишешь обычный пинч етц, скрывающий процесс по присланному PID (наверное через хук sdt). Почему бы просто не рассматривать IRP_MJ_CONTROL и не делать в юзермоде DeviceIoControl() ? |
Суть драйвера такова: Он должен перехватывать запуск процессов и заносить в лог.
также она должен защищать програму от выгрузки, а именно через перехват функции NtOpenProcess Сначало я начал делать всё без драйвера. т.е. через инжект своей DLL'ки которая перехватывала запуск программы. Но не на всех компах работало стабильно. То фаер матерился, то авир. Бывало аткое, что пашет отлично, но на некоторых прогах - вылетает. Вот для теста драйвера програма: Код:
unit Unit1;Код:
#include <ntddk.h> |
Софт айс + брек на DriverDispatcher
|
Цитата:
Цитата:
Цитата:
Цитата:
Цитата:
RTFM, она будет в irpStack->Parameters.DeviceIoControl.OutputBufferLength А в irpStack->Parameters.Read.Length будет длина буффера при IRP_MJ_READ В DriverEntry множество ошибок, связанных с обработкой статусов от IoCreateDevice/IoCreateSymbolicLink Цитата:
|
rc = PsSetCreateProcessNotifyRoutine(*CreateProcessNoti fyRoutine, FALSE); - это как раз и есть фишка с помощью которой можно отлавливать запуск и заврешение программы. Компилится запросто. Пример был взят с rootkits.ru а именно: http://rootkits.ru/viewtopic.php?id=32
На счет процеов - я уверен что драйвер не будет истользовать на многопроцессорных системах. О точно. Яже сначало сделал через READ. поэтому и оставалось irpStack->Parameters.Read.Length нашел в чем была проблема. почему я не мог связаться с драйвером. по умолчанию при открытии нужно было возвращаться статус: STATUS_SUCCESS; о чем я забыл. |
У тебя вообще в драйвере КУЧА ошибок. У тебя будет множество глюков вплоть до бсодов, с ними связанных
|
2 _Great_ чуть исправил драйвер. Вроде ошибок не вижу, т.к. делал всё на базе примеров которые взял с wasm.
Шас тестировал его - работате отлично глюков вообще не заметил. |
Неточности связанные с обработкой ошибок:
Код:
else |
я вообще это делал для отладки. в последствии всё исправил.
|
| Время: 19:56 |