Дано: 1. Модуль хукает WinApi функции NtCreateFile и NtCreateKey. 2. User-space приложение хочет получатьот него инфу о том, кто и что хукнул. Хочется делать это через ReadFile. Надо: Организовать буфер, в который будет кидаться инфа при каждом факте хука. Т.е. нужно организовать подсовывание ReadFile каждый раз новую строку. Приветствуются наброски кода. =) Нужна ещё информация - буду рад дополнить.
Ну и кто мешает организовать буфер в виде структуры, в заголовке которой будет храниться количество записей, смещение текущей записи и вся остальная нужная инфа?
Чтобы обмениваться информацией между драйвером и юзер-приложением, существуют SharedSections. Кроме того, есть DeviceIoControl, с которым можно послать в драйвер буфер для заполнения информацией. Использовать для обмена информацией ReadFile - несколько странно.
Спасибо, идейка родилась =) Ну почему, довольно красиво. Приложение открывает устройство CreateFile'ом и читает из него инфу ReadFile'ом. Для этого драйвер регает просто обработчик IRP_MJ_READ. Такая связка довольно логична и... ну надо так для курсача =)))
Ещё вопросик в том же ключе: как обеспечить реентерабильность моих функций? Т.е. зашёл я в мою NewCreateFile. Получил инфу, записал её в буфер, а указатель передвинуть не успел, т.к. в это время этот поток вытеснился и другой вызывает CreateFile и переписывает мне информацию, ++ счётчик, а затем весь в белом возвращается мой предыдущий поток и снова ++ счётчик и с чувством выполненного долга возвращает управление настоящей CreateFile. Какие существуют способы избежания этого?
А KeEnterCriticalRegion сойдёт? Вроде как должно помочь, т.е. поток не будет вытеснен пока не выйдет.
Вылетает в синий экран с ACCESS_VIOLATION. Глобально объявлен указатель на мою структуру. Код (Text): struct _log { ULONG Position; CHAR Data[4096]; } LOG_BUF, *PLOG_BUF; PLOG_BUF СurrentBuff; В DriverEntry вызываю: Код (Text): CurrentBuff = ExAllocatePool(NonPagedPool, sizeof(LOG_BUF)); Затем в функции, которая выполняется вместо CreateFile, вызываю свою лог-функцию. Которая заполняет структуру. Код (Text): KeAquireFastMutex(&LogMutex); memcpy(CurrentBuff->Data,ProcessNameOffset,15); KeReleaseFastMutex(&LogMutex); Происходит вылет.
Это заполняется процедурой из Filemon Руссиновича. Код сейчас гляну... Код (Text): ULONG FilemonGetProcessNameOffset( VOID ) { PEPROCESS curproc; int i; curproc = PsGetCurrentProcess(); // // Scan for 12KB, hoping the KPEB never grows that big! // for( i = 0; i < 3*PAGE_SIZE; i++ ) { if( !strncmp( SYSNAME, (PCHAR) curproc + i, strlen(SYSNAME) )) { return i; } } // // Name not found - oh, well // return 0; } Вызов её происходит в DriverEntry. Код (Text): ProcessNameOffset = FilemonGetProcessNameOffset();
Ну дык ProcessNameOffset не является адресом. А ты оттуда чето скопировать хочешь. К нему же надо адрес EPROCESS добавить, а ProcNameOffset всего лишь смещение имени процесса относительно начала структуры
У меня это так выглядит: Код (Text): VOID GetProcessNameOffset() { PEPROCESS curproc = PsGetCurrentProcess(); for(int i = 0; i < 0x3000; i++) { if(!strncmp("System", (PCHAR)curproc + i, strlen_s("System"))) gProcessNameOffset = i; } } bool GetCurrentProcessName(char *theName) { PEPROCESS curproc = PsGetCurrentProcess(); if(gProcessNameOffset == 0) GetProcessNameOffset(); if(gProcessNameOffset == 0) return false; strncpy(theName, (char*)((DWORD)curproc + gProcessNameOffset), NT_PROCNAMELEN); theName[NT_PROCNAMELEN] = 0; return true; }
P.S. По поводу ReadFile - так делает некоторый вполне легальный софт, например Sony Ericsson Update Service - сначала получает размер данных через DeviceIoControl, потом вызывает ReadFile/WriteFile. ReadFile/WriteFile в основном задействован для получения/отправки данных большого объема частями в цикле (куски прошивки, зона GDFS), потом идет отчет о загруженных/принятых данных. Все это работает стабильно и проблем пока не встречал.
Проблема с определением имени образа. Смещение находится без проблем, при копировании в буфер для последующей записи и открытии в последствии блокнотом - имя образа не разобрать. Что-то непонятное вместо этого. Хотя вроде в EPROCESS BYTE ImageFileName[16]; Код (Text): strncpy(LogFileBuffer+BuffSize,(char *)((ULONG)PsGetCurrentProcess() + 0x1FC),16); или strncpy(LogFileBuffer+BuffSize,(char *)((ULONG)PsGetCurrentProcess() + ProcessNameOffset),16); Подскажите, в какую сторону копать.