通过PspTerminateThreadByPointer结束进程

 

很早前写的代码了,免得腐烂了,贴出来
这个思想是在读了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
++;
                     }

                     
return FALSE;
                     
break;
                 }

                 pAddr
++;
             }

             
return FALSE;
            
break
         }

         pAddr
++;
     }

    
return FALSE;
}

4. 这些问题解决了就好办了


BOOL KillProcessByID(DWORD dwPid) 




    PLIST_ENTRY ListThread;
    PLIST_ENTRY ListThreadHead; 
    DWORD dwThreadAdd;
    DWORD dwExitState 
= 0xC00002EB;
    DWORD dwState;
    
//dwState = STATUS_SYSTEM_SHUTDOWN;
    DWORD dwAddress = GetProcessByID(dwPid);

    
if (!dwAddress)
    
{

        
return FALSE;
    }

    
    __asm
    
{
    CLI;                    
//dissable interrupt
    MOV EAX, CR0;            //move CR0 register into EAX
    AND EAX, NOT 10000H;    //disable WP bit 
    MOV CR0, EAX;            //write register back
    }


    ListThreadHead 
= ((PLIST_ENTRY)(dwAddress + dwThreadListHeadOffset));

    
if (dwThreadListHeadOffset == THREAD_LIST_HEAD_OFFSET_2K)
    
{
        
//Lock Process
        __asm
        
{
            
//push PsLockPollOnTimeout - 0;
            
//push PsLockWaitForever - 2;
            push 0;
            push KernelMode;
            push dwAddress;
            call PsLockProcess;
            mov dwState,eax;
        }

        
if (dwState != STATUS_SUCCESS)
        
{
            
//DbgPrint("failed!! ");
            
//__asm
            
//{
            
//    push dwAddress;
            
//    call PsUnLockProcess;
            
//}
            return FALSE;
        }
    
    }



    ListThread 
= ListThreadHead->Blink;
    
while (ListThread != ListThreadHead)
    
{
        
if (!MmIsAddressValid((char*)ListThread-dwThreadListEntryOffset))
        
{
            
if (dwThreadListHeadOffset == THREAD_LIST_HEAD_OFFSET_2K)
            
{
                
                
                __asm
                
{
                    push dwAddress;
                    call PsUnLockProcess;
                }

                
//return FALSE;

            }

            
//DbgPrint("MmIsAddressValid !!!!! ---- failed!! ");
            return FALSE;
        }

        
        dwThreadAdd 
= (DWORD)((char*)ListThread-dwThreadListEntryOffset);

        
//DbgPrint("Thread Address: 0x%x  ",dwThreadAdd);
        
//XP上的定义
        
//NTSTATUS
        
//00880 NTAPI
        
//00881 PspTerminateThreadByPointer(IN PETHREAD Thread,
        
//00882                             IN NTSTATUS ExitStatus,
        
//00883                             IN BOOLEAN bSelf)

        
//2K 下的定义
        
//NTSTATUS
        
//PspTerminateThreadByPointer(
        
//IN PETHREAD Thread,
        
//IN NTSTATUS ExitStatus
        
//)
        if (dwThreadListHeadOffset == THREAD_LIST_HEAD_OFFSET_2K)
        
{
            __asm
            
{
                
//push 0;
                push dwExitState;
                push dwThreadAdd;
                call PspTerminateThreadByPointer;
            }

        }

        
else
        
{
            __asm
            
{
                
//push 0;
                push dwExitState;
                push dwThreadAdd;
                call PspTerminateThreadByPointer;
            }

        }


        ListThread 
= ListThread->Blink;
    }

    
    
if (dwThreadListHeadOffset == THREAD_LIST_HEAD_OFFSET_2K)
    
{
        
// unlock process
        __asm
        
{
            push dwAddress;
            call PsUnLockProcess;
        }

    }

    
    __asm 
    
{
        MOV EAX, CR0;    
//move CR0 register into EAX
        OR EAX, 10000H; //enable WP bit 
        MOV CR0, EAX;    //write register back 
        STI;            //enable interrupt
    }

    
return TRUE;

}
 

5. 最后把一个初始化函数贴出来


BOOL MyGetVersion()
{
    ULONG MajorVersion;
    ULONG MinorVersion;
    MinorVersion 
= 0;
    MajorVersion 
= 0;
    PsGetVersion(
&MajorVersion,&MinorVersion,NULL,NULL);
    
if (MajorVersion == 5{
        
if (MinorVersion == 0{
            
//2K
            
//dwListOffset = LIST_ENTRY_OFFSET_2K;
            
//dwNameOffset = NAME_OFFSET_2K;
            
//dwStatusOffset = STATUS_OFFSET_2K;
            dwThreadListHeadOffset = THREAD_LIST_HEAD_OFFSET_2K;
            dwThreadListEntryOffset 
= THREAD_LIST_ENTRY_OFFSET_2K;
            
if (!GetLockProcessAddr())
            
{
                
return FALSE;
            }

        }

        
else if (MinorVersion == 1{
            
//XP
            
//dwListOffset = LIST_ENTRY_OFFSET_XP;
            
//dwNameOffset = NAME_OFFSET_XP;
            
//dwStatusOffset = STATUS_OFFSET_XP;
            dwThreadListHeadOffset = THREAD_LIST_HEAD_OFFSET_XP;
            dwThreadListEntryOffset 
= THREAD_LIST_ENTRY_OFFSET_XP;
        }

        
else if (MinorVersion == 2)
        
{
            
// 2K3
            dwThreadListHeadOffset = THREAD_LIST_HEAD_OFFSET_2K3;
            dwThreadListEntryOffset 
= THREAD_LIST_ENTRY_OFFSET_2K3;
        }

        
else
        
{
            
return FALSE;
        }

    }

    
else
    
{
        
return FALSE;
    }

    
return TRUE;
}

 

知道怎么杀的呢,就很好防止了,把PsLookupProcessByProcessId保护起来就对了..

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值