任務管理器
這是培訓的第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 歡迎大神指導。