SSTD restore[unhook]

Тема в разделе "WASM.NT.KERNEL", создана пользователем 008888, 9 янв 2010.

  1. 008888

    008888 New Member

    Публикаций:
    0
    Регистрация:
    19 авг 2008
    Сообщения:
    17
    Здравствуйте! Вообщем задача следующая - востановить таблицу sstd после хуков неизвестным приложением. Покопался - нашел прилично исходников, в освновном половину делают в юзер моде, потом callgate в ринг0 и уже анхучят. Проблема в том, что мне необходимо реализовать драйвером. Есть конечно реализация драйвера by Cr4sh, но я нашел другой код made in China кстате(By XiCao) :) Вообщем главное отличие в том, что у Cr4sh делается так: ZwOpenFile -> ZwReadFile -> (ProcessImports && ProcessRelocs) у китайцев же как мне кажется попроще(тобишь они указывают откуда читать, а не рыщут по всей памяти) В другом коде ZwOpenFile -> ZwSetInformationFile -> ZwReadFile.
    Вопрос в том, что лучше использовать? Больше негде не встречал ZwSetInformationFile, да и с его использованием пока косяки. Чтобы не быть голословным приведу код (определения структур и прочую мишуру я уберу) И с вашего разрешения задам пару вопросов в самом коде.
    Код (Text):
    1. #define DEVICE L"\\Device\\ssdt"
    2. #define DOSDEVICE L"\\DosDevices\\ssdt"
    3.  
    4. /// GLOBALS
    5. __declspec(dllimport) PSERVICE_DESCRIPTOR_ENTRY KeServiceDescriptorTable;
    6. PDEVICE_OBJECT DriverDeviceObject = NULL;
    7. //ф-ция реализации которых не важны.
    8. NTSTATUS STDCALL msgManager(PDEVICE_OBJECT DeviceObject, PIRP Irp);
    9. VOID STDCALL DriverUnload(IN PDRIVER_OBJECT DriverObject);
    10. NTSTATUS STDCALL DriverDispatch(IN PDEVICE_OBJECT DeviceObject,  IN PIRP Irp);
    11.  
    12.  
    13. ULONG GetKernelBaseAddress(char* lpszModule)
    14. {
    15.     NTSTATUS nResult;
    16.     ULONG ulNeededSize, uKernelAddr;
    17.     PSYSTEM_MODULE_INFORMATION pModuleList;
    18.  
    19.     uKernelAddr = 0;
    20.     ZwQuerySystemInformation(11, &ulNeededSize, 0, &ulNeededSize);
    21.     pModuleList = ExAllocatePool(NonPagedPool, ulNeededSize);
    22.     nResult = ZwQuerySystemInformation(11, pModuleList, ulNeededSize, NULL);
    23.  
    24.     if (NT_SUCCESS(nResult))
    25.     {
    26.         //ntoskrnl is always first there
    27.         uKernelAddr =(ULONG) pModuleList->Module[0].Base;
    28.         strcpy(lpszModule,"\\SystemRoot\\System32\\");
    29.         strcat(lpszModule,pModuleList->Module[0].PathLength+pModuleList->Module[0].ImageName);
    30.     }
    31.  
    32.     ExFreePool(pModuleList);
    33.  
    34.     return uKernelAddr;
    35. }
    36. /*
    37.  * Эта ф-ция почему-то всегда возвращает 0, на этом и завершается работа драйвера,
    38.  * Правда ошибок в самой ф-ции я не вижу - значит неправильные входные параметры?!
    39.  */
    40. ULONG RVAToRaw(PVOID lpBase,ULONG VirtualAddress)
    41. {
    42.     IMAGE_DOS_HEADER *pDosHeader;
    43.     IMAGE_NT_HEADERS *pNtHeader;
    44.     IMAGE_SECTION_HEADER *pSectionHeader;
    45.     ULONG NumOfSections,uLoop;
    46.     pDosHeader=(IMAGE_DOS_HEADER*)lpBase;
    47.     if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE)
    48.         return 0;
    49.     pNtHeader=(IMAGE_NT_HEADERS*)((unsigned char*)lpBase+pDosHeader->e_lfanew);
    50.     NumOfSections=pNtHeader->FileHeader.NumberOfSections;
    51.     pSectionHeader = (IMAGE_SECTION_HEADER*)((ULONG)pNtHeader + sizeof(ULONG) + sizeof(IMAGE_FILE_HEADER) + pNtHeader->FileHeader.SizeOfOptionalHeader);
    52.     VirtualAddress -= (ULONG)lpBase;
    53.     for (uLoop=0; uLoop<NumOfSections; uLoop++)
    54.     {
    55.         pSectionHeader = (IMAGE_SECTION_HEADER*)((ULONG)pSectionHeader + sizeof(IMAGE_SECTION_HEADER) * uLoop);
    56.         if(VirtualAddress>pSectionHeader->VirtualAddress&&VirtualAddress<pSectionHeader->VirtualAddress+pSectionHeader->SizeOfRawData)
    57.         {
    58.             ULONG Offset = VirtualAddress-pSectionHeader->VirtualAddress + pSectionHeader->PointerToRawData;
    59.             return Offset;
    60.         }
    61.     }
    62.     return 0;
    63. }
    64.  
    65. //StartService
    66. NTSTATUS STDCALL DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
    67. {
    68.  
    69.     DbgPrint("DriverEntry() !\n");
    70.  
    71.     UNICODE_STRING DeviceName;
    72.     UNICODE_STRING DosDeviceName;
    73.     NTSTATUS status;
    74.  
    75.     RtlInitUnicodeString(&DeviceName, DEVICE);
    76.     RtlInitUnicodeString(&DosDeviceName, DOSDEVICE);
    77.  
    78.     status = IoCreateDevice(
    79.                  DriverObject,      
    80.                  0,                  
    81.                  &DeviceName,  
    82.                  FILE_DEVICE_UNKNOWN,
    83.                  0,                  
    84.                  FALSE,            
    85.                  &DriverDeviceObject);
    86.  
    87.     if ( !NT_SUCCESS(status) )
    88.         return STATUS_NO_SUCH_DEVICE;
    89.     status = IoCreateSymbolicLink(&DosDeviceName,&DeviceName);
    90.     if( !NT_SUCCESS(status) )
    91.     {
    92.         IoDeleteDevice( DriverDeviceObject );
    93.         DbgPrint("Failed to create symbolic link\n");
    94.         return STATUS_NO_SUCH_DEVICE;
    95.     }
    96.  
    97.     DriverObject->MajorFunction[IRP_MJ_CREATE] = DriverDispatch;
    98.     DriverObject->MajorFunction[IRP_MJ_CLOSE]  = DriverDispatch;
    99.     DriverObject->MajorFunction[IRP_MJ_READ]   = DriverDispatch;
    100.     DriverObject->MajorFunction[IRP_MJ_WRITE]  = DriverDispatch;
    101.     DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = msgManager;
    102.     DriverObject->DriverUnload = DriverUnload;
    103.  
    104.  
    105.  
    106.     ULONG uKernelMoule,uImageBase,uSSDTCount,uSSDTBase,uSSDTRaw,uLoop,uOldAddress,uNewAddress;
    107.     PULONG lpArraySSDT;
    108.     char szKernelPath[256];
    109.     ANSI_STRING aFileName;
    110.     UNICODE_STRING uFileName;
    111.     OBJECT_ATTRIBUTES ObjAttr;
    112.     IO_STATUS_BLOCK ioStatus;
    113.     FILE_POSITION_INFORMATION FilePos;
    114.     HANDLE hFile;
    115.     // get system modules
    116.     memset(szKernelPath,0,256);
    117.     uKernelMoule = GetKernelBaseAddress(szKernelPath);
    118.     uImageBase   = ((IMAGE_NT_HEADERS*)(uKernelMoule + ((IMAGE_DOS_HEADER*)uKernelMoule)->e_lfanew))->OptionalHeader.ImageBase;
    119.     DbgPrint("Kernel ImageBase: 0x%.8X", uImageBase);
    120.     DbgPrint("Kernel Base: 0x%.8X", uKernelMoule);
    121.     DbgPrint("Kernel Module Path: %s", szKernelPath);
    122. //
    123.     uSSDTCount = KeServiceDescriptorTable->NumberOfServices;
    124.     uSSDTBase = (ULONG)KeServiceDescriptorTable->ServiceTableBase;
    125.     DbgPrint("SSDT BaseAddress: 0x%8X, SSDT Count: 0x%X", uSSDTBase, uSSDTCount);
    126.     lpArraySSDT = ExAllocatePool(PagedPool, uSSDTCount * sizeof(ULONG));
    127.     if (lpArraySSDT == NULL) return status;
    128. //SSDT
    129.     uSSDTRaw = RVAToRaw(&uKernelMoule, uSSDTBase);
    130.     DbgPrint("SSDT RAW: 0x%.8X", uSSDTRaw);
    131.     if (uSSDTRaw == 0)
    132.     {  
    133.         // ВОТ СЮДА попадаем всегда =(
    134.         DbgPrint("SSDT RAW Error");
    135.         ExFreePool(lpArraySSDT);
    136.         return status;
    137.     }
    138.     RtlInitAnsiString(&aFileName,szKernelPath);
    139.     status = RtlAnsiStringToUnicodeString(&uFileName, &aFileName, TRUE);
    140.     if(!NT_SUCCESS(status))
    141.     {
    142.         DbgPrint("RtlAnsiStringToUnicodeString Error");
    143.         ExFreePool(lpArraySSDT);
    144.         return status;
    145.     }
    146.  
    147.     InitializeObjectAttributes(&ObjAttr, &uFileName, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL);
    148.     status = ZwOpenFile(&hFile, FILE_READ_DATA, &ObjAttr, &ioStatus, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_SYNCHRONOUS_IO_NONALERT);
    149.     if (NT_SUCCESS(status) && hFile)
    150.     {
    151.         FilePos.CurrentByteOffset.LowPart = uSSDTRaw;//1000;//uSSDTRaw;
    152.         FilePos.CurrentByteOffset.HighPart = 0;
    153. // Тут устанавливаем откуда будем читать
    154.         status = ZwSetInformationFile(hFile, &ioStatus, &FilePos, sizeof(FILE_POSITION_INFORMATION), FilePositionInformation);
    155.         if (NT_SUCCESS(status))
    156.         {
    157.             status = ZwReadFile(hFile, NULL, NULL, NULL, &ioStatus, lpArraySSDT, uSSDTCount * sizeof(ULONG), NULL, NULL);
    158.             if (NT_SUCCESS(status))
    159.             {
    160.                 for (uLoop=0; uLoop<uSSDTCount; uLoop++)
    161.                 {
    162.                     uOldAddress = *(lpArraySSDT + uLoop) - uImageBase + uKernelMoule;
    163.                     uNewAddress = *((PULONG)uSSDTBase + uLoop);
    164.                     if (uOldAddress != uNewAddress)
    165.                     {
    166.                         DbgPrint("SSDT No.%X, Old: 0x%.8X, New: 0x%.8X", uLoop, uOldAddress, uNewAddress);
    167.                         /// запрещаем прерывания KeRaiseIrql() аналог __asm cli
    168.                         KIRQL OldIrql;
    169.                         KeRaiseIrql(HIGH_LEVEL, &OldIrql);
    170. /*
    171.  * Данный асм код надо бы перевести в синтаксис AT&T,
    172.  * Вот заодно сразу и спрошу, возможно ли сбросить wp-bit
    173.  * на си\си++, если да, то как?
    174.  */
    175. //                        asm volatile(
    176. //                            "cli"
    177. //                            "mov eax,cr0"
    178. //                            "and eax,~0x10000" // сбросить WP bit
    179. //                            "mov cr0,eax"
    180. //                        );
    181.                         // анхучим...
    182.                         *((PULONG)uSSDTBase + uLoop) = uOldAddress;
    183.                          //fast_InterlockedExchange(*(uSSDTBase + uLoop), uOldAddress);
    184.                          // ^^ эта надпись автора кода, я так понял относится к строчке выше? тогда разве не так:
    185.                          // InterlockedExchange(&uNewAddress, uOldAddress);
    186. //
    187. //                        asm volatile(
    188. //                            "mov eax,cr0"
    189. //                            "or   eax,0x10000"
    190. //                            "mov cr0,eax"
    191. //                            "sti"
    192. //                        );
    193.                         /// Возвращаем все как было.(разрешаем прерывания) аналог __asm sti
    194.                         KeLowerIrql(OldIrql);
    195.                     }
    196.                 }
    197.                 DbgPrint("SSDT TheEnd...");
    198.  
    199.             }
    200.             else
    201.                 DbgPrint("Read File Error!");
    202.         }
    203. //   else
    204. //    DbgPrint("Set File Pos Error!");
    205.         if(hFile)
    206.             ZwClose(hFile);
    207.     }
    208.     else
    209.         DbgPrint("Open File Error!");
    210.  
    211.     RtlFreeUnicodeString(&uFileName);
    212.  
    213.     ExFreePool(lpArraySSDT);
    214.  
    215.     return STATUS_SUCCESS;
    216. }
    Буду благодарен за Вашу помощь.
     
  2. ant_man

    ant_man New Member

    Публикаций:
    0
    Регистрация:
    16 дек 2004
    Сообщения:
    23
    лучше, наверно так
    RVAToRaw(/* & */ (PVOID)uKernelMoule, uSSDTBase)
     
  3. 008888

    008888 New Member

    Публикаций:
    0
    Регистрация:
    19 авг 2008
    Сообщения:
    17
    Пробовал - не помогло... Китайцы в обсуждении даже переопределили(вроде как) ULONG RVAToRaw(DWORD lpBase,ULONG VirtualAddress)
     
  4. 008888

    008888 New Member

    Публикаций:
    0
    Регистрация:
    19 авг 2008
    Сообщения:
    17
    Извиняюсь, ввел в заблуждение в оригинале используется так "RVAToRaw(uKernelMoule, uSSDTBase)"
    Вот что выдает DbgPring:
    OS: NT 5.1 (2600) (winxp sp3 вообщем)
     
  5. ant_man

    ant_man New Member

    Публикаций:
    0
    Регистрация:
    16 дек 2004
    Сообщения:
    23
    что значит - не помогло? не скомпиллировалось?
     
  6. ant_man

    ant_man New Member

    Публикаций:
    0
    Регистрация:
    16 дек 2004
    Сообщения:
    23
    pSectionHeader = (IMAGE_SECTION_HEADER*)((ULONG)pNtHeader + sizeof(ULONG) + sizeof(IMAGE_FILE_HEADER) + pNtHeader->FileHeader.SizeOfOptionalHeader);

    лучше заменить на

    pSectionHeader = IMAGE_FIRST_SECTION(pNtHeader)

    а то как-то подозрительно выглядит
     
  7. 008888

    008888 New Member

    Публикаций:
    0
    Регистрация:
    19 авг 2008
    Сообщения:
    17
    Просто результат тот же, как и вывод дебага.
    Код (Text):
    1. typedef struct _IMAGE_SECTION_HEADER {
    2.     BYTE Name[IMAGE_SIZEOF_SHORT_NAME];
    3.     union {
    4.         DWORD PhysicalAddress;
    5.         DWORD VirtualSize;
    6.     } Misc;
    7.     DWORD VirtualAddress;
    8.     DWORD SizeOfRawData;
    9.     DWORD PointerToRawData;
    10.     DWORD PointerToRelocations;
    11.     DWORD PointerToLinenumbers;
    12.     WORD NumberOfRelocations;
    13.     WORD NumberOfLinenumbers;
    14.     DWORD Characteristics;
    15. } IMAGE_SECTION_HEADER,*PIMAGE_SECTION_HEADER;
    Код (Text):
    1. typedef struct _IMAGE_NT_HEADERS {
    2.     DWORD Signature;
    3.     IMAGE_FILE_HEADER FileHeader;
    4.     IMAGE_OPTIONAL_HEADER OptionalHeader;
    5. } IMAGE_NT_HEADERS32,*PIMAGE_NT_HEADERS32;
    Что то я смысла в "pSectionHeader = IMAGE_FIRST_SECTION(pNtHeader)" не вижу. Но попробовал - тот же результат. Ф-ция возвращает 0;
     
  8. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    wrk.
    Код (Text):
    1. // IMAGE_FIRST_SECTION doesn't need 32/64 versions since the file header is the same either way.
    2.  
    3. #define IMAGE_FIRST_SECTION( ntheader ) ((PIMAGE_SECTION_HEADER)        \
    4.     ((ULONG_PTR)ntheader +                                              \
    5.      FIELD_OFFSET( IMAGE_NT_HEADERS, OptionalHeader ) +                 \
    6.      ((PIMAGE_NT_HEADERS)(ntheader))->FileHeader.SizeOfOptionalHeader   \
    7.     ))
    8.  
    9. PIMAGE_SECTION_HEADER
    10. RtlSectionTableFromVirtualAddress (
    11.     IN PIMAGE_NT_HEADERS NtHeaders,
    12.     IN PVOID Base,
    13.     IN ULONG Address
    14.     )
    15.  
    16. /*++
    17.  
    18. Routine Description:
    19.  
    20.     This function locates a VirtualAddress within the image header
    21.     of a file that is mapped as a file and returns a pointer to the
    22.     section table entry for that virtual address
    23.  
    24. Arguments:
    25.  
    26.     NtHeaders - Supplies the pointer to the image or data file.
    27.  
    28.     Base - Supplies the base of the image or data file.
    29.  
    30.     Address - Supplies the virtual address to locate.
    31.  
    32. Return Value:
    33.  
    34.     NULL - The file does not contain data for the specified directory entry.
    35.  
    36.     NON-NULL - Returns the pointer of the section entry containing the data.
    37.  
    38. --*/
    39.  
    40. {
    41.     ULONG i;
    42.     PIMAGE_SECTION_HEADER NtSection;
    43.  
    44.     NtSection = IMAGE_FIRST_SECTION( NtHeaders );
    45.     for (i=0; i<NtHeaders->FileHeader.NumberOfSections; i++) {
    46.         if ((ULONG)Address >= NtSection->VirtualAddress &&
    47.             (ULONG)Address < NtSection->VirtualAddress + NtSection->SizeOfRawData
    48.            ) {
    49.             return NtSection;
    50.             }
    51.         ++NtSection;
    52.         }
    53.  
    54.     return NULL;
    55. }
    56.  
    57. PVOID
    58. RtlAddressInSectionTable (
    59.     IN PIMAGE_NT_HEADERS NtHeaders,
    60.     IN PVOID Base,
    61.     IN ULONG Address
    62.     )
    63.  
    64. /*++
    65.  
    66. Routine Description:
    67.  
    68.     This function locates a VirtualAddress within the image header
    69.     of a file that is mapped as a file and returns the seek address
    70.     of the data the Directory describes.
    71.  
    72. Arguments:
    73.  
    74.     NtHeaders - Supplies the pointer to the image or data file.
    75.  
    76.     Base - Supplies the base of the image or data file.
    77.  
    78.     Address - Supplies the virtual address to locate.
    79.  
    80. Return Value:
    81.  
    82.     NULL - The file does not contain data for the specified directory entry.
    83.  
    84.     NON-NULL - Returns the address of the raw data the directory describes.
    85.  
    86. --*/
    87.  
    88. {
    89.     PIMAGE_SECTION_HEADER NtSection;
    90.  
    91.     NtSection = RtlSectionTableFromVirtualAddress( NtHeaders,
    92.                                                    Base,
    93.                                                    Address
    94.                                                  );
    95.     if (NtSection != NULL) {
    96.         return( ((PCHAR)Base + ((ULONG_PTR)Address - NtSection->VirtualAddress) + NtSection->PointerToRawData) );
    97.         }
    98.     else {
    99.         return( NULL );
    100.         }
    101. }
     
  9. ant_man

    ant_man New Member

    Публикаций:
    0
    Регистрация:
    16 дек 2004
    Сообщения:
    23
    008888

    Да, показалось. Гадать можно долго, потрассировать быстрее. Может там количество секций в памяти тоже пропатчено...
     
  10. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    Код (Text):
    1.         pSectionHeader = (IMAGE_SECTION_HEADER*)((ULONG)pSectionHeader + sizeof(IMAGE_SECTION_HEADER) * uLoop);
    за такое банить надо %)
    Правильный вариант сам прищумаешь?
     
  11. 008888

    008888 New Member

    Публикаций:
    0
    Регистрация:
    19 авг 2008
    Сообщения:
    17
    2 n0name -угу, протупил, дефайна не заметил...
    2 Clerk
    Код (Text):
    1.     IMAGE_DOS_HEADER *pDosHeader;
    2.     IMAGE_NT_HEADERS *pNtHeader;
    3.     ULONG NumOfSections,uLoop;
    4.     pDosHeader=(IMAGE_DOS_HEADER*)lpBase;
    5.     if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE)
    6.         return 0;
    7.  
    8.     pNtHeader=(IMAGE_NT_HEADERS*)((unsigned char*)lpBase+pDosHeader->e_lfanew);
    9.     if(!pNtHeader) DbgPrint("Smth WRONG!\n");
    10.     pointer =  RtlAddressInSectionTable(pNtHeader,lpBase,VirtualAddress);
    11.     if(pointer == NULL)
    12.     {
    13.         DbgPrint("pointer = null\n");
    14.         return status;
    15.     }
    RtlAddressInSectionTable возвращает NULL...
     
  12. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    VirtualAddress надеюсь это RVA?
     
  13. 008888

    008888 New Member

    Публикаций:
    0
    Регистрация:
    19 авг 2008
    Сообщения:
    17
    VirtualAddress = KeServiceDescriptorTable->ServiceTableBase;
     
  14. n0name

    n0name New Member

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

    Wizard109 New Member

    Публикаций:
    0
    Регистрация:
    6 ноя 2006
    Сообщения:
    346
    Нда... наверное нужен подфорум с названием "я ничо не понял, помогите скомпилить чтоб заработало"...

    008888
    Посмотри здесь. Неплохое начало по твоей теме.
    http://www.wasm.ru/forum/viewtopic.php?id=19538&p=1
     
  16. 008888

    008888 New Member

    Публикаций:
    0
    Регистрация:
    19 авг 2008
    Сообщения:
    17
    Ого,быстро тут сообщения трут некоторые.
    Ну да ладно, вообщем вроде бы разобрался,один вопрос остался, почему в KeServiceDescriptorTable->TableSize такое огромное число?
     
  17. Twister

    Twister New Member

    Публикаций:
    0
    Регистрация:
    12 окт 2005
    Сообщения:
    720
    Адрес:
    Алматы
    Огромное это какое? :)
     
  18. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    008888
    Оскорбления и флейм стираются нещадно и незаметно для пользователей.
    А вот и не правда, у вас какое?
     
  19. 008888

    008888 New Member

    Публикаций:
    0
    Регистрация:
    19 авг 2008
    Сообщения:
    17
    SSDT Count: 0x805E0F55
    SSDT Count: 0x80587999
     
  20. AntiFreeze

    AntiFreeze Дмитрий

    Публикаций:
    0
    Регистрация:
    26 июн 2008
    Сообщения:
    65
    Ну это как бы похоже на адреса внутри ntoskrnl.exe. Что по ним? ;)