Оптимальный буфер в ring 0.

Тема в разделе "WASM.WIN32", создана пользователем Nekto0n, 14 май 2007.

  1. Nekto0n

    Nekto0n New Member

    Публикаций:
    0
    Регистрация:
    22 фев 2007
    Сообщения:
    13
    Дано:
    1. Модуль хукает WinApi функции NtCreateFile и NtCreateKey.
    2. User-space приложение хочет получатьот него инфу о том, кто и что хукнул. Хочется делать это через ReadFile.
    Надо:
    Организовать буфер, в который будет кидаться инфа при каждом факте хука. Т.е. нужно организовать подсовывание ReadFile каждый раз новую строку.
    Приветствуются наброски кода. =)
    Нужна ещё информация - буду рад дополнить.
     
  2. gilg

    gilg New Member

    Публикаций:
    0
    Регистрация:
    19 май 2005
    Сообщения:
    527
    Ну и кто мешает организовать буфер в виде структуры, в заголовке которой будет храниться количество записей, смещение текущей записи и вся остальная нужная инфа?
     
  3. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    Чтобы обмениваться информацией между драйвером и юзер-приложением, существуют SharedSections.
    Кроме того, есть DeviceIoControl, с которым можно послать в драйвер буфер для заполнения информацией.
    Использовать для обмена информацией ReadFile - несколько странно.
     
  4. Nekto0n

    Nekto0n New Member

    Публикаций:
    0
    Регистрация:
    22 фев 2007
    Сообщения:
    13
    Спасибо, идейка родилась =)
    Ну почему, довольно красиво. Приложение открывает устройство CreateFile'ом и читает из него инфу ReadFile'ом. Для этого драйвер регает просто обработчик IRP_MJ_READ. Такая связка довольно логична и... ну надо так для курсача =)))
     
  5. Nekto0n

    Nekto0n New Member

    Публикаций:
    0
    Регистрация:
    22 фев 2007
    Сообщения:
    13
    Ещё вопросик в том же ключе: как обеспечить реентерабильность моих функций? Т.е. зашёл я в мою NewCreateFile. Получил инфу, записал её в буфер, а указатель передвинуть не успел, т.к. в это время этот поток вытеснился и другой вызывает CreateFile и переписывает мне информацию, ++ счётчик, а затем весь в белом возвращается мой предыдущий поток и снова ++ счётчик и с чувством выполненного долга возвращает управление настоящей CreateFile.
    Какие существуют способы избежания этого?
     
  6. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    InterlocedAdd/InterlockedSub/InterlockedExchange, либо мьютексы.
     
  7. Nekto0n

    Nekto0n New Member

    Публикаций:
    0
    Регистрация:
    22 фев 2007
    Сообщения:
    13
    А KeEnterCriticalRegion сойдёт? Вроде как должно помочь, т.е. поток не будет вытеснен пока не выйдет.
     
  8. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    Дольше чем интерлокед функции и чем фастмьютексы.
     
  9. Nekto0n

    Nekto0n New Member

    Публикаций:
    0
    Регистрация:
    22 фев 2007
    Сообщения:
    13
    Вылетает в синий экран с ACCESS_VIOLATION. Глобально объявлен указатель на мою структуру.
    Код (Text):
    1. struct _log
    2. {
    3.      ULONG Position;
    4.      CHAR Data[4096];
    5. } LOG_BUF, *PLOG_BUF;
    6.  
    7. PLOG_BUF СurrentBuff;
    В DriverEntry вызываю:
    Код (Text):
    1. CurrentBuff = ExAllocatePool(NonPagedPool, sizeof(LOG_BUF));
    Затем в функции, которая выполняется вместо CreateFile, вызываю свою лог-функцию. Которая заполняет структуру.
    Код (Text):
    1. KeAquireFastMutex(&LogMutex);
    2. memcpy(CurrentBuff->Data,ProcessNameOffset,15);
    3. KeReleaseFastMutex(&LogMutex);
    Происходит вылет.
     
  10. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    ProcessNameOffset откуда берется?
     
  11. Nekto0n

    Nekto0n New Member

    Публикаций:
    0
    Регистрация:
    22 фев 2007
    Сообщения:
    13
    Это заполняется процедурой из Filemon Руссиновича. Код сейчас гляну...
    Код (Text):
    1. ULONG
    2. FilemonGetProcessNameOffset(
    3.     VOID
    4.     )
    5. {
    6.     PEPROCESS       curproc;
    7.     int             i;
    8.  
    9.     curproc = PsGetCurrentProcess();
    10.  
    11.     //
    12.     // Scan for 12KB, hoping the KPEB never grows that big!
    13.     //
    14.     for( i = 0; i < 3*PAGE_SIZE; i++ ) {
    15.      
    16.         if( !strncmp( SYSNAME, (PCHAR) curproc + i, strlen(SYSNAME) )) {
    17.  
    18.             return i;
    19.         }
    20.     }
    21.  
    22.     //
    23.     // Name not found - oh, well
    24.     //
    25.     return 0;
    26. }
    Вызов её происходит в DriverEntry.
    Код (Text):
    1. ProcessNameOffset = FilemonGetProcessNameOffset();
     
  12. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Ну дык ProcessNameOffset не является адресом. А ты оттуда чето скопировать хочешь.
    К нему же надо адрес EPROCESS добавить, а ProcNameOffset всего лишь смещение имени процесса относительно начала структуры
     
  13. Nekto0n

    Nekto0n New Member

    Публикаций:
    0
    Регистрация:
    22 фев 2007
    Сообщения:
    13
    Ух ё! Спасиба, туплю =(
     
  14. Guest

    Guest Guest

    Публикаций:
    0
    У меня это так выглядит:

    Код (Text):
    1. VOID GetProcessNameOffset()
    2. {
    3.     PEPROCESS curproc = PsGetCurrentProcess();
    4.     for(int i = 0; i < 0x3000; i++)
    5.     {
    6.         if(!strncmp("System", (PCHAR)curproc + i, strlen_s("System")))  
    7.             gProcessNameOffset = i;
    8.     }
    9. }
    10.  
    11. bool GetCurrentProcessName(char *theName)
    12. {
    13.     PEPROCESS curproc     = PsGetCurrentProcess();
    14.    
    15.     if(gProcessNameOffset == 0)
    16.         GetProcessNameOffset();
    17.     if(gProcessNameOffset == 0)
    18.         return false;
    19.  
    20.     strncpy(theName, (char*)((DWORD)curproc + gProcessNameOffset), NT_PROCNAMELEN);
    21.     theName[NT_PROCNAMELEN] = 0;
    22.     return true;
    23. }
     
  15. Nekto0n

    Nekto0n New Member

    Публикаций:
    0
    Регистрация:
    22 фев 2007
    Сообщения:
    13
    Угу. Это из Filemonitor'а двух мозговитых и всем известных дядек =)
     
  16. Guest

    Guest Guest

    Публикаций:
    0
    P.S. По поводу ReadFile - так делает некоторый вполне легальный софт, например Sony Ericsson Update Service - сначала получает размер данных через DeviceIoControl, потом вызывает ReadFile/WriteFile. ReadFile/WriteFile в основном задействован для получения/отправки данных большого объема частями в цикле (куски прошивки, зона GDFS), потом идет отчет о загруженных/принятых данных. Все это работает стабильно и проблем пока не встречал.
     
  17. Nekto0n

    Nekto0n New Member

    Публикаций:
    0
    Регистрация:
    22 фев 2007
    Сообщения:
    13
    Проблема с определением имени образа.
    Смещение находится без проблем, при копировании в буфер для последующей записи и открытии в последствии блокнотом - имя образа не разобрать. Что-то непонятное вместо этого. Хотя вроде в EPROCESS
    BYTE ImageFileName[16];
    Код (Text):
    1. strncpy(LogFileBuffer+BuffSize,(char *)((ULONG)PsGetCurrentProcess() + 0x1FC),16);
    2. или
    3. strncpy(LogFileBuffer+BuffSize,(char *)((ULONG)PsGetCurrentProcess() + ProcessNameOffset),16);
    Подскажите, в какую сторону копать.