通过PspTerminateThreadByPointer结束进程

Win64 驱动内核编程-26.强制结束进程 强制结束进程     依然已经走到驱动这一层了,那么通常结束掉一个进程不是什么难的事情。同时因为win64 位的各种保护,导致大家慢慢的已经不敢HOOK了,当然这指的是产品。作为学习和破解的话当然可以尝试各种hook。目前来说很多杀软进程保护都是通过回调了保护的,简单,稳定,安全。So,强制结束进程会比当年简单很多。 首先就是上一个最基本的驱动里结束进程的方法:   1.直接调用ZwTer 阅读详情

 

很早前写的代码了,免得腐烂了,贴出来
这个思想是在读了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保护起来就对了..

加载驱动进程防杀的软件源码 加载驱动进程防杀本人精心收集的VB源码,绝对实用 立即下载

相关推荐

python代码爬取大众点评评论!直接copy就可以运行!

python代码爬取大众点评评论!直接copy就可以运行!

QiuQiRuQin的博客 1万+

驱动开发:内核强制结束进程运行

内核态,但有时我们不得不想办法结束掉这些特殊的进程,当然某些正常进程在特殊状态下也会无法被正常结束,此时使用驱动前行在内核态将其结束掉就变得很有用了,驱动结束进程有多种方法。存在时则可以看到结束效果,当然这种方式只是在内核层面调用了结束进程函数,其本质上还是正常结束,只是这种方式权限要大一些仅此而已。没有被导出,所以我们需要动态的这个内存地址,然后动态调用即可,这个寻找方法可以总结为以下步骤。第二种方法,其原理就是将进程内的线程全部结束掉从而让进程自动结束,由于。首先是第一种方法结束进程,封装实现。

微软技术分享 1万+

[Dify] -进阶13- 使用“知识库 + 工作流”打造智能推荐系统

本文介绍了在Dify平台上构建智能推荐系统的方法,重点阐述了知识库与工作流技术的结合应用。通过知识库管理RAG流程,实现文档上传、向量嵌入和检索优化;利用工作流设计节点化推荐逻辑,支持并行处理与条件分支。以电话销售话术推荐为例,展示了从数据收集到实时生成的完整流程。该方法具有准确性高、扩展性强、维护简便等优势,可广泛应用于各类推荐场景,实现从数据存储到智能推荐的闭环解决方案。

技术小甜甜:传播可落地技术,帮助个人和企业降低解决真实场景问题的成本 1041

使用 PspTerminateThreadByPointer 强制结束进程

实现过程 我们知道,线程是进程中执行运算的最小单位,是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,只拥有一点在运行中必不可少的资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源。一个线程可以创建和撤消另一个线程,同一进程中的多个线程之间可以并发执行。 也就是说,当一个进程中的所有线程都被结束的时候,这个进程也就没有了存在的意义,也随之结束了。这,便是我们本文介绍的这种强制杀进程的实现原理,即把进程中的线程都杀掉,从而让进程消亡,实现间接杀进程的效果。 Windows

LYSM 2451

使用PsTerminateThreadByPointer强制结束进程

该函数会在内部检查是否是系统线程,如果是系统线程不会结束它. #include<ntifs.h> #include <ntddk.h> //根据进程结构获得进程名指针 需要自己申明一下。 ULONG64 g_kernelModuleBase = 0; typedef struct _LDR_DATA_TABLE_ENTRY { LIST_ENTRY InLoadOrderLinks; LIST_ENTRY InMemoryOrderLinks; LIST_ENTRY I

qq_41490873的博客 656

 进程和线程的结束

进程和线程的结束 在执行体层,线程的终止函数是NtTerminateThread,内部调用PspTerminateThreadByPointer完成终止处理。系统线程的终止函数是PsTerminateSystemThread,内部调用 PspTerminateThreadByPointer完成终止处理。 三个函数原型如下: NTSTATUS NtTerminateThread( _in_opt HANDLE ThreadHandle, _in NTSTATUS ExitStatus); N.

