Сейчас на форуме: r0lka, yashechka (+5 невидимых)

 eXeL@B —› Крэки, обсуждения —› KeServiceDescriptorTableShadow
Посл.ответ Сообщение

Ранг: 3.0 (гость)
Активность: 0=0
Статус: Участник

Создано: 10 сентября 2005 18:16
· Личное сообщение · #1

Вопрос: как вызывать NtUser функции (графическая подсистема) из драйвера?
Насколько я понимаю, надо найти KeServiceDescriptorTableShadow.
Проблема номер 1 - найти эту таблицу
Проблема номер 2 - определить номер нужного системного вызова.

Может кто подскажет как это сделать?



Ранг: 12.0 (новичок)
Активность: 0.010
Статус: Участник

Создано: 11 сентября 2005 14:27
· Личное сообщение · #2

Проще сделать екзешник и запускать его с правами текущего юзера из драйвера. А потом из драйвера же им и управлять



Ранг: 51.9 (постоянный)
Активность: 0.030
Статус: Участник

Создано: 12 сентября 2005 10:43
· Личное сообщение · #3

А чем тебе не подходит импорт с Win32k.sys ?



Ранг: 51.9 (постоянный)
Активность: 0.030
Статус: Участник

Создано: 12 сентября 2005 11:22
· Личное сообщение · #4

А что мешает вызывать Int 2eh с EAX кодом системного сервиса ?



Ранг: 3.0 (гость)
Активность: 0=0
Статус: Участник

Создано: 12 сентября 2005 16:00
· Личное сообщение · #5

Barakuda пишет:
А чем тебе не подходит импорт с Win32k.sys ?


Тем, что функции не экспортируются.

Barakuda пишет:
А что мешает вызывать Int 2eh с EAX кодом системного сервиса ?


Сколько не пробовал, только синий экран получил.
Да и к тому же мне надо эти функции перехватывать, так что KeServiceDescriptorTableShadow искать все равно придется.



Ранг: 51.9 (постоянный)
Активность: 0.030
Статус: Участник

Создано: 13 сентября 2005 10:32
· Личное сообщение · #6

1) О самих стуктурах:
typedef struct SystemServiceDescriptorTable
{
SSD SystemServiceDescriptors[4];
} SSDT, *LPSSDT;

Ниже приводятся описания остальных структур:

typedef VOID *SSTAT[];
typedef unsigned char SSTPT[];
typedef SSTAT *LPSSTAT;
typedef SSTPT *LPSSTPT;

typedef struct SystemServiceDescriptor
{
LPSSTAT lpSystemServiceTableAddressTable;
ULONG dwFirstServiceIndex;
ULONG dwSystemServiceTableNumEntries;
LPSSTPT lpSystemServiceTableParameterTable;
} SSD, *LPSSD;

Я думаю это ты знаешь.

2) В ядре существует функция, для добавления новых сервисов - KeAddSystemServiceTable. Она умеет добавлять сервисы в обе таблицы. Учитывая тот факт что 0-й дескриптор у них идентичен можно, путем сканирования кода функции KeAddSystemServiceTable, найти адрес Shadow таблицы. Как это делается:
/*
* Find the address of the KeServiceDescriptorTableShadow.
* Uses technique from Undocumented Windows NT.
*/
static struct srv_table *
find_shadow_table ()
{
unsigned char *check = (unsigned char *)KeAddSystemServiceTable;
int i;
struct srv_table *rc=0;

for (i=0; i<100; i++) {
__try {
rc = *(struct srv_table**)check;
if (!MmIsAddressValid (rc)
|| (rc == KeServiceDescriptorTable)
|| (memcmp (rc, KeServiceDescriptorTable, sizeof (*rc))
!= 0)) {
check++;
rc = 0;
}
} __except (EXCEPTION_EXECUTE_HANDLER) {
rc = 0;
}
if (rc)
break;
}
return rc;
}

