现在的位置: 首页 > 综合 > 正文

通过PspTerminateThreadByPointer结束进程

2013年05月02日 ⁄ 综合 ⁄ 共 6403字 ⁄ 字号 评论关闭

早前写的代码了,免得腐烂了,贴出来
这个思想是在读了PJF牛人 "终止进程内幕" 后才晓得
基本思想就是用户态将欲结束的进程PID传递到内核驱动,驱动通过PsLookupProcessByProcessId得到进程的EPROCESS结构,再通过EPROCESS结构找到线程的链表头,遍历这个链表,逐一调用PspTerminateThreadByPointer,将其一个一个的KILL掉
这里有三个问题:
1. EPROCESS 结构里面的 线程链表头的 OFFSET 在2000, XP 2003中不一样,所以要硬编码
#define THREAD_LIST_HEAD_OFFSET_XP 0x190
#define THREAD_LIST_HEAD_OFFSET_2K 0x270
#define THREAD_LIST_HEAD_OFFSET_2K3 0x180

#define THREAD_LIST_ENTRY_OFFSET_XP 0x22c
#define THREAD_LIST_ENTRY_OFFSET_2K 0x240
#define THREAD_LIST_ENTRY_OFFSET_2K3 0x224

2.如何获得PspTerminateThreadByPointer

// XP: nt!PsTerminateSystemThread -> GetPspTerminateThreadByPointer
// 2k: NtTerminateThread -> PspTerminateThreadByPointer