maomao171314的专栏 985

浅谈驱动中强制结束进程的3种方法

一个应用程序想要结束另一个进程所要做的事:首先获得目标的进程ID,接着利用OpenProcess获取进程句柄(确保足够权限),最后将句柄传给TerminateProcess了结那个进程. OpenProcess通过本机系统服务接口进入核心态,随后调用ntoskrnl的NtOpenProcess.在服务函数里,系统使用SeSinglePrivilegeCheck检查调用者是否有DEBUG权

少仲 7286

驱动 -- 强制结束进程 -- 整理

有一阵子没 写博客,正好这几天 写了个内核级强制结束进程 的小例子。写这个例子之前都没去查什么资料,主要是想试试自己能不能写出来吧。写完后才发现 看雪论坛 曾经发表过一篇很相似的文章,实现的细节可能有点不一样,不过原理基本是相同的了。 都是通过 这个 PspTerminateThreadByPointer 函数,我是通过查ReactOs 来理解的 NtTeriminateProc

FadeTrack 2557

强制进程结束(内核函数)

windows给我们结束进程的函数是PsTerminateSystemThread function,通过反汇编我们可以看到PsTerminateSystemThread 调用了未导出的函数PspTerminateThreadByPointer ,然后这个函数又调用了APC和PspExitThread函数对进程实现强制结束。 ...

mmmsss987的博客 1369

模拟PspTerminateProcess结束进程-学习笔记

此文是阅读黑防上胡文亮大牛《模拟实现NT系统通用PspTerminateProcess》后作为学习笔记记录下来的,仅作学习记录,理解错的请勿拍砖。和通过特征暴力搜索定位PspTerminateProcess的地址的方法相比,亮点就是模拟了实现PspTerminateProcess,PspTerminateThreadByPointer等函数。 此前先看PJF大牛的一篇《进程终止的内幕》

求索 2402

PsTerminateProcess结束进程

PsTerminateProcess函数用于结束一个进程,其声明如下 NTSTATUS NTAPI PsTerminateProcess(IN PEPROCESS Process, IN NTSTATUS ExitStatus) 其中第一个参数是PEPROCESS的指针,如果你只知道pid,可以通过PsLookupProcessByProcessId 获得,而第二个参数指定退出状...

weixin_30781433的博客 407

两个强制结束进程的方法

这两个函数分别用于终止进程和线程,但由于未公开导出,需要通过逆向工程获取地址。

(*/ω\*) 1378

C++强杀进程,可结束IceSword

核心代码:#include #define NT_DEVICE_NAME                    L"//Device//KillProcess"#define DOS_DEVICE_NAME          L"//DosDevices//KillProcess"UNICODE_STRING                                         Devi

xinew的专栏 1050

code:插APC杀进程

apc

Richard的专栏 2500

进程和线程的创建过程

http://book.douban.com/annotation/28879242/

fyfy 2463

进程与线程(八)进程保护(1) && 驱动逆向初步

INIT:00010D85 public start INIT:00010D85 start proc near INIT:00010D85 mov edi, edi INIT:00010D87 push ebp INIT:00010D88

Returns' Station 1246

pspcidtable杂谈

今天再次看了gz1X牛的文章,回忆了许多知识. 哈哈. 玩了很长时间游戏,写点儿文字算是对自责的一种安慰 要说R0枚举隐藏进程, 只是对没有抹掉PspCidTable而言的.gz1X牛提示了2种方法:Quote::1. 利用未导出的ExEnumHandleTable函数2. 获取PHANDLE_TABLE_ENTRY等,然后PsLookupProcessByProcessId 偶觉得都

yaneng的专栏 1715
上一篇: 绕过安全软件挂钩SSDT的检测
下一篇: [讨论]关于缓冲区溢出的检测
galihoo
博客等级 码龄22年 14粉丝 14原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值