Восстановление оригинального адреса функции в SST!

Тема в разделе "WASM.BEGINNERS", создана пользователем vanilly_cpp, 29 ноя 2007.

  1. vanilly_cpp

    vanilly_cpp New Member

    Публикаций:
    0
    Регистрация:
    29 ноя 2007
    Сообщения:
    68
    Доброго времени суток!
    Прошу помочь начинающему с вот такой задачкой: Необходимо восстановить оригинальный адрес функции ZwWriteVirtualMemory в SST!
    Как это делается с точки зрения теории вроде нашел :

    «Для восстановления SST можно использовать ее копию, хранящуюся внутри NTOSKRNL.EXE. Находим все перекрестные ссылки к KeServiceDescriptorTable (т.е. просто ищем ее адрес, записанный с учетом обратного порядка байт на x86, задом наоборот). Одна из них ведет к инструкции типа "mov [mem], imm32" и представляет собой смещение оригинальной SST (imm32), записываемой в KeServiceDescriptorTable[0].»

    Проблема 1: Как будет выглядеть инструкция «mov [mem], imm32» в HEX или bin виде?
    Проблема 2: Даже если я и узнаю как будет выглядеть данная инструкция, в правильности своих дальнейших действий нет ни какой уверенности. Для начала я бы взял и перевернул последовательность байт отображающую данную инструкцию (дабы получить код, записанный с учетом обратного порядка байт на x86), затем используя функции ZwCreateFile / ZwReadFile загрузил бы файл NTOSKRNL.EXE в память, после чего нашел бы в нем полученную последовательность байт, которая бы и являлась начальным адресом SST в данном файле, затем со смещением в 4 байта от полученного адреса я смог бы найли адреса оригинальных функций SST, нашел бы среди них ту которая мне нужна, взял бы ее адрес и записал в ту же позицию в SST в памяти.

    Плиз развейте или подтвердите кто-нибуть мой миф ))) и помогите пожалуйста с получением кода инструкции «mov [mem], imm32» если она мне чем-то действительно поможет.

    Заранее большое спосибо!
     
  2. PaCHER

    PaCHER New Member

    Публикаций:
    0
    Регистрация:
    25 мар 2006
    Сообщения:
    852
    Проблема 1: Как будет выглядеть инструкция «mov [mem], imm32» в HEX или bin виде?
    Береш отладчик вбиваеш инструкциюи смотриш кода
    C705 mem_dword imm32_dword

    Посмотри какиенить сырсы сигнатурных поисков, а как выгледят команды в хексе смотри просто в Olly DBG
     
  3. vanilly_cpp

    vanilly_cpp New Member

    Публикаций:
    0
    Регистрация:
    29 ноя 2007
    Сообщения:
    68
    Спасибо за ответ!

    "Береш отладчик вбиваеш инструкциюи смотриш кода" - это в том смысле, что мне нужно создать левый .exe в котором бы просто были эти инструкции, затем загрузить в Olly DBG и узнать их код? Но я ведь не могу это(mov [mem], imm32) скомпилить. Одним из операндов вроде бы должен быть регистр?

    Или я очень сильно туплю?

    Пробовал так же запустить в Olly DBG какой-нибудь .exe и вбить вместо какой-нибудь строки данную инструкцию, тоже не вышло.

    А что значит C705 - не это ли именно то, что мне нужно?

    Пробовал искать данную последовательность только наоборот(0x05 0xC7) в NTOSKRNL.EXE нашел ее аж 12 раз

    DWORD dw;

    HANDLE hh = CreateFile("C:/WINDOWS/system32/NTOSKRNL.EXE",
    GENERIC_READ,
    0,
    NULL,
    OPEN_EXISTING,
    0,
    NULL);

    int i = GetFileSize(hh, &dw);

    UCHAR* buf = new UCHAR;

    ReadFile(hh, buf, i, &dw, NULL);

    int k = 1;

    for(int n = 0; n < i; n ++)
    {
    if(buf[n] == 0x05)
    {
    if(buf[n+1] == 0xC7)
    {
    printf("found - %d\n", k++);
    }
    }
    }

    delete [] buf;

    Я вообще хоть на правильном пути к решению своей задачи или глупости делаю?
     
  4. asd

    asd New Member

    Публикаций:
    0
    Регистрация:
    12 мар 2005
    Сообщения:
    952
    Адрес:
    Russia
    vanilly_cpp
    поиск по васму "90210 sdt" там кода работающего и не очень завались.
     
  5. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    загружаешь совершенно левый бинарник, хоть блокнот, хоть калькулятор. выбираешь любую инструкцию и жмешь пробел (Assembly). Вводишь команду mov [12345678], abcdef12 - пример команды типа mov [mem],imm32, и жмешь ентер. "и о чудо, никаких пятен!" олли отассемблировал команду и показал слева ее машинный код.
     
  6. vanilly_cpp

    vanilly_cpp New Member

    Публикаций:
    0
    Регистрация:
    29 ноя 2007
    Сообщения:
    68
    asd
    Спасибо по поводу запроса поиска! Я икал SST или SSDT, а там в темах упоминается SDT! Потому не находил! Большое спасибо сейчас буду изучать!

    Дело принципа, просто заинтересовало!
    Все делаю именно так, но к несчастью пятна есть (( Загрузил bin NOTEPAD сделал все вроде так, как нужно, но увы: ниже окошка ввода команд появляется красненькая надпись "Unknown identifier" и ничего не происходит ((((
     
  7. vanilly_cpp

    vanilly_cpp New Member

    Публикаций:
    0
    Регистрация:
    29 ноя 2007
    Сообщения:
    68
    Asd, на одной из найденных тем я встретил фразу
    пробовал поиском таких статей не нашел, можно попросить ссылочку? Очень хочется посмотреть теоретическое описание! ))
     
  8. vanilly_cpp

    vanilly_cpp New Member

    Публикаций:
    0
    Регистрация:
    29 ноя 2007
    Сообщения:
    68
    Упс, сорри не дочитал! Я искал по WASM а статья с rootkit.com, уже нашел! Последний пост отменяется!
     
  9. vanilly_cpp

    vanilly_cpp New Member

    Публикаций:
    0
    Регистрация:
    29 ноя 2007
    Сообщения:
    68
    Искал инфу по форму, нашел следуюший код:

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

    В ф-ии "xGetProcAddress" в стороке

    dwNameCount = *(ULONG *)(ptr + 24);

    получаю ноль (dwNameCount = 0)

    Узнать по этому поводу смог то, что образ файла загружается загрузчиком ОС как бы по по одному, а зачитывается ф-ей xGetProcAddress по другому, и что необходима несколько иная реализация данной ф-ии!

    Кто что может подсказать по этому поводу?

    P.S. система "WinXP sp2"
     
  10. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Адрес оригинальной SST в ntoskrnl является одним из параметров функции KeAddSystemServiceTable, вызываемой для
    добавления SST в том же модуле(в win32k также). Но поиск ссылки на эту функцию будет довольно сложен.