6
0
mirror of https://github.com/JKornev/hidden synced 2024-06-25 00:18:04 +00:00

Hiding a process from PspCidTable on Windows Vista and 7

This commit is contained in:
JKornev 2021-08-24 03:45:25 +03:00
parent 0c01afa4e1
commit 536a3ec3e8
5 changed files with 70 additions and 21 deletions

@ -249,3 +249,23 @@ NTSTATUS NormalizeDevicePath(PCUNICODE_STRING Path, PUNICODE_STRING Normalized)
return STATUS_SUCCESS;
}
BOOLEAN IsWin8OrAbove()
{//TODO: cache it
RTL_OSVERSIONINFOW version;
NTSTATUS status;
RtlZeroMemory(&version, sizeof(version));
status = RtlGetVersion(&version);
if (!NT_SUCCESS(status))
LogWarning("Can't get an OS version, status:%x", status);
if (version.dwMajorVersion < 6)
return FALSE;
if (version.dwMajorVersion == 6 && version.dwMinorVersion < 2) // NT 6.2 == Win8
return FALSE;
return TRUE;
}

@ -156,6 +156,8 @@ NTSTATUS NormalizeDevicePath(PCUNICODE_STRING Path, PUNICODE_STRING Normalized);
__VA_ARGS__ \
)
BOOLEAN IsWin8OrAbove();
#define LogError(frmt, ...) _LogMsg(DPFLTR_ERROR_LEVEL, "error", frmt, __VA_ARGS__)
#define LogWarning(frmt, ...) _LogMsg(DPFLTR_WARNING_LEVEL, "warning", frmt, __VA_ARGS__)
#define LogTrace(frmt, ...) _LogMsg(DPFLTR_TRACE_LEVEL, "trace", frmt, __VA_ARGS__)