BOOL GetPspTerminateThreadByPointer()
{
    
char * PsTerminateSystemThreadAddr;
    
int iLen;
    DWORD dwAddr;
    
//pAddr;
     PNTPROC ServiceTable;
     DWORD NtTerminateThreadAddr;
     
char * pAddr;
    
if (dwThreadListHeadOffset == THREAD_LIST_HEAD_OFFSET_2K)
    
{
        ServiceTable 
= KeServiceDescriptorTable->ntoskrnl.ServiceTable;
        
        NtTerminateThreadAddr 
= *((PULONG)ServiceTable + NTTERMINATETHREAD_OFFSET_2K);
        pAddr  
= (char *)NtTerminateThreadAddr;
        
for (iLen=0;iLen<0xff;iLen++)
        
{
            
if (*pAddr == (char)0xff
                
&&*(pAddr+1== (char)0x75
                
&&*(pAddr+2== (char)0xfc
                
&&*(pAddr+8== (char)0x8b
                )
            
{
                pAddr 
+= 4;
                dwAddr 
= *(DWORD *)pAddr + (DWORD)pAddr +4;
                
//DbgPrint("PspTerminateThreadByPointer:: 0x%x ",dwAddr);
                PspTerminateThreadByPointer = dwAddr;
                
return TRUE;
                
//break;
            }

            pAddr
++;
        }

    }

    
else
    
{
        
        PsTerminateSystemThreadAddr
= (char *)PsTerminateSystemThread;
        __asm
        
{
            __emit 
0x90;
            __emit 
0x90;
        }

        
for (iLen=0;iLen<50;iLen++)
        
{
            
if (*PsTerminateSystemThreadAddr == (char)0xff
                
&& *(PsTerminateSystemThreadAddr+1== (char)0x75
                
&& *(PsTerminateSystemThreadAddr+2== (char)0x08
                )
            
{
                __asm
                
{
                    __emit 
0x90;
                    __emit 
0x90;
                }

                PsTerminateSystemThreadAddr 
+= 5;
                dwAddr 
= *(DWORD *)PsTerminateSystemThreadAddr + (DWORD)PsTerminateSystemThreadAddr +4;
                
                
//DbgPrint("PspTerminateThreadByPointer:: 0x%x ",dwAddr);
                PspTerminateThreadByPointer = dwAddr;
                
return TRUE;
                
//break;
            }

            PsTerminateSystemThreadAddr
++;
        }

    }

    
return FALSE;
}

3. 在2k下面需要得到 PsLockProcess 和 PsUnlockProcess ,不然调用PspTerminateThreadByPointer就要挂


//2K 下使用 ,NtTerminateThread -> PspTerminateThreadByPointer
BOOL GetLockProcessAddr()
{
    
char * PsTerminateSystemThreadAddr;
    
int iLen;
    DWORD dwAddr;
    
//pAddr;
     PNTPROC ServiceTable;
     DWORD NtTerminateThreadAddr;
     
char * pAddr;
     
     ServiceTable 
= KeServiceDescriptorTable->ntoskrnl.ServiceTable;
     
/*
     NtTerminateThreadAddr = *((PULONG)ServiceTable + NTTERMINATETHREAD_OFFSET_2K);
     pAddr  = (char *)NtTerminateThreadAddr;

     for (iLen = 0;iLen<0xff;iLen++)
     {
         //想不到windows竟然用硬编码来寻址..
            if (*pAddr == (char)0x2c
                &&*(pAddr+1) == (char)0x02
                &&*(pAddr+2) == (char)0x00
                &&*(pAddr+3) == (char)0x00
                )
            {
                pAddr += 5;
                dwAddr = *(DWORD *)pAddr + (DWORD)pAddr +4;
                DbgPrint("PsLockProcess :: 0x%x ",dwAddr);
                PsLockProcess = dwAddr;
                for (iLen = 0;iLen<0xff;iLen++)
                {
                    if (*pAddr == (char)0x2c
                        &&*(pAddr+1) == (char)0x02
                        &&*(pAddr+2) == (char)0x00
                        &&*(pAddr+3) == (char)0x00
                        )
                    {
                        pAddr += 5;
                        dwAddr = *(DWORD *)pAddr + (DWORD)pAddr +4;
                        DbgPrint("PsUnLockProcess :: 0x%x ",dwAddr);
                        PsUnLockProcess = dwAddr;
                        return TRUE;
                        //return dwAddr;
                        //break;
                    }
                    pAddr++;
                }
                //return dwAddr;
                //break;
            }
            pAddr++;
     }
    
*/

     
//DbgPrint("NtAssignProcessToJobObject中寻找");
     
//在NtTerminateThread 中没有找到
     
//NtAssignProcessToJobObject中寻找
     DWORD NtAssignProcessToJobObjectAddr = *((PULONG)ServiceTable + 0x12);
     pAddr  
= (char *)NtAssignProcessToJobObjectAddr;
     
     
for (iLen = 0;iLen<0xff;iLen++)
     
{
         
// 定位标志
         if (*pAddr == (char)0xcc
             
&&*(pAddr+1== (char)0x00
             
&&*(pAddr+2== (char)0x00
             
&&*(pAddr+3== (char)0x00
             
&&*(pAddr-6== (char)0xe4
             )
         
{
             
// 找到定位标志
             for (iLen = 0;iLen<0x30;iLen++)
             
{
                 __asm
                 
{
                     __emit 
0x90;
                     __emit 
0x90;
                 }

                 
//
                 if (*pAddr == (char)0xff
                     
&&*(pAddr+1== (char)0x75
                     
&&*(pAddr+2== (char)0xf4
                     
//&&*(pAddr+3) == (char)0x00
                     )
                 
{
                     pAddr 
+= 5;
                     dwAddr 
= *(DWORD *)pAddr + (DWORD)pAddr +4;
                     
//DbgPrint("PsLockProcess :: 0x%x ",dwAddr);
                     PsLockProcess = dwAddr;
                     
for (iLen = 0;iLen<0xff;iLen++)
                     
{
                         
if (*pAddr == (char)0xff
                             
&&*(pAddr+1== (char)0x75
                             
&&*(pAddr+2== (char)0xfc
                             
//&&*(pAddr+3) == (char)0x00
                             )
                         
{
                             pAddr 
+= 4;
                             dwAddr 
= *(DWORD *)pAddr + (DWORD)pAddr +4;
                             
//DbgPrint("PsUnLockProcess :: 0x%x ",dwAddr);
                             PsUnLockProcess = dwAddr;
                             
return TRUE;
                             
//return dwAddr;
                             
//break;
                         }

                         pAddr
++;

抱歉!评论已关闭.