mirror of https://github.com/JKornev/hidden
Improved looking for EPROCESS::ActiveProcessLinks algo
This commit is contained in:
parent
59439bae79
commit
331952e7fc
|
@ -1,6 +1,7 @@
|
|||
#include "KernelAnalyzer.h"
|
||||
#include "Helper.h"
|
||||
#include <Zydis/Zydis.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef struct _KernelInternals {
|
||||
ULONG ActiveProcessLinksOffset;
|
||||
|
@ -20,6 +21,14 @@ PVOID GetPspCidTablePointer()
|
|||
return s_NTinternals.PspCidTable;
|
||||
}
|
||||
|
||||
PLIST_ENTRY GetActiveProcessLinksList(PEPROCESS Process)
|
||||
{
|
||||
if (!s_NTinternals.ActiveProcessLinksOffset)
|
||||
return NULL;
|
||||
|
||||
return (PLIST_ENTRY)((ULONG_PTR)Process + s_NTinternals.ActiveProcessLinksOffset);
|
||||
}
|
||||
|
||||
// =========================================================================================
|
||||
|
||||
BOOLEAN Disassemble(PVOID fn, SIZE_T size, BOOLEAN(*InstructionCallback)(ZyanU64,ZydisDecodedInstruction*,PVOID), PVOID params)
|
||||
|
@ -168,9 +177,93 @@ VOID LookForPspCidTable()
|
|||
}
|
||||
}
|
||||
|
||||
VOID LookActiveProcessLock()
|
||||
// =========================================================================================
|
||||
|
||||
BOOLEAN IsKernelAddress(PVOID Address)
|
||||
{
|
||||
//Disassemble()
|
||||
#ifdef _M_AMD64
|
||||
ULONG_PTR kernelStarts = 0x800000000000;
|
||||
#else
|
||||
ULONG_PTR kernelStarts = 0x80000000;
|
||||
#endif
|
||||
|
||||
if ((ULONG_PTR)Address <= kernelStarts)
|
||||
return FALSE;
|
||||
|
||||
if (!MmIsAddressValid(Address))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOLEAN IsValidActiveProcessLinksOffset(PEPROCESS Process, HANDLE ProcessId, ULONG Offset)
|
||||
{
|
||||
// EPROCESS ActiveProcessLinks field is next to UniqueProcessId
|
||||
// ...
|
||||
// + 0x0b4 UniqueProcessId : Ptr32 Void
|
||||
// + 0x0b8 ActiveProcessLinks : _LIST_ENTRY
|
||||
// + 0x0c0 Flags2 : Uint4B
|
||||
// ...
|
||||
__try
|
||||
{
|
||||
HANDLE UniqueProcessId = *(HANDLE*)((ULONG_PTR)Process + Offset - sizeof(HANDLE));
|
||||
if (UniqueProcessId != ProcessId)
|
||||
return FALSE;
|
||||
|
||||
PLIST_ENTRY ActiveProcessLinks = (PLIST_ENTRY)((ULONG_PTR)Process + Offset);
|
||||
if (!IsKernelAddress(ActiveProcessLinks->Blink) || !IsKernelAddress(ActiveProcessLinks->Flink))
|
||||
return FALSE;
|
||||
}
|
||||
__except (EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
ULONG FindActiveProcessLinksOffset(PEPROCESS Process)
|
||||
{
|
||||
#ifdef _M_AMD64
|
||||
ULONG knownOffsets[] = { 0xE8/*Vista*/, 0x188/*7*/, 0x2E8/*8*/, 0x2F0/*TH1*/, 0x448/*20H1*/ };
|
||||
ULONG lookingStartOffset = 0xC0;
|
||||
ULONG lookingPeakOffset = 0x500;
|
||||
#else
|
||||
ULONG knownOffsets[] = { 0xA0/*Vista*/, 0xB8/*7*/, 0xE8/*20H1*/ };
|
||||
ULONG lookingStartOffset = 0x80;
|
||||
ULONG lookingPeakOffset = 0x200;
|
||||
#endif
|
||||
|
||||
HANDLE processId = PsGetProcessId(Process);
|
||||
|
||||
// Fast check
|
||||
|
||||
for (ULONG i = 0; i < _countof(knownOffsets); i++)
|
||||
{
|
||||
if (IsValidActiveProcessLinksOffset(Process, processId, knownOffsets[i]))
|
||||
return knownOffsets[i];
|
||||
}
|
||||
|
||||
// Slow check
|
||||
|
||||
for (ULONG offset = lookingStartOffset; offset < lookingPeakOffset; offset += sizeof(void*))
|
||||
{
|
||||
if (IsValidActiveProcessLinksOffset(Process, processId, offset))
|
||||
return offset;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
VOID LookForActiveProcessLinks()
|
||||
{
|
||||
s_NTinternals.ActiveProcessLinksOffset = FindActiveProcessLinksOffset(PsGetCurrentProcess());
|
||||
if (s_NTinternals.ActiveProcessLinksOffset)
|
||||
LogInfo("EPROCESS->ActiveProcessList offset is %x", s_NTinternals.ActiveProcessLinksOffset);
|
||||
else
|
||||
LogWarning("Failed to find EPROCESS->ActiveProcessList");
|
||||
|
||||
//TODO: PspActiveProcessLock
|
||||
}
|
||||
|
||||
// =========================================================================================
|
||||
|
@ -208,7 +301,7 @@ VOID InitializeKernelAnalyzer()
|
|||
return;
|
||||
|
||||
LookForPspCidTable();
|
||||
LookActiveProcessLock();
|
||||
LookForActiveProcessLinks();
|
||||
}
|
||||
|
||||
VOID DestroyKernelAnalyzer()
|
||||
|
|
|
@ -6,3 +6,5 @@ VOID InitializeKernelAnalyzer();
|
|||
VOID DestroyKernelAnalyzer();
|
||||
|
||||
PVOID GetPspCidTablePointer();
|
||||
|
||||
PLIST_ENTRY GetActiveProcessLinksList(PEPROCESS Process);
|
|
@ -173,49 +173,6 @@ OB_PREOP_CALLBACK_STATUS ThreadPreCallback(PVOID RegistrationContext, POB_PRE_OP
|
|||
return OB_PREOP_SUCCESS;
|
||||
}
|
||||
|
||||
//TODO:
|
||||
// - Find an offset on driver initialization step
|
||||
|
||||
BOOLEAN FindActiveProcessLinksOffset(PEPROCESS Process, ULONG* Offset)
|
||||
{
|
||||
#ifdef _M_AMD64
|
||||
ULONG peak = 0x300;
|
||||
#else
|
||||
ULONG peak = 0x150;
|
||||
#endif
|
||||
HANDLE* ptr = (HANDLE*)Process;
|
||||
HANDLE processId;
|
||||
ULONG i;
|
||||
|
||||
if (g_activeProcessListOffset)
|
||||
{
|
||||
*Offset = g_activeProcessListOffset;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
processId = PsGetProcessId(Process);
|
||||
|
||||
// EPROCESS ActiveProcessLinks field is next to UniqueProcessId
|
||||
// ...
|
||||
// + 0x0b4 UniqueProcessId : Ptr32 Void
|
||||
// + 0x0b8 ActiveProcessLinks : _LIST_ENTRY
|
||||
// + 0x0c0 Flags2 : Uint4B
|
||||
// ...
|
||||
for (i = 15; i < peak / sizeof(HANDLE); i++)
|
||||
{
|
||||
if (ptr[i] == processId)
|
||||
{
|
||||
ULONG offset = sizeof(HANDLE) * (i + 1);
|
||||
InterlockedExchange((LONG volatile*)&g_activeProcessListOffset, offset);
|
||||
LogInfo("EPROCESS->ActiveProcessList offset is %x", offset);
|
||||
*Offset = offset;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
VOID UnlinkProcessFromList(PLIST_ENTRY Current)
|
||||
{ // https://github.com/landhb/HideProcess/blob/master/driver/hideprocess.c
|
||||
PLIST_ENTRY Previous, Next;
|
||||
|
@ -239,18 +196,13 @@ VOID UnlinkProcessFromList(PLIST_ENTRY Current)
|
|||
//
|
||||
VOID UnlinkProcessFromActiveProcessLinks(PProcessTableEntry Entry)
|
||||
{
|
||||
PEPROCESS Process = Entry->reference;
|
||||
ULONG eprocListOffset = 0;
|
||||
PLIST_ENTRY CurrentList = NULL;
|
||||
|
||||
if (!FindActiveProcessLinksOffset(Process, &eprocListOffset))
|
||||
PLIST_ENTRY CurrentList = GetActiveProcessLinksList(Entry->reference);
|
||||
if (!CurrentList)
|
||||
{
|
||||
LogError("Error, can't find active process list offset, eprocess:%p", Process);
|
||||
LogWarning("Error, can't get active process links list, eprocess:%p", Entry->reference);
|
||||
return;
|
||||
}
|
||||
|
||||
CurrentList = (PLIST_ENTRY)((ULONG_PTR)Process + eprocListOffset);
|
||||
|
||||
// We use g_activeProcListLock to sync our modification inside hidden and raise
|
||||
// IRQL to disable special APC's because we want to minimize a BSOD chance because
|
||||
// of lack of the ActiveProcessLinks syncronization
|
||||
|
@ -279,31 +231,30 @@ VOID LinkProcessFromList(PLIST_ENTRY Current, PLIST_ENTRY Target)
|
|||
|
||||
VOID LinkProcessToActiveProcessLinks(PProcessTableEntry Entry)
|
||||
{
|
||||
PEPROCESS Process = Entry->reference;
|
||||
ULONG eprocListOffset = 0;
|
||||
PLIST_ENTRY CurrentList = NULL, TargetList = NULL;
|
||||
PEPROCESS System;
|
||||
NTSTATUS status;
|
||||
|
||||
if (!FindActiveProcessLinksOffset(Process, &eprocListOffset))
|
||||
{
|
||||
LogWarning("Warning, can't find active process list offset, eprocess:%p", Process);
|
||||
return;
|
||||
}
|
||||
|
||||
status = PsLookupProcessByProcessId(SYSTEM_PROCESS_ID, &System);
|
||||
if (!NT_SUCCESS(status))
|
||||
{
|
||||
LogWarning("Warning, can't find active system process");
|
||||
LogWarning("Error, can't find active system process");
|
||||
return;
|
||||
}
|
||||
|
||||
CurrentList = (PLIST_ENTRY)((ULONG_PTR)Process + eprocListOffset);
|
||||
TargetList = (PLIST_ENTRY)((ULONG_PTR)System + eprocListOffset);
|
||||
CurrentList = GetActiveProcessLinksList(Entry->reference);
|
||||
TargetList = GetActiveProcessLinksList(System);
|
||||
|
||||
KeAcquireGuardedMutex(&g_activeProcListLock);
|
||||
LinkProcessFromList(CurrentList, TargetList);
|
||||
KeReleaseGuardedMutex(&g_activeProcListLock);
|
||||
if (CurrentList && TargetList)
|
||||
{
|
||||
KeAcquireGuardedMutex(&g_activeProcListLock);
|
||||
LinkProcessFromList(CurrentList, TargetList);
|
||||
KeReleaseGuardedMutex(&g_activeProcListLock);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogWarning("Error, can't get active process links list, eprocess:%p,%p", Entry->reference, System);
|
||||
}
|
||||
|
||||
ObDereferenceObject(System);
|
||||
}
|
||||
|
|
|
@ -72,7 +72,7 @@
|
|||
- Поддержка case-sensetive путей на Windows 10
|
||||
- Реализовать сокрытие процессов
|
||||
+ Сделать видимыми скрытые процессы после выгрузки и /unhide
|
||||
- Улучшить алгоритм поиска офсета
|
||||
+ Улучшить алгоритм поиска офсета
|
||||
+ Добавить конфигурацию в реестр
|
||||
- Реализовать скрытие процесса из PspCidTable
|
||||
- Добавить сокрытие потоков из PspCidTable
|
||||
|
|
Loading…
Reference in New Issue