@ -103,16 +103,10 @@ BOOLEAN LookForPspCidTableCallback(ZyanU64 address, ZydisDecodedInstruction* ins
{
BOOLEAN EnterCalls = *(BOOLEAN*)params;
#ifdef _M_AMD64
UCHAR opcodeMOV = 0x8B; // MOV Reg, Mem
#else
UCHAR opcodeMOV = 0xA1; // MOV Reg, Mem
#endif
if (instruction->mnemonic == ZYDIS_MNEMONIC_RET)
return FALSE; // Stop scan if the function is ended
if (instruction->mnemonic == ZYDIS_MNEMONIC_MOV && instruction->opcode == opcodeMOV)
if (instruction->mnemonic == ZYDIS_MNEMONIC_MOV)
{
ZyanU64 pointer = 0;

@ -304,7 +304,6 @@ BOOLEAN RemoveHandleCallbackWin8(PVOID PspCidTable, PHANDLE_TABLE_ENTRY HandleTa
PHANDLE_TABLE_WIN8 cidTable = (PHANDLE_TABLE_WIN8)PspCidTable;
BOOLEAN result = FALSE;
if (PspCidTable != GetPspCidTablePointer())
{
LogWarning("Attempt to enumerate invalid table, %p != %p", PspCidTable, GetPspCidTablePointer());
@ -314,16 +313,6 @@ BOOLEAN RemoveHandleCallbackWin8(PVOID PspCidTable, PHANDLE_TABLE_ENTRY HandleTa
if (context->ProcessId == Handle)
{
PEPROCESS System;
NTSTATUS status;
status = PsLookupProcessByProcessId(SYSTEM_PROCESS_ID, &System);
if (!NT_SUCCESS(status))
{
LogWarning("Warning, can't find active system process");
goto cleanup;
}
context->Found = TRUE;
context->Entry = HandleTableEntry;
context->EntryBackup = *HandleTableEntry;
@ -356,6 +345,28 @@ cleanup_no_unlock:
return result;
}
BOOLEAN RemoveHandleCallback(PHANDLE_TABLE_ENTRY HandleTableEntry, HANDLE Handle, PVOID EnumParameter)
{
PCidTableContext context = (PCidTableContext)EnumParameter;
if (context->ProcessId != Handle)
return FALSE;
context->Found = TRUE;
context->Entry = HandleTableEntry;
context->EntryBackup = *HandleTableEntry;
LogInfo(
"PID %Iu has been removed from PspCidTable, entry:%p, object:%p, access:%08x",
Handle,
HandleTableEntry,
context->EntryBackup.u1.Object,
context->EntryBackup.u2.GrantedAccess
);
return TRUE;
}
VOID UnlinkProcessFromCidTable(PProcessTableEntry Entry)
{
PVOID PspCidTable = GetPspCidTablePointer();
@ -370,7 +381,8 @@ VOID UnlinkProcessFromCidTable(PProcessTableEntry Entry)
context.ProcessId = Entry->processId;
context.Found = FALSE;
if (!ExEnumHandleTable(PspCidTable, (EX_ENUMERATE_HANDLE_ROUTINE)RemoveHandleCallbackWin8, &context, NULL))
EX_ENUMERATE_HANDLE_ROUTINE routine = (IsWin8OrAbove() ? (EX_ENUMERATE_HANDLE_ROUTINE)&RemoveHandleCallbackWin8 : &RemoveHandleCallback);
if (!ExEnumHandleTable(PspCidTable, routine, &context, NULL))
{
LogWarning("Can't unlink process %Iu from PspCidTable", Entry->processId);
return;
@ -382,6 +394,13 @@ VOID UnlinkProcessFromCidTable(PProcessTableEntry Entry)
return;
}
// Hack for Windows Vista, 7, to avoid lock bit leak
if (!IsWin8OrAbove())
{
context.Entry->u1.Object = NULL;
context.Entry->u2.GrantedAccess = 0;
}
Entry->cidEntryBackup = context.EntryBackup;
Entry->cidEntry = context.Entry;
}
@ -530,7 +549,16 @@ VOID CheckProcessFlags(PProcessTableEntry Entry, PCUNICODE_STRING ImgPath, HANDL
}
if (Entry->hidden)
UnlinkProcessFromActiveProcessLinks(Entry);
{
// If CheckProcessFlags() performed for initialized process we can safely perform full process
// hiding code. But if a process isn't initialized (for instance on a ps create notification) we
// need to postpone removing from PspCidTable because in a current step it would break a process
// initialization
if (Entry->inited)
HideProcess(Entry);
else
UnlinkProcessFromActiveProcessLinks(Entry);
}
}
VOID LoadProcessImageNotifyCallback(PUNICODE_STRING FullImageName, HANDLE ProcessId, PIMAGE_INFO ImageInfo)
@ -547,7 +575,7 @@ VOID LoadProcessImageNotifyCallback(PUNICODE_STRING FullImageName, HANDLE Proces
ExAcquireFastMutex(&g_processTableLock);
lookup = GetProcessInProcessTable(ProcessId);
if (!lookup->inited)
if (lookup && !lookup->inited)
{
lookup->inited = TRUE;
LogTrace("Process has been initialized:%Iu", ProcessId);

@ -75,9 +75,14 @@
- Улучшить алгоритм поиска офсета
+ Добавить конфигурацию в реестр
- Реализовать скрытие процесса из PspCidTable
- Добавить сокрытие потоков из PspCidTable
+ Добавить поддержку Vista\7
- Решить проблему синхронизации доступа к ActiveProcessLinks
- Добавить поддержку сокрытия из SessionProcessLinks (если в этом есть смысл)
- Реализовать сокрытие сервисов через scdb патч
- Добавить тест для проверки сокрытия процессов
+ Решить проблему с %tu принтом лога на 32-бит драйвере
- Эмулировать создание reg\fs обьектов, когда обьект с таким же именем скрыт
+ GetProcessInProcessTable может возвращать ptr чтобы избежать UpdateProcessInProcessTable
- Windows 7 x86 protect тест завален
- Проверить всё на Windows Vista