ищу shadow sdt - нужны win32k сервисы (NtUserXXX/NtGdiXXX),- методом поиска lea ecx, dword_[eax] от начала KeAddSystemServiceTable. нахожу. юзаю вот такие структурки: PHP: typedef struct _SYSTEM_SERVICE_TABLE { ULONG** ServiceTable; ULONG* CounterTable; ULONG ServiceLimit; UCHAR* ArgumentTable; }SYSTEM_SERVICE_TABLE , * PSYSTEM_SERVICE_TABLE , * * PPSYSTEM_SERVICE_TABLE; typedef struct _SERVICE_DESCRIPTOR_TABLE { SYSTEM_SERVICE_TABLE ntoskrnl; SYSTEM_SERVICE_TABLE win32k; SYSTEM_SERVICE_TABLE unused1; SYSTEM_SERVICE_TABLE unused2; }SERVICE_DESCRIPTOR_TABLE, * PSERVICE_DESCRIPTOR_TABLE, * * PPSERVICE_DESCRIPTOR_TABLE; параметр число сервисов Win32k нормально отображается, но вот указатель на таблицу уводит пальцем в небо. ВТФ?! зы slesh ни на кого кроме тя не рассчитываю =)
дык у Shadow у каждого процесса своя, так что ты должен прежде аттачиться к нужному процессу. т.е. всё типа так: Code: typedef struct _SYSTEM_SERVICE_TABLE { PNTPROC ServiceTable; PDWORD CounterTable; ULONG ServiceLimit; PBYTE ArgumentTable; } SYSTEM_SERVICE_TABLE, *PSYSTEM_SERVICE_TABLE; typedef struct _SERVICE_DESCRIPTOR_TABLE { SYSTEM_SERVICE_TABLE ntoskrnl; //SST для ntoskrnl.exe SYSTEM_SERVICE_TABLE win32k; //SST для win32k.sys SYSTEM_SERVICE_TABLE unused1; SYSTEM_SERVICE_TABLE unused2; } SERVICE_DESCRIPTOR_TABLE,*PSERVICE_DESCRIPTOR_TABLE; PSERVICE_DESCRIPTOR_TABLE ShadowTable; SYSTEM_SERVICE_TABLE * GetShadowSDT() { int i; unsigned char *check = (unsigned char*)KeAddSystemServiceTable; SYSTEM_SERVICE_TABLE *rc = 0; for (i = 0; i < 100; i++) { __try { rc = *(SYSTEM_SERVICE_TABLE**)check; if (!MmIsAddressValid(rc) || (rc == KeServiceDescriptorTable) || (memcmp(rc, KeServiceDescriptorTable, sizeof(*rc)))) { check++; rc = 0; } } __except (EXCEPTION_EXECUTE_HANDLER) { rc = 0; } if (rc) { break; } } return rc; } /*************************/ ShadowTable = (PSERVICE_DESCRIPTOR_TABLE)GetShadowSDT(); /*************************/ PsLookupProcessByProcessId KeAttachProcess ShadowTable->win32k.ServiceTable[ID]; KeDetachProcess
Только что набрасал код для Win 7 и протестил. Тестил получение адреса NtUserGetDC для calc.exe После ребута адрес стал 821ACBEB Кто в принципе сходится. в офсетах И во всех случаях это было АП win32k.sys так что норм. А если читать данные после детача, то будет бсод. потому что страницы Win32k.sys находятся в АП всех процессов, кроме ядра (по крайней мере судя по тесту)
респект мужик!! я даж вспомнил - гдето читал что вроде как вин32к мапится в каждый проц (но там говорилось что в юзермодное пространство, или чето такое) тока ресолвил я ее вот так (резудьтаты одинаковые): Code: ULONG utilsGetShadowSDT() { ULONG KrnlBase, i, rc = 0; ULONG KeAddSysSvcTable; utilsGetKernelInfo(KrnlBase, NULL); // windows 7 7600 x86 ntoskrnlpa!KeAddSystemServiceTable // PAGE:0058C0F2 mov edi, edi // PAGE:0058C0F4 push ebp // PAGE:0058C0F5 mov ebp, esp // PAGE:0058C0F7 cmp [ebp+arg_10], 1 // PAGE:0058C0FB ja short loc_58C15D // PAGE:0058C0FD mov eax, [ebp+arg_10] // PAGE:0058C100 shl eax, 4 // PAGE:0058C103 cmp ds:KeServiceDescriptorTable[eax], 0 // PAGE:0058C10A jnz short loc_58C15D // PAGE:0058C10C 8D 88 00 8A 56 00 lea ecx, dword_568A00[eax] <--- вот оно KeAddSysSvcTable = (ULONG)imagehlpGetExportEntry((CONST PVOID)KrnlBase, "KeAddSystemServiceTable"); for(i = KeAddSysSvcTable; i < KeAddSysSvcTable + 59; i++) { if(!MmIsAddressValid((PVOID)i)) break; if(*(unsigned short*)i == 0x888D) { rc = *(PULONG)(i + 2); break; } } return rc; }