模块功能
添加当前模块大概功能的描述,希望不要把所有接口文档写在一个文件中,至少按模块分类。
- 列表
- 点击列表添加颜色
- 右键某一列内容出现菜单
代码实现
```cppinclude “dialog_main.h”
include
include “dialog_pe.h”
include “dialog_about.h”
include “pe_tool.h”
// MAIN Dialog 消息处理函数 BOOL CALLBACK DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { BOOL result = TRUE; switch (uMsg) { case WM_INITDIALOG: // 对话框初始化消息 InitListViewProcess(hwndDlg); // 初始化Process ListCtrl InitListViewModules(hwndDlg); // 初始化Modules ListCtrl g_hwndMain = hwndDlg; break;
case WM_CLOSE:
// 处理窗口关闭消息
EndDialog(hwndDlg, 0);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_COMMAND:
// 子控件消息处理
switch (LOWORD(wParam))
{
case IDC_BUTTON_EXIT:
EndDialog(hwndDlg, 0);
break;
case IDC_BUTTON_ABOUT:
DialogBox(g_hInstance, MAKEINTRESOURCE(IDD_DIALOG_ABOUT), hwndDlg, DialogAboutProc);
break;
case IDC_BUTTON_PE:
ShowPeDialog();
// PE对话框
break;
default:
result = FALSE;
}
case WM_NOTIFY:
{
NMHDR *pNmhdr = (NMHDR*)lParam;
if (wParam == IDC_LIST_PROCESS && pNmhdr->code == NM_CLICK)
{
InitListContentModule();
}
else if (wParam == IDC_LIST_MODULES && pNmhdr->code == NM_DBLCLK)
{
CopyModulePath();
}
}
default:
result = FALSE;
}
return result;
}
void InitListViewProcess(HWND hwndDlg) { LV_COLUMN lv = { 0 }; HWND hwndList;
// 获取句柄
hwndList = GetDlgItem(hwndDlg, IDC_LIST_PROCESS);
// 设置整行选中
SendMessage(hwndList, LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_FULLROWSELECT, LVS_EX_FULLROWSELECT);
lv.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;
// 第一列
lv.pszText = TEXT("进程名");
lv.cx = 180;
lv.iSubItem = 0;
ListView_InsertColumn(hwndList, 0, &lv);
// 第二列
lv.pszText = TEXT("PID");
lv.cx = 50;
lv.iSubItem = 1;
ListView_InsertColumn(hwndList, 1, &lv);
// 第三列
lv.pszText = TEXT("镜像地址");
lv.cx = 80;
lv.iSubItem = 2;
ListView_InsertColumn(hwndList, 2, &lv);
// 第四列
lv.pszText = TEXT("镜像大小");
lv.cx = 80;
lv.iSubItem = 3;
ListView_InsertColumn(hwndList, 3, &lv);
// 遍历进程列表
InitListContentProcess(hwndList);
g_hwndListProcess = hwndList;
}
void InitListViewModules(HWND hwndDlg) {
LV_COLUMN lv = { 0 };
HWND hwndList;
// 获取句柄
hwndList = GetDlgItem(hwndDlg, IDC_LIST_MODULES);
// 设置整行选中
SendMessage(hwndList, LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_FULLROWSELECT, LVS_EX_FULLROWSELECT);
lv.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM;
// 第一列
lv.pszText = TEXT("模块名称");
lv.cx = 100;
lv.iSubItem = 0;
ListView_InsertColumn(hwndList, 0, &lv);
// 第二列
lv.pszText = TEXT("模块位置");
lv.cx = 300;
lv.iSubItem = 1;
ListView_InsertColumn(hwndList, 1, &lv);
g_hwndListModules = hwndList;
}
void InitListContentProcess(hwndList) { // 1. 取得所有进程 // 2. 获取进程信息(进程名称, 主模块ImageBase, 主模块ImageSize, 主模块EOP) // 3. 填充列表数据
//// 1. 获取所有进程ID
//DWORD processIds[1024] = { 0 };
//DWORD dwNumberOfIds = 0;
//if (GetAllProcessId(processIds, sizeof(processIds), &dwNumberOfIds) == FALSE)
//{
// MessageBox(g_hwndMain, TEXT("获取进程列表!"), TEXT("WARRING"), MB_OK);
// return;
//}
HANDLE lpSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (lpSnapshot == INVALID_HANDLE_VALUE)
{
MessageBox(g_hwndMain, TEXT("创建快照失败"), TEXT("ERROR"), MB_OK);
return;
}
PROCESSENTRY32 p32;
p32.dwSize = sizeof(p32);
BOOL pr = Process32First(lpSnapshot, &p32);
// 遍历所有进程
for (int row = 0; pr; row++)
{
// 进程ID
DWORD dwPid = p32.th32ProcessID;
// 进程名
LPTSTR name = p32.szExeFile;
// 主模块信息
MODULEINFO mi = { 0 };
BOOL miResult = FALSE;
miResult = GetMainModuleInfo(dwPid, &mi);
LV_ITEM vitem = { 0 };
vitem.mask = LVIF_TEXT;
vitem.iItem = row;
// 第一列(进程名)
vitem.pszText = name;
vitem.iSubItem = 0;
ListView_InsertItem(hwndList, &vitem);
// 第二列(PID)
TCHAR buffer[16];
wsprintf(buffer, TEXT("%d"), dwPid);
vitem.pszText = buffer;
vitem.iSubItem = 1;
ListView_SetItem(hwndList, &vitem);
if (miResult)
{
// 第三列(主模块基地址)
wsprintf(buffer, TEXT("%p"), mi.lpBaseOfDll);
vitem.pszText = buffer;
vitem.iSubItem = 2;
ListView_SetItem(hwndList, &vitem);
// 第四列(镜像大小)
wsprintf(buffer, TEXT("%p"), mi.SizeOfImage);
vitem.pszText = buffer;
vitem.iSubItem = 3;
ListView_SetItem(hwndList, &vitem);
}
pr = Process32Next(lpSnapshot, &p32);
}
}
void InitListContentModule() { // 1. 获取到进程的ID // 2. 遍历模块 // 3. 填充数据. 数据获取失败. 清空列表
DWORD dwRowId;
TCHAR szPid[0x20] = { 0 };
dwRowId = SendMessage(g_hwndListProcess, LVM_GETNEXTITEM, -1, LVNI_SELECTED);
if (dwRowId == -1)
{
return;
}
// 清空所有数据行
ListView_DeleteAllItems(g_hwndListModules);
// 获取PID
LV_ITEM lv = { 0 };
lv.iSubItem = 1;
lv.pszText = szPid;
lv.cchTextMax = 0x20;
SendMessage(g_hwndListProcess, LVM_GETITEMTEXT, dwRowId, (DWORD)&lv);
DWORD dwPid = StrToInt(szPid);
// 遍历模块
DWORD dwNumOfModules = 0;
BOOL bResult = FALSE;
HMODULE hModules[1024];
HANDLE hProcess;
bResult = GetAllModules(dwPid, hModules, 1024, &dwNumOfModules);
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);
if (bResult == FALSE || hProcess == NULL || dwNumOfModules == 0)
{
return;
}
// 填充所有行数据
for (int row = 0; row < dwNumOfModules; row++)
{
// 获取模块数据: 模块名称,模块地址
TCHAR strBaseName[1024] = { 0 };
TCHAR strFileName[1024] = { 0 };
GetModuleBaseName(hProcess, hModules[row], strBaseName, 1024);
GetModuleFileNameEx(hProcess, hModules[row], strFileName, 1024);
LV_ITEM vitem = { 0 };
vitem.mask = LVIF_TEXT;
vitem.iItem = row;
// 第一列(模块名称)
vitem.pszText = strBaseName;
vitem.iSubItem = 0;
ListView_InsertItem(g_hwndListModules, &vitem);
// 第二列(模块位置)
vitem.pszText = strFileName;
vitem.iSubItem = 1;
ListView_SetItem(g_hwndListModules, &vitem);
MODULEINFO mi;
if (GetModuleInformation(hProcess, hModules[row], &mi, sizeof(MODULEINFO)))
{
mi.lpBaseOfDll;
vitem.pszText = strFileName;
vitem.iSubItem = 1;
ListView_SetItem(g_hwndListModules, &vitem);
}
}
CloseHandle(hProcess);
}
void ShowPeDialog() { // 选择文件 // 加载PE
// 弹出文件选择器
TCHAR strFeFileExt[128] = TEXT("PE File(*.exe,*.dll,*.sys)\0*.exe;*.dll*;.sys\0") \
TEXT("All File(*.*)\0*.*\0\0");
TCHAR strFileName[256] = { 0 };
OPENFILENAMEW st = { 0 };
ZeroMemory(&st, sizeof(OPENFILENAME));
st.lStructSize = sizeof(OPENFILENAME);
st.Flags = OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST;
st.hwndOwner = g_hwndMain;
st.lpstrFilter = strFeFileExt;
st.lpstrFile = strFileName;
st.nMaxFile = MAX_PATH;
if (GetOpenFileName(&st) == FALSE)
{
SetStaticMessage(TEXT("未选择文件!"));
return;
}
//PVOID g_pFileBuffer = NULL;
//DWORD g_dwFileSize = 0;
if (ReadPeFile(strFileName, &g_pFileBuffer, &g_dwFileSize) == FALSE)
{
SetStaticMessage(TEXT("加载PE文件失败!"));
return;
}
TCHAR buf[1024];
wsprintf(buf, TEXT("已打开文件 %s"), strFileName);
SetStaticMessage(buf);
DialogBox(g_hInstance, MAKEINTRESOURCE(IDD_DIALOG_PE), g_hwndMain, DialogPeProc);
}
BOOL GetAllModules(DWORD dwPid, HMODULE pModuel, int nSize, DWORD dwNumOfModules) {
HANDLE hProcess;
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid);
if (hProcess == NULL)
{
return FALSE;
}
DWORD cbNeeded;
if (EnumProcessModules(hProcess, pModuel, nSize, &cbNeeded) == FALSE)
{
CloseHandle(hProcess);
return FALSE;
}
*dwNumOfModules = cbNeeded / sizeof(DWORD);
return TRUE;
}
BOOL GetAllProcessId(DWORD *pPids, DWORD cb, PDWORD lpNumberOfPids) { DWORD cbNeeded; if (!EnumProcesses(pPids, cb, &cbNeeded)) { return FALSE; }
*lpNumberOfPids = cbNeeded / sizeof(DWORD);
return TRUE;
}
BOOL GetMainModuleInfo(DWORD dwPid, MODULEINFO* mi) { HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid); if (hProcess == NULL) { return FALSE; }
HMODULE hModules[1];
DWORD cbNeeded;
if (EnumProcessModules(hProcess, hModules, sizeof(hModules), &cbNeeded) == FALSE)
{
CloseHandle(hProcess);
return FALSE;
}
MODULEINFO info;
DWORD cb;
if (GetModuleInformation(hProcess, hModules[0], &info, &cb) == FALSE)
{
CloseHandle(hProcess);
return FALSE;
}
*mi = info;
CloseHandle(hProcess);
return TRUE;
}
void SetStaticMessage(LPCTSTR str) { HWND hwndStatic = GetDlgItem(g_hwndMain, IDC_STATIC1); SetWindowText(hwndStatic, str); }
void CopyModulePath() {
DWORD dwRowId;
TCHAR strPath[4096] = { 0 };
dwRowId = SendMessage(g_hwndListModules, LVM_GETNEXTITEM, -1, LVNI_SELECTED);
if (dwRowId == -1)
{
return;
}
// 获取路径
LV_ITEM lv = { 0 };
lv.iSubItem = 1;
lv.pszText = strPath;
lv.cchTextMax = 4096;
SendMessage(g_hwndListModules, LVM_GETITEMTEXT, dwRowId, (DWORD)&lv);
TCHAR buf[1024];
wsprintf(buf, TEXT("已复制 %s"), strPath);
SetStaticMessage(buf);
CopyTextToClipboard(strPath, sizeof(TCHAR));
}
BOOL CopyTextToClipboard(LPCTSTR strText)
{
// 打开剪贴板
if (!OpenClipboard(NULL) || !EmptyClipboard())
{
SetStaticMessage(TEXT(“打开或清空剪切板出错”));
return;
}
HGLOBAL hMen;
// 分配全局内存
hMen = GlobalAlloc(GMEM_MOVEABLE, ((_tcslen(strText) + 1)*sizeof(TCHAR)));
if (!hMen)
{
SetStaticMessage(TEXT("分配全局内存出错!"));
// 关闭剪切板
CloseClipboard();
return;
}
// 把数据拷贝考全局内存中
// 锁住内存区
LPTSTR lpStr = (LPTSTR)GlobalLock(hMen);
// 内存复制
memcpy(lpStr, strText, ((_tcslen(strText))*sizeof(TCHAR)));
// 字符结束符
lpStr[_tcslen(strText)] = (TCHAR)0;
// 释放锁
GlobalUnlock(hMen);
// 把内存中的数据放到剪切板上
DWORD flag = sizeof(TCHAR) == 2 ? CF_UNICODETEXT : CF_TEXT;
SetClipboardData(CF_UNICODETEXT, hMen);
CloseClipboard();
return;
}
```