3) Если же по каким-то причинам этот метод не дал положительного результата, то делается попытка использовать жесткий адрес (KeServiceDescriptorTable-0x230) - т.к. положение Shadow таблицы в памяти не изменилось с WinNt4 SP3. Возможен вариант, но это на твой страх и риск, получения KeServiceDescriptorTable с ntoskrnl.exe и добавления 0х50 байт, для получения w32k!W32pServiceTable.

4) Почитай Свена Шрайбера, а также Марка Руссиновича. У них очень хорошо изложен теоретический материал. А для практики - существуют исходники руткитов и трейсеров.



Ранг: 3.0 (гость)
Активность: 0=0
Статус: Участник

Создано: 13 сентября 2005 13:08
· Личное сообщение · #7

Этот метод я испробовал, но он почемуто ничего не находит.

Может кто-нибудь подскажет гуру у которого можно об этих вещах спросить, а то мозги уже плавяться.



Ранг: 51.9 (постоянный)
Активность: 0.030
Статус: Участник

Создано: 13 сентября 2005 13:25
· Личное сообщение · #8

Вот исходник, который РАБОТАЕТ именно по такому принципу (Правда функция поиска Shadow имеет несколько другое имя: "LPSSDT FindShadowTable(void)" ) he4dev.e1.bmstu.ru/HookSysCall/He4Hook.zip
Если уж не хватит терпения разобратся, то тебе стоит задать этот вопрос на форуме www.wasm.ru/forum/action=vtopic&forum=4
И скажи всётаки какая у тебя Windows. Неужели трудно в Айсе написать "d KeServiceDescriptorTable" и приплюсовать 0х50 байт для получения указателя на адреса процедур W32k ?



Ранг: 3.0 (гость)
Активность: 0=0
Статус: Участник

Создано: 13 сентября 2005 14:12
· Личное сообщение · #9

Я брал код именно из этого исходника. Он работает только на чистой системе, а когда стоит антивирус Касперского, то ничего не работает. А почуму не работает не могу понять.



Ранг: 51.9 (постоянный)
Активность: 0.030
Статус: Участник

Создано: 13 сентября 2005 14:37
· Личное сообщение · #10

Что же ты раньше молчал ?
Чтоб Касперского не выбили, он перемещает SDT.

Почитай это.
virusinfo.info/archive/index.php/t-2487.html




Ранг: 120.6 (ветеран)
Активность: 0.090
Статус: Участник
rootkit developer

Создано: 14 сентября 2005 21:00
· Личное сообщение · #11

MaxSS
Помню геморроился я сам как-то с этим делом.
Трабл номер раз: при перемещении SDT антивирусом КарлаСпермского меняется содержимое первой SST и смещение Shadow SDT, а следовательно вышеприведенный код не работает. Проблема решается сканированием KiAddSystemServiceTable на инструкцию lea ecx, KeServiceDescriptorTableShadow[eax].
Вот работающий код находящий Shadow SDT на виндах от NT4 до лонгхорна и не боящийся приколов Дяди Карла:
void GetKeServiceDescriptorTableShadow()
{
	PUCHAR cPtr, pOpcode;
	ULONG Length;
	
	for (cPtr = (PUCHAR)KeAddSystemServiceTable; 
	     cPtr < (PUCHAR)KeAddSystemServiceTable + PAGE_SIZE; 
		 cPtr += Length) 
	{
		if (!MmIsAddressValid(cPtr)) break;

		Length = SizeOfCode(cPtr, &pOpcode);

		if (!Length || (Length == 1 && *pOpcode == 0xC3)) break;
		
		if (*(PUSHORT)pOpcode == 0x888D)
		{
			KeServiceDescriptorTableShadow = *(PVOID *)(pOpcode + 2);
			break;
		}
	}
}

Функция SizeOfCode - получает размер инструкции по указателю. Я использовал свой дизассемблер длин LDasm.

