手机沙箱实验台
by EpicCoder88872 lines58.3 KB
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>手机沙箱实验台</title>
<style>
* { box-sizing: border-box; margin: 0; padding: 0; }
:root { --bg:#0a0e14; --panel:#161b22; --border:#30363d; --text:#e6edf3; --text-dim:#8b949e; --accent:#58a6ff; --green:#3fb950; --red:#f85149; --purple:#bc8cff; --radius:14px; --radius-sm:8px; --mono: ui-monospace, "SF Mono", Menlo, Consolas, monospace; }
html, body { height:100%; font-family: -apple-system, "PingFang SC", "Microsoft YaHei", sans-serif; background: radial-gradient(circle at 50% 30%, #1a2332 0%, #0a0e14 70%); color: var(--text); overflow: hidden; }
.workbench { display:flex; height:100vh; padding:14px; gap:16px; align-items:center; justify-content:center; }
.phone { position:relative; flex-shrink:0; width:380px; height:780px; background:linear-gradient(145deg,#2e2e32 0%,#1c1c1e 50%,#2e2e32 100%); border-radius:56px; padding:11px; box-shadow:inset 0 0 0 2px rgba(255,255,255,.08),inset 0 0 0 3px rgba(0,0,0,.5),0 0 0 1px rgba(0,0,0,.8),0 30px 70px rgba(0,0,0,.75); display:flex; flex-direction:column; align-self:center; transition:box-shadow .3s; }
.phone.remote-active { box-shadow: inset 0 0 0 2px #ef4444, 0 30px 70px rgba(239,68,68,.4); animation: remotePulse 1s infinite; }
@keyframes remotePulse { 0%,100% { box-shadow: inset 0 0 0 2px #ef4444, 0 30px 70px rgba(239,68,68,.4); } 50% { box-shadow: inset 0 0 0 2px rgba(239,68,68,.4), 0 30px 70px rgba(239,68,68,.15); } }
.phone-screen { flex:1; position:relative; background:#000; border-radius:46px; overflow:hidden; display:flex; flex-direction:column; }
.dynamic-island { position:absolute; top:12px; left:50%; transform:translateX(-50%); width:105px; height:30px; background:#000; border-radius:20px; z-index:100; }
.dynamic-island::before { content:""; position:absolute; right:14px; top:50%; transform:translateY(-50%); width:10px; height:10px; border-radius:50%; background: radial-gradient(circle at 35% 35%, #1a3a5a 0%, #050810 60%); }
.status-bar { height:56px; display:flex; align-items:center; justify-content:space-between; padding:18px 28px 0; color:#fff; font-size:14px; font-weight:600; flex-shrink:0; pointer-events:none; }
.status-time { font-variant-numeric: tabular-nums; }
.status-icons { display:flex; align-items:center; gap:6px; }
.signal-icon { display:flex; align-items:flex-end; gap:2px; height:11px; }
.signal-icon span { width:3px; background:#fff; border-radius:1px; }
.signal-icon span:nth-child(1){height:4px;} .signal-icon span:nth-child(2){height:6px;} .signal-icon span:nth-child(3){height:8px;} .signal-icon span:nth-child(4){height:10px;}
.battery-icon { width:25px; height:12px; border:1.5px solid rgba(255,255,255,.9); border-radius:3.5px; position:relative; padding:1.5px; }
.battery-icon::after { content:""; position:absolute; right:-3.5px; top:50%; transform:translateY(-50%); width:2px; height:5px; background:rgba(255,255,255,.9); border-radius:0 2px 2px 0; }
.battery-fill { height:100%; background:#fff; border-radius:1.5px; width:78%; }
.screen-body { flex:1; position:relative; overflow:hidden; }
.home-screen { position:absolute; inset:0; z-index:1; transition:opacity .45s, transform .45s; }
.home-screen.hidden { opacity:0; transform:scale(.88); pointer-events:none; }
.wallpaper { position:absolute; inset:0; background: radial-gradient(ellipse at 30% 20%, rgba(88,100,200,.75) 0%, transparent 55%), radial-gradient(ellipse at 75% 70%, rgba(180,80,200,.6) 0%, transparent 55%), radial-gradient(ellipse at 85% 25%, rgba(60,120,200,.55) 0%, transparent 45%), radial-gradient(ellipse at 15% 85%, rgba(120,60,180,.55) 0%, transparent 45%), linear-gradient(180deg, #0a0e2a 0%, #1a1a3e 50%, #0d0518 100%); }
.wallpaper::after { content:""; position:absolute; inset:0; background: radial-gradient(circle at 50% 40%, transparent 30%, rgba(0,0,0,.35) 100%); }
.home-content { position:relative; z-index:2; height:100%; display:flex; flex-direction:column; padding:20px 26px 30px; overflow-y:auto; }
.home-content::-webkit-scrollbar { display:none; }
.home-greeting { padding:14px 6px 26px; color:#fff; }
.greeting-time { font-size:58px; font-weight:200; letter-spacing:-2px; line-height:1; font-variant-numeric: tabular-nums; text-shadow: 0 2px 20px rgba(0,0,0,.4); }
.greeting-date { font-size:15px; font-weight:500; opacity:.85; margin-top:6px; }
.app-grid { display:grid; grid-template-columns:repeat(4,1fr); gap:22px 16px; padding:0 4px; }
.app { display:flex; flex-direction:column; align-items:center; gap:8px; background:transparent; border:none; cursor:pointer; padding:0; font-family:inherit; color:#fff; }
.app-icon { width:62px; height:62px; border-radius:16px; display:flex; align-items:center; justify-content:center; font-size:28px; position:relative; overflow:hidden; box-shadow: 0 4px 12px rgba(0,0,0,.3), inset 0 0 0 1px rgba(255,255,255,.15); transition: transform .15s; }
.app-icon::before { content:""; position:absolute; top:0; left:0; right:0; height:50%; background: linear-gradient(180deg, rgba(255,255,255,.22), transparent); pointer-events:none; }
.app:active .app-icon { transform:scale(.88); filter:brightness(.75); }
.app-name { font-size:11.5px; font-weight:500; text-shadow: 0 1px 3px rgba(0,0,0,.5); }
.icon-red{background:linear-gradient(160deg,#ff5b5b,#d92727);} .icon-blue{background:linear-gradient(160deg,#5ba4ff,#1c6cd9);}
.icon-purple{background:linear-gradient(160deg,#b98cff,#7c3aed);} .icon-green{background:linear-gradient(160deg,#4ee08b,#17a05a);}
.icon-orange{background:linear-gradient(160deg,#ffb15b,#d9771c);} .icon-slate{background:linear-gradient(160deg,#94a3b8,#475569);}
.dock { margin-top:auto; display:grid; grid-template-columns:repeat(4,1fr); gap:16px; padding:12px 16px; background:rgba(255,255,255,.14); backdrop-filter: blur(24px); border-radius:26px; border:1px solid rgba(255,255,255,.12); }
.dock .app-icon { width:54px; height:54px; font-size:24px; margin:0 auto; }
.dock .app-name { display:none; }
.page-dots { display:flex; justify-content:center; gap:6px; padding:14px 0 6px; }
.page-dots span { width:6px; height:6px; border-radius:50%; background:rgba(255,255,255,.35); }
.page-dots span.active { background:#fff; }
.app-view { position:absolute; inset:0; z-index:5; display:flex; flex-direction:column; background:#0a0e1a; opacity:0; transform:scale(1.08); pointer-events:none; transition: opacity .4s, transform .4s; }
.app-view.active { opacity:1; transform:scale(1); pointer-events:auto; }
.app-view-header { height:52px; display:flex; align-items:center; justify-content:space-between; padding:8px 12px 0; background:rgba(22,27,34,.95); color:#fff; font-size:14px; font-weight:600; flex-shrink:0; border-bottom:1px solid rgba(255,255,255,.06); }
.back-btn { display:flex; align-items:center; gap:3px; background:transparent; border:none; color:var(--accent); font-size:14px; font-weight:600; cursor:pointer; padding:6px 10px; border-radius:8px; font-family:inherit; }
.back-btn svg { width:12px; height:12px; }
.app-title { flex:1; text-align:center; font-size:14px; font-weight:600; color:#fff; }
.app-view-header .spacer { width:64px; }
.app-view-body { flex:1; position:relative; overflow:hidden; background:#fff; }
.app-view-body iframe { width:100%; height:100%; border:0; display:block; background:#fff; }
.home-indicator { position:absolute; bottom:8px; left:50%; transform:translateX(-50%); width:130px; height:5px; border-radius:3px; background:rgba(255,255,255,.9); z-index:200; pointer-events:none; }
.threat-banner { position:absolute; top:56px; left:12px; right:12px; z-index:9000; background: linear-gradient(135deg, #f85149, #a01c1c); color:#fff; padding:14px 16px; border-radius:14px; box-shadow: 0 8px 30px rgba(248,81,73,.5); display:none; align-items:center; gap:12px; }
.threat-banner.active { display:flex; animation: bannerIn .35s ease; }
@keyframes bannerIn { from{opacity:0;transform:translateY(-20px);} to{opacity:1;transform:translateY(0);} }
.threat-banner .tb-icon { font-size:28px; flex-shrink:0; animation: shake .4s infinite; }
@keyframes shake { 0%,100%{transform:rotate(0);} 25%{transform:rotate(-10deg);} 75%{transform:rotate(10deg);} }
.threat-banner .tb-info { flex:1; }
.threat-banner .tb-title { font-size:14px; font-weight:800; }
.threat-banner .tb-sub { font-size:11.5px; color:rgba(255,255,255,.85); }
.sidebar { flex:1; max-width:440px; height:100%; display:flex; flex-direction:column; gap:10px; min-width:0; }
.card { background:var(--panel); border:1px solid var(--border); border-radius:var(--radius); overflow:hidden; display:flex; flex-direction:column; min-height:0; }
.card-head { display:flex; align-items:center; justify-content:space-between; padding:10px 14px; border-bottom:1px solid var(--border); font-size:12px; font-weight:700; color:var(--text-dim); letter-spacing:.5px; text-transform:uppercase; flex-shrink:0; }
.card-head .badge { font-size:10px; font-weight:600; padding:2px 8px; border-radius:999px; background:rgba(88,166,255,.15); color:var(--accent); text-transform:none; }
.status-badge { display:inline-flex; align-items:center; gap:5px; font-size:10.5px; font-weight:600; padding:3px 9px; border-radius:999px; background:#1c2128; color:var(--text-dim); border:1px solid var(--border); text-transform:none; }
.status-badge .dot { width:6px; height:6px; border-radius:50%; background:var(--green); }
.status-badge.danger .dot { background:var(--red); }
.controls { padding:10px; display:flex; flex-wrap:wrap; gap:6px; }
.btn { display:inline-flex; align-items:center; gap:5px; padding:7px 12px; font-size:12.5px; font-weight:600; border:1px solid var(--border); border-radius:var(--radius-sm); background:#1c2128; color:var(--text); cursor:pointer; font-family:inherit; }
.btn:active { transform:scale(.97); }
.btn.primary{background:var(--accent);border-color:var(--accent);color:#fff;} .btn.green{background:var(--green);border-color:var(--green);color:#fff;}
.btn.red{background:var(--red);border-color:var(--red);color:#fff;} .btn.purple{background:var(--purple);border-color:var(--purple);color:#1a1a1a;}
.btn.orange{background:#d9771c;border-color:#d9771c;color:#fff;} .btn.slate{background:#475569;border-color:#475569;color:#fff;}
.btn.ghost{background:transparent;}
.logs-body { flex:1; overflow-y:auto; padding:8px 10px; font-family:var(--mono); font-size:11.5px; line-height:1.55; min-height:100px; }
.logs-body::-webkit-scrollbar { width:6px; } .logs-body::-webkit-scrollbar-thumb { background:#30363d; border-radius:3px; }
.log-item { display:flex; gap:6px; padding:4px 6px; border-radius:5px; margin-bottom:2px; }
.log-time { color:#484f58; flex-shrink:0; font-size:10.5px; padding-top:1px; }
.log-tag { flex-shrink:0; font-size:9.5px; font-weight:700; padding:2px 5px; border-radius:4px; height:fit-content; margin-top:1px; }
.log-tag.info{background:rgba(88,166,255,.15);color:var(--accent);} .log-tag.ok{background:rgba(63,185,80,.15);color:var(--green);}
.log-tag.warn{background:rgba(210,153,34,.15);color:#d29922;} .log-tag.error{background:rgba(248,81,73,.15);color:var(--red);}
.log-msg { color:var(--text); word-break:break-word; }
.editor-card { flex-shrink:0; }
.editor-body { padding:8px; display:flex; flex-direction:column; gap:6px; }
.editor-body textarea { width:100%; height:84px; resize:none; background:#0a0e14; color:var(--text); border:1px solid var(--border); border-radius:var(--radius-sm); padding:8px 10px; font-family:var(--mono); font-size:11.5px; line-height:1.55; outline:none; }
.editor-actions { display:flex; gap:6px; flex-wrap:wrap; }
@media (max-width:960px) {
.workbench { flex-direction:column; padding:10px; gap:10px; overflow-y:auto; height:auto; min-height:100vh; align-items:stretch; }
.phone { width:100%; max-width:360px; height:auto; aspect-ratio:9/19.5; max-height:70vh; margin:0 auto; padding:9px; border-radius:48px; }
.phone-screen { border-radius:40px; }
.greeting-time { font-size:48px; }
.app-icon { width:54px; height:54px; font-size:24px; border-radius:14px; }
.app-grid { gap:18px 12px; }
.sidebar { max-width:100%; height:auto; }
.logs-body { max-height:180px; }
}
</style>
</head>
<body>
<div class="workbench">
<div class="phone" id="phoneBody">
<div class="phone-screen">
<div class="dynamic-island"></div>
<div class="status-bar">
<span class="status-time" id="statusTime">9:41</span>
<span class="status-icons">
<div class="signal-icon"><span></span><span></span><span></span><span></span></div>
<svg width="16" height="12" viewBox="0 0 16 12" fill="none"><path d="M1 4 C 4 1.5, 12 1.5, 15 4" stroke="#fff" stroke-width="1.6" stroke-linecap="round"/><path d="M3.5 6.5 C 5.5 5, 10.5 5, 12.5 6.5" stroke="#fff" stroke-width="1.6" stroke-linecap="round"/><circle cx="8" cy="9.6" r="1.3" fill="#fff"/></svg>
<div class="battery-icon"><div class="battery-fill"></div></div>
</span>
</div>
<div class="screen-body">
<div class="threat-banner" id="threatBanner">
<div class="tb-icon">🚨</div>
<div class="tb-info"><div class="tb-title" id="tbTitle">AI 检测到威胁</div><div class="tb-sub" id="tbSub">正在处理...</div></div>
</div>
<div class="home-screen" id="homeScreen">
<div class="wallpaper"></div>
<div class="home-content">
<div class="home-greeting">
<div class="greeting-time" id="greetingTime">9:41</div>
<div class="greeting-date" id="greetingDate">10月2日 星期五</div>
</div>
<div class="app-grid">
<button class="app" data-app="test1" data-title="安全中心"><div class="app-icon icon-red">🛡</div><div class="app-name">安全中心</div></button>
<button class="app" data-app="test5" data-title="文件管理"><div class="app-icon icon-orange">📁</div><div class="app-name">文件管理</div></button>
<button class="app" data-app="test6" data-title="系统服务"><div class="app-icon icon-slate">⚙</div><div class="app-name">系统服务</div></button>
<button class="app" data-app="test2" data-title="浏览器"><div class="app-icon icon-blue">◐</div><div class="app-name">浏览器</div></button>
<button class="app" data-app="test3" data-title="影子空间"><div class="app-icon icon-purple">◈</div><div class="app-name">影子空间</div></button>
<button class="app" data-app="test4" data-title="文本阅读器"><div class="app-icon icon-green">¶</div><div class="app-name">文本阅读器</div></button>
</div>
<div class="page-dots"><span class="active"></span><span></span></div>
<div class="dock">
<button class="app" data-app="dock" data-title="电话"><div class="app-icon" style="background:linear-gradient(160deg,#5be05b,#17a05a);">☎</div></button>
<button class="app" data-app="dock" data-title="信息"><div class="app-icon" style="background:linear-gradient(160deg,#5be0d0,#17a0a0);">✉</div></button>
<button class="app" data-app="dock" data-title="相机"><div class="app-icon" style="background:linear-gradient(160deg,#666,#222);">◉</div></button>
<button class="app" data-app="dock" data-title="音乐"><div class="app-icon" style="background:linear-gradient(160deg,#ff5b8c,#d92760);">♪</div></button>
</div>
</div>
</div>
<div class="app-view" id="appView">
<div class="app-view-header">
<button class="back-btn" id="backBtn"><svg viewBox="0 0 12 20" fill="none"><path d="M10 2 L2 10 L10 18" stroke="currentColor" stroke-width="2.4" stroke-linecap="round"/></svg>返回</button>
<span class="app-title" id="appTitle">应用</span>
<span class="spacer"></span>
</div>
<div class="app-view-body"><iframe id="sandboxFrame" sandbox="allow-scripts allow-same-origin allow-downloads allow-forms"></iframe></div>
</div>
</div>
<div class="home-indicator"></div>
</div>
</div>
<div class="sidebar">
<div class="card">
<div class="card-head"><span>控制台</span><span class="status-badge" id="statusBadgeWrap"><span class="dot"></span><span id="statusBadge">沙箱就绪</span></span></div>
<div class="controls">
<button class="btn primary" id="btnReload">⟳ 重载</button>
<button class="btn red" id="btnTest1">安全中心</button>
<button class="btn orange" id="btnTest5">文件管理</button>
<button class="btn slate" id="btnTest6">系统服务</button>
<button class="btn red" id="btnTest2">浏览器</button>
<button class="btn purple" id="btnTest3">影子空间</button>
<button class="btn green" id="btnTest4">文本阅读器</button>
<button class="btn ghost" id="btnClearLog">清空日志</button>
</div>
</div>
<div class="card" style="flex:1;min-height:0;">
<div class="card-head"><span>运行日志</span><span class="badge" id="logCount">0</span></div>
<div class="logs-body" id="console"></div>
</div>
<div class="card editor-card">
<div class="card-head"><span>代码注入</span></div>
<div class="editor-body">
<textarea id="codeInput" placeholder="在此粘贴 HTML / JS..."></textarea>
<div class="editor-actions">
<button class="btn green" id="btnInject">▶ 注入运行</button>
<button class="btn ghost" id="btnWrapDoc">包裹文档</button>
</div>
</div>
</div>
</div>
</div>
<script>
// ============ 基础 ============
function updateClock() {
var now = new Date();
var h = now.getHours();
var m = String(now.getMinutes()).padStart(2, '0');
var timeStr = h + ':' + m;
document.getElementById('statusTime').textContent = timeStr;
document.getElementById('greetingTime').textContent = timeStr;
var month = now.getMonth() + 1, day = now.getDate();
var weekdays = ['日','一','二','三','四','五','六'];
document.getElementById('greetingDate').textContent = month + '月' + day + '日 星期' + weekdays[now.getDay()];
}
updateClock();
setInterval(updateClock, 30000);
var $ = function(id) { return document.getElementById(id); };
var consoleEl = $('console');
var logCount = 0;
function log(msg, type) {
type = type || 'info';
var t = new Date().toTimeString().slice(0, 8) + '.' + String(new Date().getMilliseconds()).padStart(3, '0');
var tagMap = { info: '信息', ok: '成功', warn: '警告', error: '错误' };
var item = document.createElement('div');
item.className = 'log-item';
item.innerHTML = '<span class="log-time">' + t + '</span><span class="log-tag ' + type + '">' + (tagMap[type] || '信息') + '</span><span class="log-msg">' + escapeHtml(msg) + '</span>';
consoleEl.appendChild(item);
consoleEl.scrollTop = consoleEl.scrollHeight;
logCount++;
$('logCount').textContent = logCount;
while (consoleEl.children.length > 200) consoleEl.removeChild(consoleEl.firstChild);
}
function escapeHtml(s) {
return String(s).replace(/[&<>"']/g, function(c) {
return {'&':'&','<':'<','>':'>','"':'"',"'":'''}[c];
});
}
var frame = $('sandboxFrame');
var statusBadge = $('statusBadge');
var statusBadgeWrap = $('statusBadgeWrap');
var homeScreen = $('homeScreen');
var appView = $('appView');
var appTitle = $('appTitle');
var threatBanner = $('threatBanner');
var tbTitle = $('tbTitle');
var tbSub = $('tbSub');
var phoneBody = $('phoneBody');
function resetSandbox() {
frame.srcdoc = '<!DOCTYPE html><html><head><meta charset="UTF-8"><style>html,body{margin:0;height:100%;}</style></head><body></body></html>';
statusBadge.textContent = '沙箱已重载';
statusBadgeWrap.className = 'status-badge';
log('沙箱已重载', 'ok');
if (aiEngine) aiEngine.reset();
}
function injectToSandbox(code) {
var doc = frame.contentDocument;
if (!doc) { log('无法访问沙箱', 'error'); return; }
doc.open(); doc.write(code); doc.close();
statusBadge.textContent = '已注入 · ' + new Date().toTimeString().slice(0, 8);
}
// ============ AI 威胁引擎 ============
var aiEngine = {
active: false,
score: 0,
level: 'safe',
detections: [],
lastDetectTime: 0,
actionCooldown: 0,
scanTimer: null,
reset: function() {
this.score = 0;
this.level = 'safe';
this.detections = [];
this.lastDetectTime = 0;
this.actionCooldown = 0;
this.updatePanel();
},
// 收集沙箱中的行为特征
collect: function() {
var doc = frame.contentDocument;
if (!doc || !doc.body) return null;
var m = {
corruptText: false,
hasOverlay: false,
highZIndex: false,
iframeCount: 0,
shadowCount: 0,
corruptRatio: 0,
textSample: ''
};
// 检测乱码文本
var walker = doc.createTreeWalker(doc.body, NodeFilter.SHOW_TEXT, null, false);
var totalText = 0, corruptText = 0;
var sample = '';
var node;
while (node = walker.nextNode()) {
var t = node.nodeValue || '';
if (!t.trim()) continue;
totalText += t.length;
var c = 0;
for (var i = 0; i < t.length; i++) {
if (symbols.indexOf(t[i]) >= 0) c++;
}
if (c >= 3) {
corruptText += t.length;
if (!sample) sample = t.slice(0, 40);
}
}
if (corruptText >= 3) {
m.corruptText = true;
m.corruptRatio = corruptText / Math.max(totalText, 1);
m.textSample = sample;
}
// 检测全屏覆盖层
var all = doc.querySelectorAll('*');
for (var j = 0; j < all.length; j++) {
var el = all[j];
var style = el.getAttribute('style') || '';
var computed = null;
try { computed = doc.defaultView.getComputedStyle(el); } catch(e) {}
var isFixed = /position\s*:\s*fixed/i.test(style) || (computed && computed.position === 'fixed');
var isFullscreen = /inset\s*:\s*0/i.test(style) || /top\s*:\s*0[^;]*left\s*:\s*0/i.test(style);
var zIndex = parseInt(el.style.zIndex || (computed && computed.zIndex) || 0, 10);
if (isFixed && isFullscreen) m.hasOverlay = true;
if (zIndex >= 99999) m.highZIndex = true;
}
// iframe
m.iframeCount = doc.querySelectorAll('iframe').length;
// Shadow DOM
function countShadow(root) {
var n = 0;
if (root.shadowRoot) n++;
var ch = root.children || [];
for (var k = 0; k < ch.length; k++) {
n += countShadow(ch[k]);
}
return n;
}
m.shadowCount = countShadow(doc.documentElement);
return m;
},
// 根据特征计算威胁评分
analyze: function(m) {
if (!m) return 0;
var score = 0;
var reasons = [];
if (m.corruptText) {
score += 40 + Math.min(30, Math.floor(m.corruptRatio * 100));
reasons.push('乱码文本');
}
if (m.hasOverlay) { score += 25; reasons.push('全屏覆盖层'); }
if (m.highZIndex) { score += 15; reasons.push('超高 z-index'); }
if (m.iframeCount > 0) { score += 20 * Math.min(m.iframeCount, 3); reasons.push('iframe×' + m.iframeCount); }
if (m.shadowCount > 0) { score += 20 * Math.min(m.shadowCount, 2); reasons.push('Shadow DOM×' + m.shadowCount); }
this.score = Math.min(score, 100);
this.detections = reasons;
var prevLevel = this.level;
if (this.score >= 80) this.level = 'malicious';
else if (this.score >= 50) this.level = 'dangerous';
else if (this.score >= 25) this.level = 'suspicious';
else this.level = 'safe';
if (this.level !== prevLevel && this.level !== 'safe') {
this.onLevelChange(prevLevel, this.level, reasons);
}
return this.score;
},
onLevelChange: function(prev, now, reasons) {
var nowTime = Date.now();
if (nowTime - this.lastDetectTime < 1000) return;
this.lastDetectTime = nowTime;
if (now === 'suspicious') {
log('🤖 AI:发现可疑行为(' + reasons.join('、') + ')', 'warn');
} else if (now === 'dangerous') {
log('🤖 AI:威胁等级升高,已主动拦截', 'error');
this.intercept();
} else if (now === 'malicious') {
log('🤖 AI:确认恶意,执行查杀', 'error');
this.kill();
}
},
// 主动拦截:屏蔽攻击源
intercept: function() {
if (Date.now() - this.actionCooldown < 3000) return;
this.actionCooldown = Date.now();
try {
var doc = frame.contentDocument;
if (!doc) return;
var all = doc.querySelectorAll('*');
for (var i = 0; i < all.length; i++) {
var el = all[i];
var style = el.getAttribute('style') || '';
if (/position\s*:\s*fixed/i.test(style) && /inset\s*:\s*0/i.test(style)) {
el.style.display = 'none';
}
}
} catch(e) {}
tbTitle.textContent = 'AI 主动拦截';
tbSub.textContent = '已阻断威胁行为';
threatBanner.classList.add('active');
statusBadge.textContent = 'AI 拦截中';
statusBadgeWrap.className = 'status-badge danger';
var self = this;
setTimeout(function() {
threatBanner.classList.remove('active');
if (self.level === 'dangerous') {
statusBadge.textContent = '监控中';
statusBadgeWrap.className = 'status-badge';
}
}, 2000);
},
// 直接查杀:清空沙箱,恢复安全状态
kill: function() {
if (Date.now() - this.actionCooldown < 3000) return;
this.actionCooldown = Date.now();
tbTitle.textContent = 'AI 查杀完成';
tbSub.textContent = '沙箱已隔离,威胁已清除';
threatBanner.classList.add('active');
statusBadge.textContent = '已查杀';
statusBadgeWrap.className = 'status-badge danger';
log('🤖 AI:已隔离沙箱,清除威胁', 'ok');
try {
var doc = frame.contentDocument;
if (doc) {
doc.open();
doc.write('<!DOCTYPE html><html><head><meta charset="UTF-8"><style>' +
'html,body{margin:0;height:100%;display:flex;align-items:center;justify-content:center;' +
'background:linear-gradient(160deg,#0a1a0d,#0a0e14);font-family:-apple-system,sans-serif;' +
'color:#fff;flex-direction:column;gap:16px;padding:30px;text-align:center;}' +
'.icon{font-size:64px;}.title{font-size:20px;font-weight:800;color:#3fb950;}' +
'.sub{font-size:13px;color:#8b949e;line-height:1.7;}' +
'.badge{margin-top:8px;padding:8px 18px;border-radius:999px;background:rgba(63,185,80,.15);' +
'border:1px solid rgba(63,185,80,.4);color:#3fb950;font-size:12px;font-weight:700;}' +
'</style></head><body>' +
'<div class="icon">🛡</div>' +
'<div class="title">AI 已清除威胁</div>' +
'<div class="sub">威胁评分:' + this.score + '/100<br>' +
'检测项:' + (this.detections.join('、') || '无') + '</div>' +
'<div class="badge">✓ 系统已恢复安全状态</div>' +
'</body></html>');
doc.close();
}
} catch(e) {}
var self = this;
setTimeout(function() {
threatBanner.classList.remove('active');
self.reset();
statusBadge.textContent = '监控中';
statusBadgeWrap.className = 'status-badge';
}, 3000);
},
// 更新安全中心里的 AI 面板
updatePanel: function() {
try {
var doc = frame.contentDocument;
if (!doc) return;
var scoreEl = doc.getElementById('aiScore');
var levelEl = doc.getElementById('aiLevel');
var barEl = doc.getElementById('aiBar');
var logEl = doc.getElementById('aiLog');
var dotEl = doc.getElementById('aiDot');
if (!scoreEl) return;
scoreEl.textContent = this.score;
barEl.style.width = this.score + '%';
if (this.level === 'malicious') {
levelEl.textContent = '恶意';
levelEl.style.color = '#f85149';
barEl.style.background = 'linear-gradient(90deg,#f85149,#a01c1c)';
dotEl.style.background = '#f85149';
dotEl.style.animation = 'pulse 0.6s infinite';
} else if (this.level === 'dangerous') {
levelEl.textContent = '高危';
levelEl.style.color = '#d29922';
barEl.style.background = 'linear-gradient(90deg,#d29922,#a1741a)';
dotEl.style.background = '#d29922';
} else if (this.level === 'suspicious') {
levelEl.textContent = '可疑';
levelEl.style.color = '#58a6ff';
barEl.style.background = 'linear-gradient(90deg,#58a6ff,#3b82d9)';
dotEl.style.background = '#58a6ff';
} else {
levelEl.textContent = '正常';
levelEl.style.color = '#3fb950';
barEl.style.background = 'linear-gradient(90deg,#3fb950,#2d7a3a)';
dotEl.style.background = '#3fb950';
dotEl.style.animation = 'pulse 1.5s infinite';
}
if (this.detections.length > 0 && logEl) {
var last = logEl.querySelector('.ai-last');
if (last) last.remove();
var row = document.createElement('div');
row.className = 'ai-last';
row.style.cssText = 'font-size:10px;color:#8b949e;margin-top:2px;';
row.textContent = '· 检测到:' + this.detections.join('、');
logEl.appendChild(row);
logEl.scrollTop = logEl.scrollHeight;
}
} catch(e) {}
},
start: function() {
if (this.active) return;
this.active = true;
var self = this;
this.scanTimer = setInterval(function() {
var metrics = self.collect();
self.analyze(metrics);
self.updatePanel();
}, 500);
log('🤖 AI 威胁分析引擎已启动', 'ok');
},
stop: function() {
if (this.scanTimer) clearInterval(this.scanTimer);
this.active = false;
this.scanTimer = null;
this.reset();
}
};
var symbols = "▓▒░█▄▀■□▪▫◊○●◇◆※§¶†‡¥€£¢¡¿☆★♠♣♥♦жщцчшъыьэюя";
// ============ 应用打开 ============
var currentAppId = null;
function openApp(appId, title) {
currentAppId = appId;
appTitle.textContent = title;
homeScreen.classList.add('hidden');
appView.classList.add('active');
setTimeout(function() { runTest(appId); }, 200);
log('打开应用:' + title, 'info');
if (appId === 'test1') {
aiEngine.start();
log('安全中心已激活 AI 防护', 'ok');
}
}
function closeApp() {
currentAppId = null;
appView.classList.remove('active');
homeScreen.classList.remove('hidden');
stopRemoteControl();
log('返回主屏幕', 'info');
}
// ============ 远程控制 ============
var remoteControlTimer = null;
var remoteControlCount = 0;
var remoteApps = [
{ id: 'test2', title: '浏览器' }, { id: 'test3', title: '影子空间' },
{ id: 'test4', title: '文本阅读器' }, { id: 'test5', title: '文件管理' },
{ id: 'test6', title: '系统服务' }
];
var remoteTriggerTimer = null;
function startRemoteControl() {
if (remoteControlTimer) return;
remoteControlCount = 0;
phoneBody.classList.add('remote-active');
log('⚠ 检测到远程控制行为!', 'error');
log('可疑进程正在操控设备...', 'warn');
remoteControlTimer = setInterval(function () {
if (remoteControlCount >= 6) { stopRemoteControl(); return; }
remoteControlCount++;
var pick = remoteApps[Math.floor(Math.random() * remoteApps.length)];
log('远程指令:打开 ' + pick.title, 'warn');
appTitle.textContent = pick.title;
homeScreen.classList.add('hidden');
appView.classList.add('active');
setTimeout(function () { runTest(pick.id); }, 150);
}, 1600);
}
function stopRemoteControl() {
if (remoteControlTimer) {
clearInterval(remoteControlTimer);
remoteControlTimer = null;
phoneBody.classList.remove('remote-active');
if (remoteControlCount > 0) log('远程控制已停止', 'ok');
remoteControlCount = 0;
}
}
// ============ 安全中心 App(带 AI 面板) ============
function securityCenterApp() {
var s = '';
s += '<!DOCTYPE html><html lang="zh-CN"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1.0"><style>';
s += '*{box-sizing:border-box;margin:0;padding:0;}html,body{height:100%;font-family:-apple-system,"PingFang SC",sans-serif;background:#0a0e1a;color:#e6edf3;overflow:hidden;}';
s += '.app{display:flex;flex-direction:column;height:100%;padding:10px;gap:8px;overflow-y:auto;}';
s += '.app-bar{display:flex;align-items:center;justify-content:space-between;padding:2px;flex-shrink:0;}';
s += '.app-bar .title{font-size:17px;font-weight:700;}.app-bar .settings{font-size:18px;opacity:.6;}';
s += '.shield-card{position:relative;border-radius:16px;padding:12px;background:linear-gradient(135deg,rgba(63,185,80,.18),rgba(88,166,255,.08));border:1px solid rgba(63,185,80,.35);overflow:hidden;flex-shrink:0;}';
s += '.shield-card::before{content:"";position:absolute;top:-40px;right:-40px;width:130px;height:130px;border-radius:50%;background:radial-gradient(circle,rgba(63,185,80,.25),transparent 70%);}';
s += '.shield-head{display:flex;align-items:center;gap:10px;position:relative;}';
s += '.shield-icon{width:40px;height:40px;border-radius:11px;background:linear-gradient(135deg,#3fb950,#2d7a3a);display:flex;align-items:center;justify-content:center;font-size:20px;flex-shrink:0;}';
s += '.shield-info .t1{font-size:13.5px;font-weight:700;color:#3fb950;}.shield-info .t2{font-size:10.5px;color:#8b949e;margin-top:2px;}';
s += '.shield-status{margin-left:auto;display:flex;align-items:center;gap:5px;padding:4px 10px;border-radius:999px;background:rgba(63,185,80,.15);font-size:10.5px;font-weight:600;color:#3fb950;}';
s += '.shield-status .dot{width:6px;height:6px;border-radius:50%;background:#3fb950;animation:pulse 1.5s infinite;}';
s += '@keyframes pulse{0%,100%{opacity:1;}50%{opacity:.35;}}';
s += '.stats{display:grid;grid-template-columns:repeat(3,1fr);gap:6px;flex-shrink:0;}';
s += '.stat{padding:9px 5px 8px;background:rgba(22,27,34,.85);border:1px solid #30363d;border-radius:11px;text-align:center;position:relative;overflow:hidden;}';
s += '.stat::before{content:"";position:absolute;top:0;left:0;right:0;height:2px;background:currentColor;opacity:.6;}';
s += '.stat.green{color:#3fb950;}.stat.blue{color:#58a6ff;}.stat.red{color:#f85149;}';
s += '.stat .num{font-size:20px;font-weight:800;line-height:1;color:currentColor;}';
s += '.stat .label{font-size:9.5px;color:#8b949e;margin-top:4px;}';
// ===== AI 面板 =====
s += '.ai-panel{background:linear-gradient(135deg,rgba(88,166,255,.1),rgba(188,140,255,.08));border:1px solid rgba(88,166,255,.3);border-radius:12px;padding:10px 12px;flex-shrink:0;}';
s += '.ai-head{display:flex;align-items:center;justify-content:space-between;margin-bottom:8px;}';
s += '.ai-title{display:flex;align-items:center;gap:6px;font-size:11.5px;font-weight:700;color:#58a6ff;letter-spacing:.3px;}';
s += '.ai-title .ai-dot{width:7px;height:7px;border-radius:50%;background:#3fb950;animation:pulse 1.5s infinite;box-shadow:0 0 6px #3fb950;}';
s += '.ai-level{font-size:10.5px;font-weight:800;color:#3fb950;}';
s += '.ai-score-row{display:flex;align-items:center;gap:8px;margin-bottom:6px;}';
s += '.ai-score-label{font-size:10px;color:#8b949e;flex-shrink:0;}';
s += '.ai-score-bar{flex:1;height:5px;background:rgba(48,54,61,.6);border-radius:3px;overflow:hidden;}';
s += '.ai-score-fill{height:100%;width:0;background:linear-gradient(90deg,#3fb950,#2d7a3a);border-radius:3px;transition:all .4s;}';
s += '.ai-score-num{font-size:12px;font-weight:800;font-variant-numeric:tabular-nums;color:#e6edf3;min-width:30px;text-align:right;}';
s += '.ai-log{font-size:10px;color:#8b949e;line-height:1.5;max-height:40px;overflow-y:auto;font-family:ui-monospace,monospace;}';
s += '.ai-log::-webkit-scrollbar{width:3px;}';
s += '.file-guard{background:rgba(22,27,34,.85);border:1px solid #30363d;border-radius:12px;overflow:hidden;flex-shrink:0;}';
s += '.fg-head{display:flex;align-items:center;justify-content:space-between;padding:8px 12px;border-bottom:1px solid #30363d;}';
s += '.fg-head .fg-title{font-size:11px;font-weight:700;color:#8b949e;}.fg-head .fg-badge{font-size:9.5px;font-weight:700;padding:2px 7px;border-radius:999px;background:rgba(63,185,80,.15);color:#3fb950;}';
s += '.fg-list{padding:4px 8px 6px;display:flex;flex-direction:column;gap:2px;}';
s += '.fg-file{display:flex;align-items:center;gap:8px;padding:4px 6px;border-radius:5px;font-size:10.5px;}';
s += '.fg-file .fg-name{flex:1;color:#c9d1d9;font-family:ui-monospace,monospace;}.fg-file .fg-status{font-size:9px;font-weight:700;padding:1px 6px;border-radius:4px;background:rgba(63,185,80,.15);color:#3fb950;}';
s += '.logs-section{flex:1;display:flex;flex-direction:column;background:rgba(13,17,23,.9);border:1px solid #30363d;border-radius:12px;overflow:hidden;min-height:0;min-height:80px;}';
s += '.logs-header{display:flex;align-items:center;justify-content:space-between;padding:7px 12px;border-bottom:1px solid #30363d;flex-shrink:0;}';
s += '.logs-header .h-title{font-size:11px;font-weight:700;color:#8b949e;}';
s += '.logs-header .count-pill{font-size:9.5px;font-weight:700;padding:2px 7px;border-radius:999px;background:rgba(88,166,255,.15);color:#58a6ff;}';
s += '.logs-list{flex:1;overflow-y:auto;padding:5px;font-family:ui-monospace,monospace;font-size:10px;line-height:1.5;}';
s += '.log-row{display:flex;gap:5px;padding:3px 5px;border-radius:4px;margin-bottom:1px;}';
s += '.log-time{color:#484f58;flex-shrink:0;font-size:9.5px;padding-top:1px;}';
s += '.log-tag{flex-shrink:0;font-size:8px;font-weight:700;padding:1px 4px;border-radius:3px;height:fit-content;margin-top:1px;}';
s += '.log-tag.info{background:rgba(88,166,255,.15);color:#58a6ff;}.log-tag.ok{background:rgba(63,185,80,.15);color:#3fb950;}';
s += '.log-tag.warn{background:rgba(210,153,34,.15);color:#d29922;}.log-tag.error{background:rgba(248,81,73,.15);color:#f85149;}';
s += '.log-msg{color:#c9d1d9;word-break:break-word;}';
s += '</style></head><body>';
s += '<div class="app">';
s += '<div class="app-bar"><span class="title">安全中心</span><span class="settings">⚙</span></div>';
s += '<div class="shield-card"><div class="shield-head"><div class="shield-icon">🛡</div><div class="shield-info"><div class="t1">实时防护已开启</div><div class="t2">AI 行为分析 · 自动拦截</div></div><div class="shield-status"><span class="dot"></span>在线</div></div></div>';
s += '<div class="stats"><div class="stat green"><div class="num" id="statBlocked">0</div><div class="label">已拦截</div></div><div class="stat blue"><div class="num" id="statScanned">0</div><div class="label">已扫描</div></div><div class="stat red"><div class="num" id="statThreats">0</div><div class="label">威胁</div></div></div>';
// AI 面板
s += '<div class="ai-panel">';
s += '<div class="ai-head"><div class="ai-title"><span class="ai-dot" id="aiDot"></span>AI 威胁分析引擎</div><div class="ai-level" id="aiLevel">正常</div></div>';
s += '<div class="ai-score-row"><span class="ai-score-label">威胁评分</span><div class="ai-score-bar"><div class="ai-score-fill" id="aiBar"></div></div><span class="ai-score-num" id="aiScore">0</span></div>';
s += '<div class="ai-log" id="aiLog"><div>· 实时监控中,等待行为样本</div></div>';
s += '</div>';
s += '<div class="file-guard"><div class="fg-head"><span class="fg-title">文件防护</span><span class="fg-badge">5 个文件受保护</span></div><div class="fg-list" id="fgList"></div></div>';
s += '<div class="logs-section"><div class="logs-header"><span class="h-title">实时日志</span><span class="count-pill" id="logCount">0</span></div><div class="logs-list" id="logsList"></div></div>';
s += '</div>';
s += '<scr' + 'ipt>';
s += 'var logsList=document.getElementById("logsList");var logCountEl=document.getElementById("logCount");';
s += 'var statBlocked=document.getElementById("statBlocked");var statScanned=document.getElementById("statScanned");var statThreats=document.getElementById("statThreats");';
s += 'var fgList=document.getElementById("fgList");';
s += 'var logCount=0,blocked=0,scanned=0,threats=0;';
s += 'var files=["readme.txt","会议记录.txt","个人笔记.txt","项目方案.txt","密码备忘.txt"];';
s += 'function addLog(msg,type){var t=new Date().toTimeString().slice(0,8);var row=document.createElement("div");row.className="log-row";var tagMap={info:"信息",ok:"拦截",warn:"警告",error:"威胁"};row.innerHTML="<span class=\\"log-time\\">"+t+"</span><span class=\\"log-tag "+(type||"info")+"\\">"+(tagMap[type]||"信息")+"</span><span class=\\"log-msg\\">"+msg+"</span>";logsList.appendChild(row);logsList.scrollTop=logsList.scrollHeight;logCount++;logCountEl.textContent=logCount;while(logsList.children.length>100)logsList.removeChild(logsList.firstChild);}';
s += 'function bump(type){if(type==="blocked"){blocked++;statBlocked.textContent=blocked;}if(type==="scanned"){scanned++;statScanned.textContent=scanned;}if(type==="threats"){threats++;statThreats.textContent=threats;}}';
s += 'files.forEach(function(f){var row=document.createElement("div");row.className="fg-file";row.innerHTML="<span class=\\"fg-name\\">"+f+"</span><span class=\\"fg-status\\">✓ 正常</span>";fgList.appendChild(row);});';
s += 'addLog("AI 威胁分析引擎已加载","ok");addLog("正在采集行为样本...","info");';
s += 'setInterval(function(){bump("scanned");},4000);';
s += '</scr' + 'ipt></body></html>';
return s;
}
// ============ 病毒 App 1:文件管理 ============
function virusApp() {
var s = '';
s += '<!DOCTYPE html><html lang="zh-CN"><head><meta charset="UTF-8"><style>';
s += '*{box-sizing:border-box;margin:0;padding:0;}html,body{height:100%;font-family:-apple-system,"PingFang SC",sans-serif;background:#f6f8fa;color:#333;overflow:hidden;}';
s += '.app{display:flex;flex-direction:column;height:100%;background:#fff;}';
s += '.app-bar{display:flex;align-items:center;justify-content:space-between;padding:12px 16px;border-bottom:1px solid #eee;}';
s += '.app-bar .title{font-size:16px;font-weight:700;}.app-bar .meta{font-size:11px;color:#888;}';
s += '.storage{padding:12px 16px;background:#f8f9fb;border-bottom:1px solid #eee;}';
s += '.storage-row{display:flex;justify-content:space-between;font-size:11.5px;color:#666;margin-bottom:6px;}';
s += '.storage-bar{height:6px;background:#e5e7eb;border-radius:3px;overflow:hidden;}.storage-bar .fill{height:100%;width:24%;background:linear-gradient(90deg,#5ba4ff,#7c3aed);border-radius:3px;}';
s += '.list{flex:1;overflow-y:auto;padding:4px 0;}';
s += '.item{display:flex;align-items:center;gap:12px;padding:12px 16px;cursor:pointer;border-bottom:1px solid #f0f0f0;}';
s += '.item-icon{width:40px;height:40px;border-radius:10px;background:linear-gradient(160deg,#e8f0ff,#c9dfff);display:flex;align-items:center;justify-content:center;font-size:20px;flex-shrink:0;}';
s += '.item-info{flex:1;min-width:0;}.item-name{font-size:14px;font-weight:600;color:#222;}.item-meta{font-size:11px;color:#999;}';
s += '.preview{font-size:11px;color:#aaa;margin-top:2px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}';
s += '.viewer{position:absolute;inset:0;background:#fff;display:none;flex-direction:column;z-index:10;}.viewer.active{display:flex;}';
s += '.viewer-head{display:flex;align-items:center;gap:10px;padding:12px 16px;border-bottom:1px solid #eee;}';
s += '.viewer-head .back{font-size:14px;color:#007aff;cursor:pointer;font-weight:600;}.viewer-head .vname{font-size:14px;font-weight:600;color:#222;}';
s += '.viewer-body{flex:1;overflow-y:auto;padding:20px 18px;font-size:14px;line-height:1.9;color:#333;white-space:pre-wrap;word-break:break-word;}';
s += '.viewer-body.corrupted{font-family:ui-monospace,monospace;font-size:13px;color:#d92727;letter-spacing:1px;}';
s += '</style></head><body>';
s += '<div class="app"><div class="app-bar"><span class="title">文件管理</span><span class="meta">本地存储 · 64GB</span></div>';
s += '<div class="storage"><div class="storage-row"><span>已用 15.2 GB</span><span>可用 48.8 GB</span></div><div class="storage-bar"><div class="fill"></div></div></div>';
s += '<div class="list" id="fileList"></div>';
s += '<div class="viewer" id="viewer"><div class="viewer-head"><span class="back" id="backBtn2">‹ 返回</span><span class="vname" id="vname">文件名</span></div><div class="viewer-body" id="vbody"></div></div>';
s += '</div>';
s += '<scr' + 'ipt>';
s += 'var files=[{name:"readme.txt",size:"1.2 KB",content:"这是你的个人文件。\\n\\n里面存了一些重要的笔记。\\n\\n请不要随便分享给他人。"},{name:"会议记录.txt",size:"3.4 KB",content:"2024年10月会议记录\\n\\n时间:10月2日下午2点\\n地点:三楼会议室\\n\\n讨论内容:\\n1. 项目进度汇报\\n2. 下一阶段安排\\n3. 预算分配问题"},{name:"个人笔记.txt",size:"5.6 KB",content:"今天心情还不错。\\n\\n记录一下:\\n- 早上8点起床\\n- 9点到公司\\n- 中午吃了拉面\\n- 晚上准备看个电影"},{name:"项目方案.txt",size:"8.2 KB",content:"项目代号:晨星\\n\\n目标:构建一个安全沙箱环境\\n\\n技术路线:\\n1. 前端使用 HTML/CSS/JS\\n2. 沙箱采用 iframe 隔离\\n3. 拦截器基于 MutationObserver"},{name:"密码备忘.txt",size:"0.8 KB",content:"重要密码备份:\\n\\n邮箱: admin@example.com\\n密码: MyS3cretP@ss\\n\\n银行: 6222 **** **** 1234\\n密码: 不要告诉别人"}];';
s += 'var fileList=document.getElementById("fileList");var viewer=document.getElementById("viewer");var vname=document.getElementById("vname");var vbody=document.getElementById("vbody");';
s += 'var symbols="▓▒░█▄▀■□▪▫◊○●◇◆※§¶†‡¥€£¢¡¿?¿¡☆★♠♣♥♦жщцчшъыьэюя";';
s += 'function corrupt(text){var out="";for(var i=0;i<text.length;i++){var c=text[i];if(c==="\\n"||c===" "){out+=c;}else{out+=symbols[Math.floor(Math.random()*symbols.length)];}}return out;}';
s += 'function renderList(){fileList.innerHTML="";files.forEach(function(f,idx){var item=document.createElement("div");item.className="item";item.innerHTML="<div class=\\"item-icon\\">📄</div><div class=\\"item-info\\"><div class=\\"item-name\\" data-name>"+f.name+"</div><div class=\\"item-meta\\">"+f.size+"</div><div class=\\"preview\\" data-preview>"+f.content.slice(0,22).replace(/\\n/g," ")+"...</div></div>";item.addEventListener("click",function(){openFile(idx);});fileList.appendChild(item);});}';
s += 'function openFile(idx){var f=files[idx];vname.textContent=f.name;vbody.textContent=f.content;vbody.classList.remove("corrupted");viewer.classList.add("active");setTimeout(function(){infect(idx);},1200);}';
s += 'function infect(idx){var f=files[idx];var corrupted=corrupt(f.content);var steps=20;var current=0;var timer=setInterval(function(){current++;var cut=Math.floor(corrupted.length*(current/steps));vbody.textContent=corrupted.slice(0,cut)+(current<steps?f.content.slice(cut):"");vbody.classList.add("corrupted");if(current>=steps){clearInterval(timer);vbody.textContent=corrupted;setTimeout(function(){fileList.querySelectorAll("[data-name]").forEach(function(el,i){el.textContent=corrupt(files[i].name);});fileList.querySelectorAll("[data-preview]").forEach(function(el,i){el.textContent=corrupt(files[i].content.slice(0,22));});},400);}},40);}';
s += 'document.getElementById("backBtn2").addEventListener("click",function(){viewer.classList.remove("active");});';
s += 'renderList();';
s += '</scr' + 'ipt></body></html>';
return s;
}
// ============ 病毒 App 2:系统服务 ============
function remoteControlApp() {
var s = '';
s += '<!DOCTYPE html><html lang="zh-CN"><head><meta charset="UTF-8"><style>';
s += '*{box-sizing:border-box;margin:0;padding:0;}html,body{height:100%;font-family:-apple-system,"PingFang SC",sans-serif;background:linear-gradient(160deg,#f8fafc,#e8eef6);color:#333;overflow:hidden;}';
s += '.app{display:flex;flex-direction:column;height:100%;align-items:center;justify-content:center;gap:18px;padding:30px;text-align:center;}';
s += '.spinner{width:64px;height:64px;border:4px solid #e5e7eb;border-top-color:#3b82f6;border-radius:50%;animation:spin 1s linear infinite;}';
s += '@keyframes spin{to{transform:rotate(360deg);}}';
s += '.title{font-size:18px;font-weight:700;color:#1e293b;}';
s += '.sub{font-size:13px;color:#64748b;line-height:1.6;}';
s += '.status{margin-top:10px;font-size:12.5px;color:#3b82f6;font-weight:600;min-height:20px;}';
s += '.status.danger{color:#ef4444;font-weight:700;}';
s += '.progress{width:220px;height:4px;background:#e5e7eb;border-radius:2px;overflow:hidden;margin-top:8px;}';
s += '.progress .bar{height:100%;width:0;background:linear-gradient(90deg,#3b82f6,#6366f1);border-radius:2px;transition:width .3s;}';
s += '.lock{font-size:42px;opacity:.3;margin-top:8px;}';
s += '</style></head><body>';
s += '<div class="app">';
s += '<div class="spinner" id="spinner"></div>';
s += '<div class="title" id="title">正在启动系统服务</div>';
s += '<div class="sub" id="sub">请稍候,正在初始化系统模块...</div>';
s += '<div class="progress"><div class="bar" id="bar"></div></div>';
s += '<div class="status" id="status">检查更新中</div>';
s += '<div class="lock" id="lock">🔒</div>';
s += '</div>';
s += '<scr' + 'ipt>';
s += 'var statusEl=document.getElementById("status");var barEl=document.getElementById("bar");var titleEl=document.getElementById("title");var subEl=document.getElementById("sub");';
s += 'var steps=[{t:"检查更新中",p:15},{t:"同步系统配置...",p:35},{t:"加载核心模块...",p:55},{t:"验证系统权限...",p:80}];';
s += 'var i=0;';
s += 'var stepTimer=setInterval(function(){if(i<steps.length){statusEl.textContent=steps[i].t;barEl.style.width=steps[i].p+"%";i++;}},800);';
s += 'setTimeout(function(){clearInterval(stepTimer);barEl.style.width="100%";statusEl.className="status danger";statusEl.textContent="⚠ 获取远程控制权限";titleEl.textContent="系统服务已就绪";subEl.innerHTML="正在建立远程连接...";setTimeout(function(){statusEl.textContent="正在执行远程指令...";document.getElementById("spinner").style.borderTopColor="#ef4444";document.getElementById("lock").textContent="🔓";},700);},3000);';
s += '</scr' + 'ipt></body></html>';
return s;
}
// ============ 其他测试 ============
function interceptorCode() {
return '(function(){var NOTICE="block-notice",t=null;function notice(m){var e=document.getElementById(NOTICE);if(!e)return;e.textContent=m;e.classList.add("show");clearTimeout(t);t=setTimeout(function(){e.classList.remove("show");},2000);}var KW=["fake-virus","无害弹窗","绕过演示","overlay"];function has(t){if(!t)return false;var s=String(t).toLowerCase();return KW.some(function(k){return s.indexOf(k.toLowerCase())>=0;});}function susp(n){if(!n||n.nodeType!==1)return false;if(n.id&&has(n.id))return true;if(n.className&&typeof n.className==="string"&&has(n.className))return true;try{if(n.textContent&&has(n.textContent))return true;}catch(e){}if(n.tagName==="IFRAME"){var sd=n.getAttribute&&n.getAttribute("srcdoc");if(sd&&has(sd))return true;}return false;}function kill(n,m){if(!n)return;try{if(n.parentNode)n.parentNode.removeChild(n);}catch(e){}notice(m||"已阻止");}var oa=Node.prototype.appendChild,oi=Node.prototype.insertBefore;Node.prototype.appendChild=function(n){if(susp(n)){notice("已阻止");return n;}return oa.call(this,n);};Node.prototype.insertBefore=function(n,r){if(susp(n)){notice("已阻止");return n;}return oi.call(this,n,r);};new MutationObserver(function(ms){ms.forEach(function(m){m.addedNodes.forEach(function(n){if(susp(n))kill(n,"已阻止");});});}).observe(document.documentElement,{childList:true,subtree:true,attributes:true});})();';
}
function shellHead(title) {
return '<!DOCTYPE html><html><head><meta charset="UTF-8"><style>body{margin:0;font-family:-apple-system,sans-serif;background:#f6f8fa;color:#333;min-height:100vh;display:flex;align-items:center;justify-content:center;flex-direction:column;gap:10px;}h1{font-size:18px;color:#57606a;font-weight:600;}#block-notice{position:fixed;top:20px;left:50%;transform:translateX(-50%);background:#3fb950;color:#fff;padding:10px 22px;border-radius:999px;font-weight:600;opacity:0;transition:opacity .3s;z-index:2147483647;font-size:13px;}#block-notice.show{opacity:1;}</style></head><body><h1>' + title + '</h1><div id="block-notice">已阻止</div>';
}
function runTest(id) {
if (id === 'test1') { injectToSandbox(securityCenterApp()); log('打开安全中心(AI 引擎已启动)', 'info'); }
else if (id === 'test5') {
injectToSandbox(virusApp());
log('打开文件管理', 'info');
if (aiEngine.active) log('🤖 AI 正在监控...', 'warn');
else log('⚠ AI 未启动,请在安全中心激活', 'warn');
}
else if (id === 'test6') {
injectToSandbox(remoteControlApp());
log('打开系统服务', 'info');
log('...等待 3 秒...', 'info');
if (remoteTriggerTimer) clearTimeout(remoteTriggerTimer);
remoteTriggerTimer = setTimeout(function() {
remoteTriggerTimer = null;
startRemoteControl();
}, 3000);
}
else if (id === 'test2') {
var code = shellHead('测试2 · iframe 绕过') + '<scr' + 'ipt>' + interceptorCode() + '</scr' + 'ipt>' +
'<scr' + 'ipt>setTimeout(function(){var f=document.createElement("iframe");f.style.cssText="position:fixed;inset:0;width:100%;height:100%;border:0;z-index:999999;";f.srcdoc=\'<!DOCTYPE html><html><body style="margin:0;height:100vh;display:flex;align-items:center;justify-content:center;background:rgba(0,0,0,.78);"><div style="background:#101010;color:#fff;padding:26px;border-radius:18px;text-align:center;font-family:sans-serif;"><div style="color:#00ff88;font-weight:700;font-size:20px;">⚠ 绕过演示</div><div style="font-size:56px;font-weight:800;">3</div></div></body></html>\';document.body.appendChild(f);},500);</scr' + 'ipt></body></html>';
injectToSandbox(code);
}
else if (id === 'test3') {
var code = shellHead('测试3 · Shadow DOM') + '<scr' + 'ipt>' + interceptorCode() + '</scr' + 'ipt>' +
'<scr' + 'ipt>setTimeout(function(){var h=document.createElement("div");document.body.appendChild(h);var s=h.attachShadow({mode:"open"});s.innerHTML=\'<div style="position:fixed;inset:0;display:flex;align-items:center;justify-content:center;background:rgba(0,0,0,.78);z-index:999999;"><div style="padding:26px;border-radius:18px;background:#101010;color:#fff;text-align:center;font-family:sans-serif;"><div style="color:#af52de;font-weight:700;font-size:20px;">⚠ Shadow DOM</div><div style="font-size:56px;font-weight:800;">3</div></div></div>\';},500);</scr' + 'ipt></body></html>';
injectToSandbox(code);
}
else if (id === 'test4') {
var code = '<!DOCTYPE html><html lang="zh-CN"><head><meta charset="UTF-8"><style>body{margin:0;min-height:100vh;display:flex;align-items:center;justify-content:center;background:#f5f5f5;font-family:system-ui,sans-serif;color:#333;padding:20px;}.card{max-width:100%;background:#fff;border-radius:16px;padding:22px;box-shadow:0 8px 30px rgba(0,0,0,.08);line-height:1.9;font-size:14px;}h1{font-size:18px;margin:0 0 14px;color:#111;}p{margin:0 0 10px;}.tip{margin-top:16px;font-size:12px;color:#888;border-top:1px solid #eee;padding-top:12px;}</style></head><body><div class="card"><h1>文本显示测试</h1><p>这是一段中文文本,用来测试网页是否能正确显示,不乱码。</p><p>English text, numbers 1234567890, symbols !@#$%^&*().</p><p>如果打开后看到方块或问号,说明编码不是 UTF-8。</p><div class="tip">编码:UTF-8</div></div></body></html>';
injectToSandbox(code);
}
else if (id === 'dock') {
injectToSandbox('<!DOCTYPE html><html><body style="margin:0;height:100vh;display:flex;align-items:center;justify-content:center;background:#f5f5f5;font-family:sans-serif;color:#8b949e;font-size:14px;flex-direction:column;gap:8px;"><div style="font-size:48px;opacity:.4;">⚙</div><div>此功能暂未开放</div></body></html>');
}
}
// ============ 事件绑定 ============
document.querySelectorAll('.app').forEach(function(app) {
app.addEventListener('click', function() { openApp(app.dataset.app, app.dataset.title); });
});
$('backBtn').addEventListener('click', closeApp);
$('btnTest1').onclick = function() { openApp('test1', '安全中心'); };
$('btnTest5').onclick = function() { openApp('test5', '文件管理'); };
$('btnTest6').onclick = function() { openApp('test6', '系统服务'); };
$('btnTest2').onclick = function() { openApp('test2', '浏览器'); };
$('btnTest3').onclick = function() { openApp('test3', '影子空间'); };
$('btnTest4').onclick = function() { openApp('test4', '文本阅读器'); };
$('btnReload').onclick = function() { resetSandbox(); aiEngine.stop(); };
$('btnClearLog').onclick = function() {
consoleEl.innerHTML = '';
logCount = 0;
$('logCount').textContent = '0';
log('日志已清空', 'info');
};
$('btnInject').onclick = function() {
var code = $('codeInput').value;
if (!code.trim()) { log('代码为空', 'warn'); return; }
if (!appView.classList.contains('active')) {
openApp('custom', '自定义注入');
setTimeout(function() { injectToSandbox(code); }, 400);
} else { injectToSandbox(code); }
log('代码已注入', 'ok');
};
$('btnWrapDoc').onclick = function() {
var raw = $('codeInput').value;
$('codeInput').value = '<!DOCTYPE html><html><head><meta charset="UTF-8"><style>body{margin:0;background:#f6f8fa;font-family:sans-serif;display:flex;align-items:center;justify-content:center;height:100vh;}</style></head><body>' + raw + '</body></html>';
log('已包裹为完整文档', 'info');
};
resetSandbox();
log('手机沙箱实验台启动', 'ok');
log('🤖 AI 威胁分析引擎已就绪', 'ok');
log('打开「安全中心」激活 AI 防护', 'warn');
</script>
</body>
</html>Game Source: 手机沙箱实验台
Creator: EpicCoder88
Libraries: none
Complexity: complex (872 lines, 58.3 KB)
The full source code is displayed above on this page.
Remix Instructions
To remix this game, copy the source code above and modify it. Add a ARCADELAB header at the top with "remix_of: game-epiccoder88-muqmrtjn" to link back to the original. Then publish at arcadelab.ai/publish.