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