任务管理器的实现及源码

任务管理器

这是培训的第3个项目——任务管理器。
这个项目做起来比较坑爹,本人之前学的嵌入式的Linux的QT,有了先入为主的嫌疑所以在短短1个星期实在不能完完全全的投入到MFC的界面编辑方式,一个星期的时间在前期准备时试过在VS12上装上QT插件,但是感到用起来巨胃疼,于是乎只能用SDK写。

这是小弟的任务管理器中的模块功能任务管理器的实现及源码_第1张图片

其中遍历进程/模块/线程是通过截取时间片再通过 遍历MODULEENTRY32/THREADENTRY32/PROCESSENTRY32结构体得到详细信息。贴出遍历进程 + 杀死进程的模块代码:
bool bianlijincheng::jincheng(vector  &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)&也可以用管理员模式运行

任务管理器的实现及源码_第2张图片
运行时的图片
任务管理器的实现及源码_第3张图片
OVER 欢迎大神指导。

你可能感兴趣的:(SDK,sdk,源码,安全,汇编)