模块功能
添加当前模块大概功能的描述,希望不要把所有接口文档写在一个文件中,至少按模块分类。
- 列表
- 点击列表添加颜色
- 右键某一列内容出现菜单
代码实现
```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++){// 进程IDDWORD 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);// 获取PIDLV_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;
}
```
