您的位置:首页 > 其它

任务管理器的实现及源码

2015-09-24 19:43 375 查看
任务管理器

这是培训的第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 欢迎大神指导。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: