任務管理器的實現及源碼

任務管理器

這是培訓的第3個項目——任務管理器。
這個項目做起來比較坑爹,本人之前學的嵌入式的Linux的QT,有了先入爲主的嫌疑所以在短短1個星期實在不能完完全全的投入到MFC的界面編輯方式,一個星期的時間在前期準備時試過在VS12上裝上QT插件,但是感到用起來巨胃疼,於是乎只能用SDK寫。
吐舌頭

這是小弟的任務管理器中的模塊功能

其中遍歷進程/模塊/線程是通過截取時間片再通過 遍歷MODULEENTRY32/THREADENTRY32/PROCESSENTRY32結構體得到詳細信息。貼出遍歷進程 + 殺死進程的模塊代碼:
bool bianlijincheng::jincheng(vector <ProcessInfo> &m_vecProcessList)
{
	HANDLE hProcessSnap;         // 進程快照句柄
	HANDLE hProcess;         // 進程句柄
	PROCESSENTRY32  StcPe32 = {0};         // 進程快照信息
	StcPe32.dwSize = sizeof(PROCESSENTRY32);
	m_vecProcessList .clear();
	// 創建進程相關的快照句柄
	hProcessSnap= CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
	if (!hProcessSnap)
	{
		return 0;
	}
	// 通過進程快照句柄獲取第一個進程信息
	if (!Process32First(hProcessSnap,&StcPe32))
	{
		CloseHandle( hProcessSnap);
		return 0;
	}
	// 循環遍歷進程信息
	do 
	{
		ProcessInfo stcInfo = {0};       // 獲取進程映像路徑
		wcscpy_s(stcInfo.szProcess,StcPe32.szExeFile);  // 獲取優先級信息
		hProcess = OpenProcess( PROCESS_QUERY_INFORMATION,FALSE,StcPe32.th32ProcessID);
		if (hProcess)
		{
			stcInfo.dwPrinorityClass=GetPriorityClass(hProcess);//獲取進程優先級
			CloseHandle(hProcess);  //關閉句柄
		}
		// 獲取進程其他信息  ↓
		//
		stcInfo.dwPid        = StcPe32.th32ProcessID;
		stcInfo.dwPrinorityClass=StcPe32.pcPriClassBase;
		stcInfo.dwThreadCount= StcPe32.cntThreads;
		stcInfo.dwParentProcess= StcPe32.th32ParentProcessID;
		stcInfo.szProcess[MAX_PATH]=(WCHAR)StcPe32.szExeFile;
		stcInfo.NAME         =StcPe32.cntUsage;
		// 獲取的信息保存到向量中
		m_vecProcessList.push_back(stcInfo);
	} while (Process32Next(hProcessSnap,&StcPe32));
	// 關閉句柄退出函數
	CloseHandle(hProcessSnap);
	return 1;
}

下面來詳解一下模塊注入功能,先貼代碼
#pragma once
#include "stdafx.h"
#include "注入.h"

