Востановление SDT в kernel mode

Тема в разделе "WASM.NT.KERNEL", создана пользователем DeeoniS, 9 фев 2007.

  1. DeeoniS

    DeeoniS New Member

    Публикаций:
    0
    Регистрация:
    6 авг 2004
    Сообщения:
    132
    Зравствуйте, собственно интересует как востановить SDT. Но только не в user mode, а на уровне ядра. Все что я нашел по данной тематике работает на уровне пользователя. Единственное упомянание про это на форуме здесь: http://www.wasm.ru/forum/viewtopic.php?pid=108168#p108168. Но застопорился на реализации LoadPeFile для ядра. Может у кого есть уже готовые решения?
     
  2. gilg

    gilg New Member

    Публикаций:
    0
    Регистрация:
    19 май 2005
    Сообщения:
    527
     
  3. DeeoniS

    DeeoniS New Member

    Публикаций:
    0
    Регистрация:
    6 авг 2004
    Сообщения:
    132
    искал, ничего похожего нет
     
  4. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    Вот мой сорц. Почти всё выдрано из статьи 90210 ;)

    Код (Text):
    1. #include <ntddk.h>
    2.  
    3. typedef NTSTATUS (NTAPI *NTPROC)();
    4. typedef NTPROC *PNTPROC;
    5.  
    6. typedef struct _SYSTEM_SERVICE_TABLE{
    7.     PNTPROC ServiceTable;
    8.     PULONG CounterTable;
    9.     ULONG ServiceLimit;
    10.     PUCHAR ArgumentTable;
    11. } SYSTEM_SERVICE_TABLE, *PSYSTEM_SERVICE_TABLE;
    12.  
    13. typedef struct _SERVICE_DESCRIPTOR_TABLE{
    14.     SYSTEM_SERVICE_TABLE NtoskrnlTable;
    15.     SYSTEM_SERVICE_TABLE Table2;
    16.     SYSTEM_SERVICE_TABLE Table3;
    17.     SYSTEM_SERVICE_TABLE Table4;
    18. } SERVICE_DESCRIPTOR_TABLE, *PSERVICE_DESCRIPTOR_TABLE;
    19.  
    20. typedef enum _SYSTEM_INFORMATION_CLASS {
    21.     SystemBasicInformation,
    22.     SystemProcessorInformation,
    23.     SystemPerformanceInformation,
    24.     SystemTimeOfDayInformation,
    25.     SystemNotImplemented1,
    26.     SystemProcessesAndThreadsInformation,
    27.     SystemCallCounts,
    28.     SystemConfigurationInformation,
    29.     SystemProcessorTimes,
    30.     SystemGlobalFlag,
    31.     SystemNotImplemented2,
    32.     SystemModuleInformation,
    33.     SystemLockInformation,
    34.     SystemNotImplemented3,
    35.     SystemNotImplemented4,
    36.     SystemNotImplemented5,
    37.     SystemHandleInformation,
    38.     SystemObjectInformation,
    39.     SystemPagefileInformation,
    40.     SystemInstructionEmulationCounts,
    41.     SystemInvalidInfoClass1,
    42.     SystemCacheInformation,
    43.     SystemPoolTagInformation,
    44.     SystemProcessorStatistics,
    45.     SystemDpcInformation,
    46.     SystemNotImplemented6,
    47.     SystemLoadImage,
    48.     SystemUnloadImage,
    49.     SystemTimeAdjustment,
    50.     SystemNotImplemented7,
    51.     SystemNotImplemented8,
    52.     SystemNotImplemented9,
    53.     SystemCrashDumpInformation,
    54.     SystemExceptionInformation,
    55.     SystemCrashDumpStateInformation,
    56.     SystemKernelDebuggerInformation,
    57.     SystemContextSwitchInformation,
    58.     SystemRegistryQuotaInformation,
    59.     SystemLoadAndCallImage,
    60.     SystemPrioritySeparation,
    61.     SystemNotImplemented10,
    62.     SystemNotImplemented11,
    63.     SystemInvalidInfoClass2,
    64.     SystemInvalidInfoClass3,
    65.     SystemTimeZoneInformation,
    66.     SystemLookasideInformation,
    67.     SystemSetTimeSlipEvent,
    68.     SystemCreateSession,
    69.     SystemDeleteSession,
    70.     SystemInvalidInfoClass4,
    71.     SystemRangeStartInformation,
    72.     SystemVerifierInformation,
    73.     SystemAddVerifier,
    74.     SystemSessionProcessesInformation
    75. } SYSTEM_INFORMATION_CLASS;
    76.  
    77. typedef struct _SYSTEM_MODULE{
    78.     ULONG   Reserved[2];
    79.     PVOID   Base;
    80.     ULONG   Size;
    81.     ULONG   Flags;
    82.     USHORT  Index;
    83.     USHORT  Unknown;
    84.     USHORT  LoadCount;
    85.     USHORT  ModuleNameOffset;
    86.     CHAR    ImageName[256];
    87. } SYSTEM_MODULE, *PSYSTEM_MODULE;
    88.  
    89. typedef struct _SYSTEM_MODULE_INFORMATION {
    90.     ULONG dwCount;
    91.     SYSTEM_MODULE Modules[1];
    92. } SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;
    93.  
    94.  
    95. #ifdef __cplusplus
    96. extern "C" {
    97. #endif
    98. extern PSERVICE_DESCRIPTOR_TABLE KeServiceDescriptorTable;
    99. extern
    100. NTSYSAPI
    101. NTSTATUS
    102. NTAPI
    103. ZwCreateSection(
    104.             OUT PHANDLE SectionHandle,
    105.             IN ACCESS_MASK DesiredAccess,
    106.             IN POBJECT_ATTRIBUTES ObjectAttributes,
    107.             IN PLARGE_INTEGER SectionSize OPTIONAL,
    108.             IN ULONG Protect,
    109.             IN ULONG Attributes,
    110.             IN HANDLE FileHandle
    111.             );
    112. extern
    113. NTSYSAPI
    114. NTSTATUS
    115. NTAPI
    116. ZwQuerySystemInformation (
    117.     IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
    118.     OUT PVOID                   SystemInformation,
    119.     IN ULONG                    Length,
    120.     OUT PULONG                  ReturnLength
    121. );
    122. #ifdef __cplusplus
    123. }
    124. #endif
    125.  
    126. #define RESTORE_SYSCALL 0x35
    127.  
    128. void DriverUnload(PDRIVER_OBJECT DriverObject){
    129. }
    130.  
    131. NTSTATUS DrvUnhookQST(ULONG dwSysCall, ULONG dwOriginal){
    132.     ULONG CR0Reg;
    133.  
    134.     _asm mov eax,CR0
    135.     _asm mov CR0Reg,eax
    136.     _asm and eax,0xFFFEFFFF
    137.     _asm mov cr0, eax
    138.     KeServiceDescriptorTable->NtoskrnlTable.ServiceTable[dwSysCall] = (NTPROC)dwOriginal;
    139.     _asm mov eax,CR0Reg
    140.     _asm mov cr0,eax
    141. }
    142.  
    143. HANDLE hKernelFile = 0, hKernelSection = 0;
    144. PVOID pKernel = NULL;
    145.  
    146. void UnMapKernel(){
    147.     if (pKernel)
    148.         ZwUnmapViewOfSection(pKernel, NtCurrentProcess());
    149.     if (hKernelSection)
    150.         ZwClose(hKernelSection);
    151.     if (hKernelFile)
    152.         ZwClose(hKernelFile);
    153. }
    154.  
    155. NTSTATUS MapKernel(){
    156.     UNICODE_STRING usKernelFile;
    157.     OBJECT_ATTRIBUTES oaKernelFile;
    158.     NTSTATUS ns = STATUS_SUCCESS;
    159.     IO_STATUS_BLOCK iosb;
    160.     ULONG dwViewSize = 0;
    161.  
    162.     RtlInitUnicodeString(&usKernelFile, L"\\SystemRoot\\System32\\ntoskrnl.exe");
    163.     InitializeObjectAttributes(&oaKernelFile, &usKernelFile, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
    164.         NULL, NULL);
    165.     ns = ZwOpenFile(&hKernelFile, FILE_READ_DATA | SYNCHRONIZE, &oaKernelFile, &iosb,
    166.         FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_SYNCHRONOUS_IO_NONALERT);
    167.     if (ns != STATUS_SUCCESS)
    168.         return ns;
    169.     ns = ZwCreateSection(&hKernelSection, SECTION_MAP_READ, NULL, NULL, PAGE_READONLY, 0x8000000,
    170.         hKernelFile);
    171.     if (ns != STATUS_SUCCESS){
    172.         UnMapKernel();
    173.         return ns;
    174.     }
    175.     ns = ZwMapViewOfSection(hKernelSection, NtCurrentProcess(), &pKernel, 0, 0, NULL, &dwViewSize,
    176.         ViewShare, 0, PAGE_READONLY);
    177.     if (ns != STATUS_SUCCESS)
    178.         UnMapKernel();
    179.     return ns;
    180. }
    181.  
    182. ULONG mystrcmp(char *str1, char *str2){
    183.     while(*str1 && *str2)
    184.         if(*str1 == *str2){
    185.             str1++;
    186.             str2++;
    187.         }else
    188.             return 0;
    189.     if(*str1 && !*str2)
    190.         return 0;
    191.     else
    192.         if (*str2 && !*str1)
    193.             return 0;
    194.     return 1;
    195. }
    196.  
    197. ULONG xGetProcAddress(ULONG hModule, char *pszName){   
    198.     ULONG dwNameCount, *AddressOfNames, *AddressOfFunctions;
    199.     USHORT *AddressOfOrdinals;
    200.     ULONG i;
    201.     char *pszExportName;    
    202.  
    203.     char *ptr = (char *)hModule;
    204.     ptr += 0x3c;
    205.     ptr = (char *)(*(ULONG *)ptr) + hModule + 0x78;
    206.     ptr = (char *)(*(ULONG *)ptr) + hModule;
    207.     dwNameCount = *(ULONG *)(ptr + 24);
    208.     AddressOfNames = (ULONG *)(*(ULONG *)(ptr + 32) + hModule);
    209.     AddressOfOrdinals = (USHORT *)((*(ULONG *)(ptr + 36)) + hModule);
    210.     AddressOfFunctions = (ULONG *)((*(ULONG *)(ptr + 28)) + hModule);
    211.     for(i = 0; i < dwNameCount; i++){      
    212.         pszExportName = (char *)(AddressOfNames[i] + hModule);
    213.         if(mystrcmp(pszExportName, pszName) == 1)
    214.             return (ULONG)(AddressOfFunctions[AddressOfOrdinals[i]]);
    215.     }
    216.     return 0;
    217. }
    218.  
    219. typedef struct _IMAGE_BASE_RELOCATION{
    220.     ULONG VirtualAddress;
    221.     ULONG SizeOfBlock;
    222. } IMAGE_BASE_RELOCATION, *PIMAGE_BASE_RELOCATION;
    223.  
    224. typedef struct {
    225.     USHORT offset: 12;
    226.     USHORT type: 4;
    227. } IMAGE_FIXUP_ENTRY, *PIMAGE_FIXUP_ENTRY;
    228.  
    229. ULONG GetKiServiceTable(ULONG SDT, ULONG hModule){
    230.     char *ptr;
    231.     PIMAGE_BASE_RELOCATION pbr;
    232.     PIMAGE_FIXUP_ENTRY pfe;
    233.     ULONG bFirst = 1, dwPointerRVA, i;
    234.  
    235.     ptr = (char *)hModule;
    236.     ptr += 0x3c;
    237.     ptr = (char *)(*(ULONG *)ptr) + hModule + 0xA0;
    238.     pbr = (PIMAGE_BASE_RELOCATION)((char *)(*(ULONG *)ptr) + hModule);
    239.     while ((bFirst) || (pbr->VirtualAddress)){
    240.         bFirst = 0;
    241.         pfe = (PIMAGE_FIXUP_ENTRY)((ULONG)pbr + 8);
    242.         for (i = 0; i < (pbr->SizeOfBlock - 8) >> 1; i++, pfe++)
    243.             if (pfe->type == 3){
    244.                 dwPointerRVA = pbr->VirtualAddress + pfe->offset;
    245.                 if (*(PULONG)(hModule + dwPointerRVA) - 0x400000 == SDT)
    246.                     if (*(PUSHORT)(hModule + dwPointerRVA - 2) == 0x05c7)
    247.                         return (*(PULONG)(hModule + dwPointerRVA + 4) - 0x400000 + hModule);
    248.             }
    249.         *(PULONG)&pbr += pbr->SizeOfBlock;
    250.     }
    251.     return 0;
    252. }
    253.  
    254. ULONG GetKernelBase(){
    255.     ULONG cb = 0, i;
    256.     PSYSTEM_MODULE_INFORMATION p = NULL;
    257.     NTSTATUS ns;
    258.  
    259.     ZwQuerySystemInformation(SystemModuleInformation, &p, 0, &cb);
    260.     if (!cb)
    261.         return 0;
    262.     p = ExAllocatePool(PagedPool, cb);
    263.     if (!p)
    264.         return 0;
    265.     ns = ZwQuerySystemInformation(SystemModuleInformation, p, cb, &cb);
    266.     if (ns != STATUS_SUCCESS)
    267.         goto exit;
    268.     for (i = 0; i < p->dwCount; i++)
    269.         if (mystrcmp("ntoskrnl.exe", &(p->Modules[i].ImageName[p->Modules[i].ModuleNameOffset])) == 1)
    270.             return (ULONG)p->Modules[i].Base;
    271. exit:
    272.     ExFreePool(p);
    273.     return 0;
    274. }
    275.  
    276. NTSTATUS RestoreSDT(){
    277.     ULONG SDT, KernelBase;
    278.     PNTPROC KiServiceTable;
    279.  
    280.     if (MapKernel() != STATUS_SUCCESS)
    281.         return STATUS_SUCCESS;
    282.     SDT = xGetProcAddress((ULONG)pKernel, "KeServiceDescriptorTable");
    283.     if (!SDT)
    284.         goto exit;
    285.     KiServiceTable = (PNTPROC)GetKiServiceTable(SDT, (ULONG)pKernel);
    286.     if (!KiServiceTable)
    287.         goto exit;
    288.     KernelBase = GetKernelBase();
    289.     if (!KernelBase)
    290.         goto exit;
    291.     DrvUnhookQST(RESTORE_SYSCALL, (ULONG)(KiServiceTable[RESTORE_SYSCALL]) - 0x400000 + GetKernelBase());
    292. exit:
    293.     UnMapKernel();
    294.     return STATUS_SUCCESS;
    295. }
    296.  
    297. NTSTATUS DriverEntry(PDRIVER_OBJECT  DriverObject, PUNICODE_STRING RegistryPath){
    298.     DriverObject->DriverUnload = DriverUnload;
    299.     RestoreSDT();
    300.     return STATUS_SUCCESS;
    301. }
     
  5. DeeoniS

    DeeoniS New Member

    Публикаций:
    0
    Регистрация:
    6 авг 2004
    Сообщения:
    132
    n0name, спасибо. Вроде то что надо. Но при беглом просмотре возник один вопрос: зачем в GetKernelBase делаешь это:
    Код (Text):
    1.     for (i = 0; i < p->dwCount; i++)
    2.         if (mystrcmp("ntoskrnl.exe", &(p->Modules[i].ImageName[p->Modules[i].ModuleNameOffset])) == 1)
    3.             return (ULONG)p->Modules[i].Base;
    во-первых, ядро вроде все время первым в списке долдно идти, а во-вторых, оно не всегда будет называться
    ntoskrnl.exe. Например на многопроцессорной машине ядро называется ntkrnlpa.exe
     
  6. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    должно, не должно, это вопрос спорный, хочешь сделаю скрин где ntoskrnl.exe последний?
    Ну да, но для многопроцессорной машины и код должен быть более строгим.
     
  7. DeeoniS

    DeeoniS New Member

    Публикаций:
    0
    Регистрация:
    6 авг 2004
    Сообщения:
    132
    а вчем строгость будет заключаться?
     
  8. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    Та же функция восстановления в SST будет другой.
     
  9. Nail

    Nail RustyNail

    Публикаций:
    0
    Регистрация:
    16 июл 2006
    Сообщения:
    10
    Даже на однопроцессорной тачке ядро может называться по любому.
    boot.ini: /KERNEL=lol.xxx
    Хм, не видел, чтобы ядро было в списке не первым.
     
  10. Nouzui

    Nouzui New Member

    Публикаций:
    0
    Регистрация:
    17 ноя 2006
    Сообщения:
    856
    и как тогда вообще узнать, что это ядро?
     
  11. gilg

    gilg New Member

    Публикаций:
    0
    Регистрация:
    19 май 2005
    Сообщения:
    527
    Nouzui
    Ядро всегда первое в списке. Сколько бы бсодов было, если его куда-нить сдвинуть :)