Трабл номер два: содержимое SST win32k как и сам драйвер win32k.sys отображаються на ЮЗЕРМОДНЫЕ АДРЕСА, как и все драйвера имеющие отношение к графической подсистеме. Это не баг, так как на их страницах стоит атрибут супервизора. Соответствующая память отмаплена ТОЛЬКО в GUI процессы.
Тоесть нужно подключаться к GUI процессу и там читать/модифицировать SST win32k. Я рекомендую подключаться к csrss.exe. Код ищущий этот процесс (не по имени):
HANDLE GetCsrPid()
{
	HANDLE                        Process, hObject;
	HANDLE                        CsrId = (HANDLE)0;
	OBJECT_ATTRIBUTES             obj;
	CLIENT_ID                     cid;
	UCHAR                         Buff[0x100];
	POBJECT_NAME_INFORMATION      ObjName = (PVOID)&Buff;
	PSYSTEM_HANDLE_INFORMATION_EX Handles;
	ULONG                         r;

	Handles = GetInfoTable(SystemHandleInformation);

	if (!Handles) return CsrId;

	for (r = 0; r < Handles->NumberOfHandles; r++)
	{
		if (Handles->Information[r].ObjectTypeNumber == 21) //Port object
		{
			InitializeObjectAttributes(&obj, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);
			
			cid.UniqueProcess = (HANDLE)Handles->Information[r].ProcessId;
			cid.UniqueThread  = 0;

			if (NT_SUCCESS(NtOpenProcess(&Process, PROCESS_DUP_HANDLE, &obj, &cid)))
			{
				if (NT_SUCCESS(ZwDuplicateObject(Process, 
				                                 (HANDLE)Handles->Information[r].Handle,
				                                 NtCurrentProcess(), 
												 &hObject, 
						     		             0, 0, DUPLICATE_SAME_ACCESS)))
				{
					if (NT_SUCCESS(ZwQueryObject(hObject, 
						                         ObjectNameInformation, 
					           		             ObjName, 
												 0x100, NULL)))
					{
						if (ObjName->Name.Buffer && 
							!wcsncmp(L"\\Windows\\ApiPort", ObjName->Name.Buffer, 20))
						{
							CsrId = (HANDLE)Handles->Information[r].ProcessId;
						} 
					}

					ZwClose(hObject);
				}

				ZwClose(Process);
			}
		}
	}

	ExFreePool(Handles);

	return CsrId;
}


Трабл номер три: для выхова этих функций нужно использовать GUI поток. Отличается он от обычного тем, что в его NT_TIB в ServiceTable лежит указатель не на KeServiceDescriptorTable, а на KeServiceDescriptorTableShadow. Для создания GUI потока можно воспользоваться неэкспортируемой функцией PsConvertToGuiThread, но несуществует надежного способа ее поиска, поэтому я рекомендую менять указатель в NT_TIB вручную.

Трабл номер четыре: необходимо чтобы на процесс в котором создан поток отображались видео драйвера. Можно создать MDL, захватить память в другом процессе и отобразить себе с помощью MmMapLockedPagesSpecifyCache, но это геморно, поэтому создавай поток в том же csrss.exe.

Надеюсь мой ответ тебе чем нибудь поможет.

P.S. в следующий раз подобные вопросы задавай на васме, я обычно сижу там, и такой вопрос без внимания не оставлю.

-----
Скажем дружно - нафиг нужно.



 eXeL@B —› Крэки, обсуждения —› KeServiceDescriptorTableShadow
:: Ваш ответ
Жирный  Курсив  Подчеркнутый  Перечеркнутый  {mpf5}  Код  Вставить ссылку 
:s1: :s2: :s3: :s4: :s5: :s6: :s7: :s8: :s9: :s10: :s11: :s12: :s13: :s14: :s15: :s16:


Максимальный размер аттача: 500KB.
Ваш логин: german1505 » Выход » ЛС
   Для печати Для печати