bool zhuru::injectDll (DWORD pid, const std::wstring & dllFullPath)
{
	HANDLE hProcess = OpenProcess (                    //打開進程
								PROCESS_CREATE_THREAD |
								PROCESS_VM_OPERATION |
								PROCESS_VM_WRITE,
								FALSE, pid);

	
	if (NULL == hProcess || INVALID_HANDLE_VALUE == hProcess)   //句柄是否有效
	{
		MessageBox(0,L"Invalid Handle !",0,0);
		return 0;
	}

	size_t size = (dllFullPath.length() + 1) * sizeof (wchar_t); //dll 路徑大小

	LPVOID addr = VirtualAllocEx (                               //分配空間
		hProcess, NULL, size,
		MEM_RESERVE | MEM_COMMIT,
		PAGE_EXECUTE_READWRITE);

	if (NULL == addr)
	{
		CloseHandle (hProcess);
		MessageBox(0,L"Allocate memory isn't successful !",0,0);
		return 0;
	}


	SIZE_T sizeWritten = 0;
	if (FALSE == WriteProcessMemory (                                    // 寫入dll的路徑
		hProcess, addr, dllFullPath.c_str(), size, &sizeWritten) || sizeWritten != size)
	{
		VirtualFreeEx (hProcess, addr, 0, MEM_RELEASE);
		CloseHandle (hProcess);
		MessageBox(0,L"Write dll's path fail !",0,0);
		return 0;
	}

	auto pLoadLibraryW = GetProcAddress (      //獲得LoadLibraryW的函數地址
		GetModuleHandleW (L"Kernel32.dll"),
		"LoadLibraryW");
	if (NULL == pLoadLibraryW)
	{
		VirtualFreeEx (hProcess, addr, 0, MEM_RELEASE);
		CloseHandle (hProcess);
		MessageBox(0,L"Get 'LoadLibraryW''s address fail !",0,0);
		return 0;
	}

	HANDLE hThread = CreateRemoteThread (             // 創建遠程線程 
		hProcess, NULL, 0,
		(LPTHREAD_START_ROUTINE) pLoadLibraryW, addr,
		0, NULL);
	if (NULL == hThread || INVALID_HANDLE_VALUE == hThread)   //句柄是否有效
	{
		VirtualFreeEx (hProcess, addr, 0, MEM_RELEASE);
		CloseHandle (hProcess);
		MessageBox(0,L"Create Remote Thread fail !",0,0);
		return 0;
	}

	if (WAIT_OBJECT_0 != WaitForSingleObject (hThread, 1000000))  //等待一秒 
	{
		CloseHandle(hThread);
		VirtualFreeEx (hProcess, addr, 0, MEM_RELEASE);
		CloseHandle (hProcess);
		MessageBox(0,L"Warning ! Too much time to inject!",0,0);
		return 0;
	}


	DWORD exitCode =0;               //獲得線程的退出碼
	if (FALSE == GetExitCodeThread (hThread, &exitCode))   //如果沒有成功獲得退出碼 
	{
		CloseHandle(hThread);
		VirtualFreeEx (hProcess, addr, 0, MEM_RELEASE);
		CloseHandle (hProcess);
		MessageBox(0,L"Get ExitCode fail",0,0);
		return 0;
	}

	if (0 == exitCode)              //退出碼是0 注入失敗
	{
		CloseHandle(hThread);
		VirtualFreeEx (hProcess, addr, 0, MEM_RELEASE);
		CloseHandle (hProcess);
		MessageBox(0,L"Injecting worse",0,0);
		return 0;
	}
	
	CloseHandle(hThread);
	VirtualFreeEx (hProcess, addr, 0, MEM_RELEASE);
	CloseHandle (hProcess);
	MessageBox(0,L"Inject successfully !",0,0);
	return 1;


}

其實也沒什麼可“詳解”的,一句話創建遠程線程實現注入功能尷尬下面是卸載模塊
#pragma once
#include "stdafx.h"
#include "卸載dll.h"

bool DeleDll::deledll(DWORD pid, HANDLE D_handle)
{
		HANDLE hProcess = NULL;
		HANDLE hThread = NULL;
		PTHREAD_START_ROUTINE pfnThreadRtn;
		// 1. 獲取目標進程的句柄
		if (!(hProcess = OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_CREATE_THREAD|PROCESS_VM_OPERATION,FALSE,pid)) ) 
			return false;
		// 2.獲得FreeLibrary
		pfnThreadRtn = (PTHREAD_START_ROUTINE)GetProcAddress(
			GetModuleHandle(TEXT("Kernel32")), //模塊句柄
			"FreeLibrary"); //函數名
		if(!pfnThreadRtn)
		{
			CloseHandle(hProcess);
			return false;
		}
		// 3.創建遠程進程
		hThread = CreateRemoteThread(hProcess,NULL,0,pfnThreadRtn,D_handle,0,NULL);
		if(!hThread)
		{
			CloseHandle(hProcess);
			return false;
		}
		// 4.等待遠程線程終止
		WaitForSingleObject(hThread, INFINITE);
		// 5.釋放相關資源並關閉句柄
		if(hThread) CloseHandle(hThread);
		if(hProcess) CloseHandle(hProcess);
		return 1;
}

這段代碼其中兼容性有問題在項目講解時的教師機就無法卸載哭(求大神指出BUG)&也可以用管理員模式運行

運行時的圖片
OVER 歡迎大神指導。

發佈了33 篇原創文章 · 獲贊 10 · 訪問量 5萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章