Заменить ObjectAttributes из-под zwCreateFile

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

  1. LivelyRoger

    LivelyRoger New Member

    Публикаций:
    0
    Регистрация:
    25 авг 2006
    Сообщения:
    20
    Обалдеть. Чтобы заменить значение одной строкой переменной нужно столько всего...
    Неужели нет пути проще?...

    P.S. будем искать....
     
  2. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    можно сделать функцию типа MapAddresses() которая будет делать всё, что нужно (создание/проецирование MDL)
     
  3. LivelyRoger

    LivelyRoger New Member

    Публикаций:
    0
    Регистрация:
    25 авг 2006
    Сообщения:
    20
    Интересно, ведь если менять строку в оригинальном ObjectAttributes, то сам ObjectAttributes уже "промапин" в юзермод. Так?
    Тогда достаточно промапить только новую строку и присвоить ее указатель вместо оригинального.
    И строка, и ObjectAttributes выходит что в юземоде.
    Но получаем одно из двух:
    0xC000003A, т.е. STATUS_OBJECT_PATH_NOT_FOUND.
    или
    0xC0000034, т.е. STATUS_OBJECT_NAME_NOT_FOUND.

    Файл по указанному пути (в корне диска С, имя file.txt) существует.

    Вот так оформил весь перехватчик:

    Код (Text):
    1. NTSTATUS NewNtCreateFile (
    2.   OUT PHANDLE             FileHandle,
    3.   IN ACCESS_MASK          DesiredAccess,
    4.   IN POBJECT_ATTRIBUTES   ObjectAttributes,
    5.   OUT PIO_STATUS_BLOCK    IoStatusBlock,
    6.   IN PLARGE_INTEGER       AllocationSize OPTIONAL,
    7.   IN ULONG                FileAttributes,
    8.   IN ULONG                ShareAccess,
    9.   IN ULONG                CreateDisposition,
    10.   IN ULONG                CreateOptions,
    11.   IN PVOID                EaBuffer OPTIONAL,
    12.   IN ULONG                EaLength )
    13. {
    14.     PWCHAR pPath = NULL;
    15.     UNICODE_STRING uniFileName;
    16.     NTSTATUS status = STATUS_SUCCESS;
    17.     void* pMdl1 = NULL;
    18.     void* pMdl2 = NULL;
    19.     void* pMdl3 = NULL;
    20.     BOOLEAN locked1 = FALSE, locked2 = FALSE, locked3 = FALSE, Attr=FALSE;
    21.     OBJECT_ATTRIBUTES InterceptedObjectAttributes;
    22.     PMDL mdl = NULL;
    23.  
    24.     status=STATUS_SUCCESS;
    25.     if (ExGetPreviousMode() == UserMode) {
    26.         pMdl1 = IoAllocateMdl(ObjectAttributes, sizeof(ObjectAttributes), FALSE, FALSE, NULL);
    27.         if (pMdl1 == NULL)
    28.             goto done1;
    29.         __try {
    30.             MmProbeAndLockPages(pMdl1, KernelMode, IoModifyAccess);
    31.         } __except(EXCEPTION_EXECUTE_HANDLER) {
    32.             goto done1;
    33.         }
    34.         locked1 = TRUE;
    35.         pMdl2 = IoAllocateMdl(ObjectAttributes->ObjectName, sizeof(UNICODE_STRING), FALSE, FALSE, NULL);
    36.         if (pMdl2 == NULL)
    37.             goto done1;
    38.         __try {
    39.             MmProbeAndLockPages(pMdl2, KernelMode, IoModifyAccess);
    40.         } __except(EXCEPTION_EXECUTE_HANDLER) {
    41.             goto done1;
    42.         }
    43.         locked2 = TRUE;
    44.         pMdl3 = IoAllocateMdl(ObjectAttributes->ObjectName->Buffer, ObjectAttributes->ObjectName->Length, FALSE, FALSE, NULL);
    45.         if (pMdl3 == NULL)
    46.             goto done1;
    47.         __try {
    48.             MmProbeAndLockPages(pMdl3, KernelMode, IoModifyAccess);
    49.         } __except(EXCEPTION_EXECUTE_HANDLER) {
    50.             goto done1;
    51.         }
    52.         locked3 = TRUE;
    53.  
    54.         if (FileAttributes!=FILE_ATTRIBUTE_DIRECTORY) {
    55.             RtlInitUnicodeString(&uniFileName, ObjectAttributes->ObjectName->Buffer);
    56.             pPath=GetFullPath(uniFileName, ObjectAttributes->RootDirectory);
    57.             if (pPath!=NULL) {
    58.                 RtlInitUnicodeString(&uniFileName, pPath);
    59.                 if (IsHidden(&uniFileName)) {    // проверка имени запрошенного файла и блокируем его если что...
    60.                     PWSTR FileName = L"\\??\\C:\\File.txt";
    61.    
    62.                     PWSTR FileNameToMap = ExAllocatePoolWithTag( NonPagedPool, 0x1000, ' gaT' );
    63.                     memcpy( FileNameToMap, FileName, sizeof(FileName) );
    64.    
    65.                     mdl = IoAllocateMdl( FileNameToMap, 0x1000, FALSE, TRUE, NULL );
    66.                     MmBuildMdlForNonPagedPool( mdl );
    67.  
    68.                     __try
    69.                     {
    70.                         PVOID UserModePointer = MmMapLockedPagesSpecifyCache( mdl, UserMode, MmCached, NULL, FALSE, NormalPagePriority );
    71.  
    72.                         if( UserModePointer )
    73.                         {
    74.                             ObjectAttributes->ObjectName->Buffer=(PWSTR)UserModePointer;
    75.  
    76.                             status=TrueNtCreateFile(FileHandle,DesiredAccess,ObjectAttributes,IoStatusBlock,
    77.                                     AllocationSize,FileAttributes,ShareAccess,CreateDisposition,
    78.                                     CreateOptions,EaBuffer,EaLength);
    79.  
    80.                             DPRINT("%x ---- %d", status, FileHandle);
    81.                             Attr=TRUE;
    82.  
    83.                             MmUnmapLockedPages( UserModePointer, mdl );
    84.                         }
    85.                     }
    86.                     __except( EXCEPTION_EXECUTE_HANDLER)
    87.                     {
    88.                         DPRINT("Failed");
    89.                     }
    90.  
    91.                     IoFreeMdl( mdl );
    92.                     ExFreePool( FileNameToMap );
    93.                 }
    94.                 ExFreePool(pPath);
    95.             }
    96.         }
    97. done1:
    98.         if (locked1)
    99.             MmUnlockPages(pMdl1);
    100.         if (locked2)
    101.             MmUnlockPages(pMdl2);
    102.         if (locked3)
    103.             MmUnlockPages(pMdl3);
    104.         if (pMdl1 != NULL)
    105.             IoFreeMdl(pMdl1);
    106.         if (pMdl2 != NULL)
    107.             IoFreeMdl(pMdl2);
    108.         if (pMdl3 != NULL)
    109.             IoFreeMdl(pMdl3);
    110.     }
    111.     if (Attr) {
    112.         return status;
    113.     }
    114.     return TrueNtCreateFile(FileHandle,DesiredAccess,ObjectAttributes,IoStatusBlock,
    115.                                 AllocationSize,FileAttributes,ShareAccess,CreateDisposition,
    116.                                 CreateOptions,EaBuffer,EaLength);
    117. }
    Все вроде просто, а файл не находится....
     
  4. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Чувак, сори, я допустил тупую ошибку в коде проецирования =)

    Код (Text):
    1.                 if (IsHidden(&uniFileName)) {    // проверка имени запрошенного файла и блокируем его если что...
    2.                     PWSTR FileName = L"\\??\\C:\\File.txt";
    3.    
    4.                     PWSTR FileNameToMap = ExAllocatePoolWithTag( NonPagedPool, 0x1000, ' gaT' );
    5.                     memcpy( FileNameToMap, FileName, sizeof(FileName) );
    Конечно же, надо написать не sizeof(FileName), который всегда равен четырём (указатель PWSTR - 4 байта), а написать вот так:

    Код (Text):
    1. wchat_t FileName[] = L"\\??\\C:\\File.txt";
    Тогда sizeof(FileName) вернет реальный размер массива
     
  5. LivelyRoger

    LivelyRoger New Member

    Публикаций:
    0
    Регистрация:
    25 авг 2006
    Сообщения:
    20
    Ничего, бывает...
    Вот только теперь новая ошибка: STATUS_OBJECT_NAME_INVALID - 0xC0000033
     
  6. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    сделай DbgPrint на всяк с указателем FileNameToMap перед вызовом TrueNtCreateFile. (потому как UserModePointer - просто его проекция в ринг3)
     
  7. LivelyRoger

    LivelyRoger New Member

    Публикаций:
    0
    Регистрация:
    25 авг 2006
    Сообщения:
    20
    Все в порядке, содержит: \??\C:\File.txt
     
  8. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    попробуй тогда DosDevices вместо ?? чтоли... или попробуй убрать \??\ и просто оставить C:\File.txt
    я бы так поигрался по кр. мере )
     
  9. LivelyRoger

    LivelyRoger New Member

    Публикаций:
    0
    Регистрация:
    25 авг 2006
    Сообщения:
    20
    Я пробовал - результат тот же.
    А без префикса(C:\...) - STATUS_OBJECT_PATH_SYNTAX_BAD
     
  10. Nouzui

    Nouzui New Member

    Публикаций:
    0
    Регистрация:
    17 ноя 2006
    Сообщения:
    856
    ->RootDirectory не забыл обнулить?
     
  11. LivelyRoger

    LivelyRoger New Member

    Публикаций:
    0
    Регистрация:
    25 авг 2006
    Сообщения:
    20
    Он и есть 0
     
  12. Nouzui

    Nouzui New Member

    Публикаций:
    0
    Регистрация:
    17 ноя 2006
    Сообщения:
    856
    тогда попробуй вместо "\??\C:" \Device\HarddiskVolume<n>, где <n> - соответствующее число
     
  13. LivelyRoger

    LivelyRoger New Member

    Публикаций:
    0
    Регистрация:
    25 авг 2006
    Сообщения:
    20
    Бесполезно, пробовал
     
  14. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    Взять что ли самому написать :P
    Ты OBJ_CASE_INSENSITIVE добавил в ObjectAttributes?
     
  15. k3internal

    k3internal New Member

    Публикаций:
    0
    Регистрация:
    11 янв 2007
    Сообщения:
    607
    <Интересно, ведь если менять строку в оригинальном ObjectAttributes, то сам ObjectAttributes уже "промапин" в юзермод. Так?
    Тогда достаточно промапить только новую строку и присвоить ее указатель вместо оригинального.
    И строка, и ObjectAttributes выходит что в юземоде.
    Но получаем одно из двух:
    0xC000003A, т.е. STATUS_OBJECT_PATH_NOT_FOUND.
    или
    0xC0000034, т.е. STATUS_OBJECT_NAME_NOT_FOUND.
    >
    Хых. Ты не понял одного. Что Структура ObjectAttributes будет использованан и по выходу из кернелмод в NTDLL. Тебе нужно её заново проинициализировать. После сих действитй в юзермоде при входе в функцию в стеке изменить указатель на вновь созданную структуру. Тогда есть шансы, что оно может работать.
     
  16. LivelyRoger

    LivelyRoger New Member

    Публикаций:
    0
    Регистрация:
    25 авг 2006
    Сообщения:
    20
    Я ObjectAttributes не меняю (только имя файла и корневой каталог).
    Но попробывал уже все варианты регистра строки с именем файла

    Если бы.... хотелось бы увидеть как это делается НА САМОМ деле...
    Если надо могу дать свой проект, меньше делать придется
    Правда, не факт, т.к. там может быть море ошибок(о которых я пока не знаю)....
     
  17. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    Код (Text):
    1. NTSTATUS NtCreateFile_New(PHANDLE FileHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes,
    2.     PIO_STATUS_BLOCK IoStatusBlock, PLARGE_INTEGER AllocationSize, ULONG FileAttributes, ULONG ShareAccess,
    3.     ULONG CreateDisposition, ULONG CreateOptions, PVOID EaBuffer, ULONG EaLength){
    4.  
    5.     NTSTATUS ns;
    6.     OBJECT_ATTRIBUTES *oaNewName = NULL, *oaUserNewName = NULL;
    7.     UNICODE_STRING *usNewName = NULL, *usUserNewName = NULL;
    8.     PWSTR pwszUserNewName = NULL, pwszNewName = NULL;
    9.     PMDL pUnicodeStringMdl = NULL, pObjectAttributesMdl = NULL, pBufferMdl = NULL;
    10.  
    11.     if (!RtlCompareUnicodeString(ObjectAttributes->ObjectName, &usFile2Hide, TRUE)){        
    12.         pwszNewName = (PWSTR)ExAllocatePool(NonPagedPool, 0x1000);
    13.         usNewName = (UNICODE_STRING *)ExAllocatePool(NonPagedPool, 0x1000);
    14.         oaNewName = (OBJECT_ATTRIBUTES *)ExAllocatePool(NonPagedPool, 0x1000);
    15.         if ((!pwszNewName) || (!usNewName) || (!oaNewName))
    16.             goto exit;
    17.         RtlInitUnicodeString(usNewName, FILE_TO_REPLACE);
    18.         memcpy(pwszNewName, usNewName->Buffer, usNewName->Length * 2 + 2);
    19.         pwszUserNewName = MapInUserSpace(pwszNewName, &pBufferMdl, 0x1000);
    20.         if (!pwszUserNewName)
    21.             goto exit;        
    22.         usNewName->Buffer = pwszUserNewName;
    23.         usUserNewName = MapInUserSpace(usNewName, &pUnicodeStringMdl, 0x1000);
    24.         if (!usUserNewName)
    25.             goto exit;
    26.         InitializeObjectAttributes(oaNewName, usUserNewName, OBJ_CASE_INSENSITIVE, 0, NULL);
    27.         oaUserNewName = MapInUserSpace(oaNewName, &pObjectAttributesMdl, 0x1000);
    28.         if (!oaUserNewName)
    29.             goto exit;
    30.         DbgPrint("%0X %0X %0X", oaUserNewName, usUserNewName, pwszUserNewName);
    31.         ns = ((TNtCreateFile)(NtCreateFile_Old))(FileHandle, DesiredAccess, oaUserNewName, IoStatusBlock,
    32.             AllocationSize, FileAttributes, ShareAccess, CreateDisposition, CreateOptions, EaBuffer,
    33.             EaLength);
    34.     } else
    35.         ns = ((TNtCreateFile)(NtCreateFile_Old))(FileHandle, DesiredAccess, ObjectAttributes, IoStatusBlock,
    36.             AllocationSize, FileAttributes, ShareAccess, CreateDisposition, CreateOptions, EaBuffer,
    37.             EaLength);
    38. exit:
    39.     UnmapInUserSpace(pBufferMdl, pwszNewName, pwszUserNewName);
    40.     UnmapInUserSpace(pUnicodeStringMdl, usNewName, usUserNewName);
    41.     UnmapInUserSpace(pObjectAttributesMdl, oaNewName, oaUserNewName);
    42.     return ns;
    43. }
     
  18. LivelyRoger

    LivelyRoger New Member

    Публикаций:
    0
    Регистрация:
    25 авг 2006
    Сообщения:
    20
    Спасибо,
    но что такое:

    - MapInUserSpace
    - UnMapInUserSpace

    Я у себя в DDK такого не нашел и компилятор, естественно, не пропускает....
    Поиск в И-нете тоже не дал результатов
     
  19. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Судя по отсутствию префиксов, что-то самопальное от автора )
     
  20. LivelyRoger

    LivelyRoger New Member

    Публикаций:
    0
    Регистрация:
    25 авг 2006
    Сообщения:
    20
    Хотелось бы увидеть содержимое....