diff --git a/web/app/components/memshell/main-config-card.tsx b/web/app/components/memshell/main-config-card.tsx index 977a0ee7..ca91dd6c 100644 --- a/web/app/components/memshell/main-config-card.tsx +++ b/web/app/components/memshell/main-config-card.tsx @@ -2,6 +2,7 @@ import { ArrowUpRightIcon, AxeIcon, CommandIcon, + InfoIcon, NetworkIcon, ServerIcon, ShieldOffIcon, @@ -40,6 +41,11 @@ import { } from "@/components/ui/select"; import { Switch } from "@/components/ui/switch"; import { Tabs } from "@/components/ui/tabs"; +import { + Tooltip, + TooltipContent, + TooltipTrigger, +} from "@/components/ui/tooltip"; import { type MainConfig, type ServerConfig, @@ -359,7 +365,7 @@ export default function MainConfigCard({ )} /> -
+
- {t("common:debug")} +
+ {t("common:debug")} + + + + + +

{t("common:debug.description")}

+
+
+
)} /> @@ -388,7 +404,17 @@ export default function MainConfigCard({ onCheckedChange={field.onChange} /> - +
+ + + + + + +

{t("common:probe.description")}

+
+
+
)} /> @@ -404,7 +430,19 @@ export default function MainConfigCard({ onCheckedChange={field.onChange} /> - +
+ + + + + + +

{t("common:byPassJavaModule.description")}

+
+
+
)} /> @@ -420,9 +458,19 @@ export default function MainConfigCard({ onCheckedChange={field.onChange} /> - +
+ + + + + + +

{t("common:lambdaSuffix.description")}

+
+
+
)} /> @@ -438,7 +486,17 @@ export default function MainConfigCard({ onCheckedChange={field.onChange} /> - +
+ + + + + + +

{t("common:shrink.description")}

+
+
+
)} /> @@ -454,9 +512,19 @@ export default function MainConfigCard({ onCheckedChange={field.onChange} /> - +
+ + + + + + +

{t("common:staticInitialize.description")}

+
+
+
)} /> diff --git a/web/app/components/probeshell/main-config-card.tsx b/web/app/components/probeshell/main-config-card.tsx index 7cef8601..f96f1ae6 100644 --- a/web/app/components/probeshell/main-config-card.tsx +++ b/web/app/components/probeshell/main-config-card.tsx @@ -1,4 +1,4 @@ -import { ServerIcon } from "lucide-react"; +import { InfoIcon, ServerIcon } from "lucide-react"; import { useCallback, useEffect, useMemo } from "react"; import { FormProvider, type UseFormReturn } from "react-hook-form"; import { useTranslation } from "react-i18next"; @@ -22,6 +22,11 @@ import { SelectValue, } from "@/components/ui/select"; import { Switch } from "@/components/ui/switch"; +import { + Tooltip, + TooltipContent, + TooltipTrigger, +} from "@/components/ui/tooltip"; import type { ServerConfig } from "@/types/memshell"; import type { ProbeShellFormSchema } from "@/types/schema"; import { Separator } from "../ui/separator"; @@ -288,7 +293,7 @@ export default function MainConfigCard({ form, servers }: MainConfigCardProps) { const SwitchGroup = useMemo( () => ( -
+
- {t("debug")} +
+ {t("debug")} + + + + + +

{t("common:debug.description")}

+
+
+
)} /> @@ -317,7 +332,17 @@ export default function MainConfigCard({ form, servers }: MainConfigCardProps) { onCheckedChange={field.onChange} /> - +
+ + + + + + +

{t("common:byPassJavaModule.description")}

+
+
+
)} /> @@ -333,7 +358,17 @@ export default function MainConfigCard({ form, servers }: MainConfigCardProps) { onCheckedChange={field.onChange} /> - +
+ + + + + + +

{t("common:lambdaSuffix.description")}

+
+
+
)} /> @@ -349,7 +384,17 @@ export default function MainConfigCard({ form, servers }: MainConfigCardProps) { onCheckedChange={field.onChange} /> - +
+ + + + + + +

{t("common:shrink.description")}

+
+
+
)} /> @@ -365,9 +410,19 @@ export default function MainConfigCard({ form, servers }: MainConfigCardProps) { onCheckedChange={field.onChange} /> - +
+ + + + + + +

{t("common:staticInitialize.description")}

+
+
+
)} /> diff --git a/web/app/i18n/common/en.json b/web/app/i18n/common/en.json index 7027c1be..f31c59e1 100644 --- a/web/app/i18n/common/en.json +++ b/web/app/i18n/common/en.json @@ -2,10 +2,12 @@ "about": "About", "basicInfo": "BasicInfo", "byPassJavaModule": "BypassModule", + "byPassJavaModule.description": "JDK 9+ module system strictly restricts reflective defineClass calls. When enabled, automatically inserts Unsafe-based module bypass code into injector", "cancel": "Cancel", "copyLabelSuccess": "Copy {{label}} successfully", "copySuccess": "Copy successfully", "debug": "Debug Mode", + "debug.description": "When enabled, injector prints injection info to logs and memshell prints exception stack traces for troubleshooting. Recommended for local testing environments", "download": "Downlaod", "encryptor": "Encryptor", "feedback": "Feedback", @@ -28,7 +30,9 @@ "server": "Server", "serverVersion": "Server Version", "shrink": "Shrink", + "shrink.description": "Uses ASM SKIP_DEBUG to remove debug info. Recommended to enable", "staticInitialize": "StaticInitialize", + "staticInitialize.description": "Adds static code block to invoke constructor. Suitable for scenarios where vulnerability sink is Class.forName(name, true, classLoader) but cannot trigger newInstance", "toast.generateError": "Generation failed, {{error}}", "toast.generateSuccess": "Generation successful", "urlPattern": "URL Pattern", @@ -37,7 +41,9 @@ "version.updateAvailableTooltip": "Click to Open Github Release Page ( v{{currentVersion}} -> v{{latestVersion}})", "shellTool": "Shell Tool", "lambdaSuffix": "LambdaSuffix", + "lambdaSuffix.description": "Bypass active scanning device detection. When enabled, adds $Proxy0$$Lambda$1 suffix to injector and memshell class names to evade detection via whitelist mechanism", "probe": "Probe Mode", + "probe.description": "Used to verify memshell injection success in non-local environments. Embeds injector bytecode into probe shell. Note: Do not enable if echo is unsupported or fails", "advancedConfig": "Advanced Config", "commandTemplate": "Command Template", "commandTemplate.placeholder": "e.g., sh -c \"{command}\" 2>&1", diff --git a/web/app/i18n/common/zh-CN.json b/web/app/i18n/common/zh-CN.json index 29bd39b3..2bd58cc9 100644 --- a/web/app/i18n/common/zh-CN.json +++ b/web/app/i18n/common/zh-CN.json @@ -2,10 +2,12 @@ "about": "关于", "basicInfo": "基本信息", "byPassJavaModule": "绕过模块限制", + "byPassJavaModule.description": "JDK 9+ 模块化系统严格限制反射调用 defineClass。开启后会在注入器中自动插入使用 Unsafe 绕过模块限制的代码", "cancel": "取消", "copyLabelSuccess": "复制 {{label}} 成功", "copySuccess": "复制成功", "debug": "调试模式", + "debug.description": "开启后注入器会打印注入信息到业务日志,内存马会打印异常堆栈信息,便于排查问题。本地测试环境推荐开启", "download": "下载", "encryptor": "加密器", "feedback": "反馈", @@ -28,7 +30,9 @@ "server": "服务类型", "serverVersion": "服务版本", "shrink": "缩小字节码", + "shrink.description": "使用 ASM SKIP_DEBUG 去除调试信息,建议开启", "staticInitialize": "静态初始化", + "staticInitialize.description": "在类中添加静态代码块调用构造方法。适用于无法触发 newInstance 漏洞 sink 点为 Class.forName(name, true, classLoader) 的场景", "toast.generateError": "生成失败,{{error}}", "toast.generateSuccess": "生成成功", "urlPattern": "请求路径", @@ -37,7 +41,9 @@ "version.updateAvailableTooltip": "点击前往 GitHub Release ( v{{currentVersion}} -> v{{latestVersion}})", "shellTool": "内存马工具", "lambdaSuffix": "Lambda 类名后缀", + "lambdaSuffix.description": "绕过主动扫描设备检测。开启后会在注入器和内存马类名后添加 $Proxy0$$Lambda$1 后缀,利用白名单机制躲避检测", "probe": "回显模式", + "probe.description": "用于非本地环境下判断内存马注入是否成功。开启后会将注入器字节码放入回显马。注意:不支持回显或回显失败的场景请勿开启", "advancedConfig": "高级配置", "commandTemplate": "命令模板", "commandTemplate.placeholder": "例如:sh -c \"{command}\" 2>&1", diff --git a/web/app/routes/memshell.tsx b/web/app/routes/memshell.tsx index 8b40b14a..7942f53d 100644 --- a/web/app/routes/memshell.tsx +++ b/web/app/routes/memshell.tsx @@ -124,7 +124,7 @@ export default function MemShellPage() { return ( -
+
-
+