#include "stdafx.h" #include "PluginSettingsDlg.h" #include "2015RemoteDlg.h" #include "resource.h" #include "jsoncpp/json.h" #include #include #ifndef _WIN64 #ifdef _DEBUG #pragma comment(lib, "jsoncpp/jsoncppd.lib") #else #pragma comment(lib, "jsoncpp/jsoncpp.lib") #endif #else #ifdef _DEBUG #pragma comment(lib, "jsoncpp/jsoncpp_x64d.lib") #else #pragma comment(lib, "jsoncpp/jsoncpp_x64.lib") #endif #endif BEGIN_MESSAGE_MAP(CPluginSettingsDlg, CDialogLangEx) ON_BN_CLICKED(IDC_BTN_SAVE, &CPluginSettingsDlg::OnBnClickedBtnSave) ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST_PLUGINS, &CPluginSettingsDlg::OnLvnItemchangedListPlugins) END_MESSAGE_MAP() CPluginSettingsDlg::CPluginSettingsDlg(std::vector& dllList, CWnd* pParent) : CDialogLangEx(IDD_DIALOG_PLUGIN_SETTINGS, pParent) , m_DllList(dllList) , m_nSelectedIndex(-1) { } CPluginSettingsDlg::~CPluginSettingsDlg() { } void CPluginSettingsDlg::DoDataExchange(CDataExchange* pDX) { CDialogLangEx::DoDataExchange(pDX); DDX_Control(pDX, IDC_LIST_PLUGINS, m_listPlugins); DDX_Control(pDX, IDC_COMBO_RUNTYPE_P, m_comboRunType); DDX_Control(pDX, IDC_COMBO_CALLTYPE, m_comboCallType); DDX_Control(pDX, IDC_COMBO_MODE, m_comboMode); DDX_Control(pDX, IDC_EDIT_INTERVAL, m_editInterval); DDX_Control(pDX, IDC_EDIT_MAXCOUNT, m_editMaxCount); } BOOL CPluginSettingsDlg::OnInitDialog() { CDialogLangEx::OnInitDialog(); // 初始化列表控件 InitListCtrl(); // 初始化运行类型下拉框 m_comboRunType.InsertString(SHELLCODE, _TR("Shellcode")); m_comboRunType.InsertString(MEMORYDLL, _TR("内存DLL")); m_comboRunType.SetCurSel(MEMORYDLL); // 初始化调用方式下拉框 m_comboCallType.InsertString(CALLTYPE_DEFAULT, _TR("自动检测")); m_comboCallType.InsertString(CALLTYPE_IOCPTHREAD, _TR("IOCP线程")); m_comboCallType.InsertString(CALLTYPE_FRPC_CALL, _TR("自定义FRPC[不可用]")); m_comboCallType.InsertString(CALLTYPE_FRPC_STDCALL, _TR("标准FRPC[不可用]")); m_comboCallType.SetCurSel(CALLTYPE_DEFAULT); // 初始化调度模式下拉框 m_comboMode.InsertString(SCH_MODE_NONE, _TR("不自动执行")); m_comboMode.InsertString(SCH_MODE_STARTUP, _TR("启动执行")); m_comboMode.InsertString(SCH_MODE_DAILY, _TR("每日定时")); m_comboMode.InsertString(SCH_MODE_WEEKLY, _TR("每周定时")); m_comboMode.InsertString(SCH_MODE_MONTHLY, _TR("每月定时")); m_comboMode.InsertString(SCH_MODE_YEARLY, _TR("每年定时")); m_comboMode.InsertString(SCH_MODE_OFF, _TR("关闭执行")); m_comboMode.SetCurSel(SCH_MODE_NONE); // 加载配置 m_Configs = LoadPluginConfigs(); // 加载插件列表 LoadPluginsToList(); return TRUE; } void CPluginSettingsDlg::InitListCtrl() { m_listPlugins.SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES); m_listPlugins.InsertColumn(0, _TR("名称"), LVCFMT_LEFT, 120); m_listPlugins.InsertColumn(1, _TR("大小"), LVCFMT_RIGHT, 80); m_listPlugins.InsertColumn(2, _TR("运行类型"), LVCFMT_LEFT, 80); m_listPlugins.InsertColumn(3, _TR("调度模式"), LVCFMT_LEFT, 120); m_listPlugins.InsertColumn(4, _TR("MD5"), LVCFMT_LEFT, 220); GetDlgItem(IDC_STATIC_PLUGIN_SETTINGS)->SetWindowText(_TR("插件参数配置")); GetDlgItem(IDC_STATIC_PLUGIN_RUNTYPE)->SetWindowText(_TR("运行类型:")); GetDlgItem(IDC_STATIC_PLUGIN_CALLTYPE)->SetWindowText(_TR("调用方式:")); GetDlgItem(IDC_STATIC_PLUGIN_SCHEDULE)->SetWindowText(_TR("调度模式:")); GetDlgItem(IDC_STATIC_PLUGIN_INTERVAL)->SetWindowText(_TR("间隔(秒):")); GetDlgItem(IDC_STATIC_PLUGIN_COUNTER)->SetWindowText(_TR("最大次数:")); SetWindowText(_TR("插件设置")); } void CPluginSettingsDlg::LoadPluginsToList() { m_listPlugins.DeleteAllItems(); const char* runTypeNames[] = { "Shellcode", "内存DLL" }; const char* modeNames[] = { "不自动执行", "启动执行", "每日定时", "每周定时" }; int index = 0; for (const auto& dll : m_DllList) { if (!dll || !dll->Data) continue; // 获取 DllExecuteInfo const char* buf = (char*)(dll->Data->Buf()); if (dll->Data->length() < 1 + sizeof(DllExecuteInfo)) continue; const DllExecuteInfo* info = reinterpret_cast(buf + 1); // 查找或创建配置 PluginConfig* cfg = FindConfig(dll->Name); m_listPlugins.InsertItem(index, CString(dll->Name.c_str())); CString sizeStr; sizeStr.Format(_T("%d KB"), info->Size / 1024); m_listPlugins.SetItemText(index, 1, sizeStr); int runType = cfg ? cfg->RunType : info->RunType; int mode = cfg ? cfg->Mode : info->Schedule.Mode; m_listPlugins.SetItemText(index, 2, _TR(runTypeNames[runType < 2 ? runType : 0])); m_listPlugins.SetItemText(index, 3, _TR(modeNames[mode < 4 ? mode : 0])); m_listPlugins.SetItemText(index, 4, CString(info->Md5)); m_listPlugins.SetItemData(index, (DWORD_PTR)dll); index++; } } void CPluginSettingsDlg::OnLvnItemchangedListPlugins(NMHDR* pNMHDR, LRESULT* pResult) { LPNMLISTVIEW pNMLV = reinterpret_cast(pNMHDR); *pResult = 0; if (pNMLV->uNewState & LVIS_SELECTED) { m_nSelectedIndex = pNMLV->iItem; UpdateSelectedPluginInfo(); } } void CPluginSettingsDlg::UpdateSelectedPluginInfo() { if (m_nSelectedIndex < 0) return; DllInfo* dll = reinterpret_cast(m_listPlugins.GetItemData(m_nSelectedIndex)); if (!dll || !dll->Data) return; const char* buf = (char*)(dll->Data->Buf()); const DllExecuteInfo* info = reinterpret_cast(buf + 1); // 查找配置(如果有) PluginConfig* cfg = FindConfig(dll->Name); // 更新下拉框和编辑框 int runType = cfg ? cfg->RunType : info->RunType; int callType = cfg ? cfg->CallType : info->CallType; int mode = cfg ? cfg->Mode : info->Schedule.Mode; unsigned int interval = cfg ? cfg->Interval : info->Schedule.Config.Startup.Interval; unsigned char maxCount = cfg ? cfg->MaxCount : info->Schedule.MaxCount; m_comboRunType.SetCurSel(runType < 2 ? runType : 0); m_comboCallType.SetCurSel(callType < 4 ? callType : 0); m_comboMode.SetCurSel(mode < 4 ? mode : 0); CString str; str.Format(_T("%u"), interval); m_editInterval.SetWindowText(str); str.Format(_T("%u"), maxCount); m_editMaxCount.SetWindowText(str); } void CPluginSettingsDlg::OnBnClickedBtnSave() { if (m_nSelectedIndex < 0) { MessageBoxL(_T("请先选择一个插件"), _T("提示"), MB_ICONINFORMATION); return; } SaveCurrentPluginConfig(); SavePluginConfigs(m_Configs); // 刷新列表显示 LoadPluginsToList(); // 重新选中 m_listPlugins.SetItemState(m_nSelectedIndex, LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED); MessageBoxL(_T("配置已保存"), _T("提示"), MB_ICONINFORMATION); } void CPluginSettingsDlg::SaveCurrentPluginConfig() { if (m_nSelectedIndex < 0) return; DllInfo* dll = reinterpret_cast(m_listPlugins.GetItemData(m_nSelectedIndex)); if (!dll || !dll->Data) return; const char* buf = (char*)dll->Data->Buf(); const DllExecuteInfo* info = reinterpret_cast(buf + 1); // 查找或创建配置 PluginConfig* cfg = FindConfig(dll->Name); if (!cfg) { PluginConfig newCfg; newCfg.Name = dll->Name; m_Configs.push_back(newCfg); cfg = &m_Configs.back(); } cfg->Md5 = info->Md5; cfg->RunType = m_comboRunType.GetCurSel(); cfg->CallType = m_comboCallType.GetCurSel(); cfg->Mode = (unsigned char)m_comboMode.GetCurSel(); CString str; m_editInterval.GetWindowText(str); cfg->Interval = _ttoi(str); m_editMaxCount.GetWindowText(str); cfg->MaxCount = (unsigned char)_ttoi(str); // 更新 DllInfo 中的 Buffer(修改 DllExecuteInfo) DllExecuteInfo* infoMut = const_cast(info); infoMut->RunType = cfg->RunType; infoMut->CallType = cfg->CallType; infoMut->Schedule.Mode = cfg->Mode; infoMut->Schedule.Config.Startup.Interval = cfg->Interval; infoMut->Schedule.MaxCount = cfg->MaxCount; } PluginConfig* CPluginSettingsDlg::FindConfig(const std::string& name) { for (auto& cfg : m_Configs) { if (cfg.Name == name) { return &cfg; } } return nullptr; } std::string CPluginSettingsDlg::GetPluginConfigPath() { std::string dbPath = GetDbPath(); // 获取目录部分 size_t pos = dbPath.find_last_of("\\/"); std::string dir = (pos != std::string::npos) ? dbPath.substr(0, pos + 1) : ""; return dir + "plugins.json"; } std::vector CPluginSettingsDlg::LoadPluginConfigs() { std::vector configs; std::string path = GetPluginConfigPath(); std::ifstream file(path); if (!file.is_open()) { return configs; } Json::Value root; Json::CharReaderBuilder builder; std::string errors; if (!Json::parseFromStream(builder, file, &root, &errors)) { return configs; } if (!root.isArray()) { return configs; } for (const auto& item : root) { PluginConfig cfg; cfg.Name = item.get("name", "").asString(); cfg.Md5 = item.get("md5", "").asString(); cfg.RunType = item.get("runType", MEMORYDLL).asInt(); cfg.CallType = item.get("callType", CALLTYPE_IOCPTHREAD).asInt(); cfg.Mode = (unsigned char)item.get("mode", SCH_MODE_NONE).asInt(); cfg.Flags = (unsigned char)item.get("flags", 0).asInt(); cfg.Interval = item.get("interval", 0).asUInt(); cfg.MaxCount = (unsigned char)item.get("maxCount", 0).asInt(); if (!cfg.Name.empty()) { configs.push_back(cfg); } } return configs; } void CPluginSettingsDlg::SavePluginConfigs(const std::vector& configs) { std::string path = GetPluginConfigPath(); Json::Value root(Json::arrayValue); for (const auto& cfg : configs) { Json::Value item; item["name"] = cfg.Name; item["md5"] = cfg.Md5; item["runType"] = cfg.RunType; item["callType"] = cfg.CallType; item["mode"] = cfg.Mode; item["flags"] = cfg.Flags; item["interval"] = cfg.Interval; item["maxCount"] = cfg.MaxCount; root.append(item); } std::ofstream file(path); if (file.is_open()) { Json::StreamWriterBuilder builder; builder["indentation"] = " "; std::unique_ptr writer(builder.newStreamWriter()); writer->write(root, &file); } } void CPluginSettingsDlg::PatchDllList(std::vector& dllList) { std::vector configs = LoadPluginConfigs(); for (auto& dll : dllList) { if (!dll || !dll->Data) continue; // 查找对应的配置 PluginConfig* cfg = nullptr; for (auto& c : configs) { if (c.Name == dll->Name) { cfg = &c; break; } } if (!cfg) continue; // 更新 DllExecuteInfo char* buf = (char*)dll->Data->Buf(); if (dll->Data->length() < 1 + sizeof(DllExecuteInfo)) continue; DllExecuteInfo* info = reinterpret_cast(buf + 1); info->RunType = cfg->RunType; info->CallType = cfg->CallType; info->Schedule.Mode = cfg->Mode; info->Schedule.Flags = cfg->Flags; info->Schedule.Config.Startup.Interval = cfg->Interval; info->Schedule.MaxCount = cfg->MaxCount; } }