add cookie_grabber extension; minor fixes to TMWebDriver/SOPs/simphtml

This commit is contained in:
Liang Jiaqing
2026-02-19 18:40:28 +08:00
parent 467c4c0eb2
commit 8329efeb9c
9 changed files with 163 additions and 6 deletions

View File

@@ -97,7 +97,7 @@ class TMWebDriver:
auto_switch_newtab = data.get('auto_switch_newtab', False) auto_switch_newtab = data.get('auto_switch_newtab', False)
try: try:
result = self.execute_js(code, timeout=timeout, session_id=session_id, auto_switch_newtab=auto_switch_newtab) result = self.execute_js(code, timeout=timeout, session_id=session_id, auto_switch_newtab=auto_switch_newtab)
print('[remote result]', str(result)[:500]) print('[remote result]', str(result)[:500].replace('\n', ' '))
newTabs = result.get('newTabs', []) if isinstance(result, dict) else [] newTabs = result.get('newTabs', []) if isinstance(result, dict) else []
return json.dumps({'result': result, 'newTabs': newTabs}, ensure_ascii=False) return json.dumps({'result': result, 'newTabs': newTabs}, ensure_ascii=False)
except Exception as e: except Exception as e:
@@ -175,7 +175,7 @@ class TMWebDriver:
session.mark_disconnected() session.mark_disconnected()
break break
def execute_js(self, code, timeout=10.0, session_id=None, auto_switch_newtab=False) -> Any: def execute_js(self, code, timeout=15, session_id=None, auto_switch_newtab=False) -> Any:
if session_id is None: session_id = self.default_session_id if session_id is None: session_id = self.default_session_id
if self.is_remote: if self.is_remote:
print('remote_execute_js') print('remote_execute_js')

View File

@@ -0,0 +1,24 @@
// background.js - 保留原有事件 + 新增消息监听
chrome.runtime.onInstalled.addListener(() => {
console.log('Cookie Grabber installed');
});
// content script 请求cookie时的处理
chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
if (msg.type === 'getCookies' && sender.tab) {
const url = sender.tab.url;
// 普通cookie + partitioned cookie 双查合并
chrome.cookies.getAll({url}, cookies => {
console.log('[CookieGrabber] normal cookies:', cookies.map(c => c.name));
chrome.cookies.getAll({url, partitionKey: {topLevelSite: url.match(/^https?:\/\/[^/]+/)[0]}}, pCookies => {
console.log('[CookieGrabber] partitioned cookies:', pCookies.map(c => c.name));
const map = {};
cookies.forEach(c => map[c.name] = c.value);
pCookies.forEach(c => map[c.name] = c.value);
const str = Object.entries(map).map(([k,v]) => k + '=' + v).join('; ');
sendResponse({cookies: str});
});
});
return true; // 异步响应
}
});

View File

@@ -0,0 +1,18 @@
// content.js - MutationObserver 监听触发元素
const TRIGGER_ID = '__ljqcg__';
const obs = new MutationObserver(muts => {
for (const m of muts) {
for (const node of m.addedNodes) {
if (node.nodeType === 1 && node.id === TRIGGER_ID) {
chrome.runtime.sendMessage({type: 'getCookies'}, res => {
if (res && res.cookies) node.textContent = res.cookies;
else node.textContent = '__cg_error__';
});
return;
}
}
}
});
obs.observe(document.documentElement, {childList: true, subtree: true});

View File

@@ -0,0 +1,32 @@
{
"manifest_version": 3,
"name": "Cookie Grabber",
"version": "1.0",
"description": "获取所有 cookies",
"permissions": [
"cookies",
"storage",
"tabs",
"activeTab"
],
"background": {
"service_worker": "background.js"
},
"action": {
"default_popup": "popup.html"
},
"host_permissions": [
"<all_urls>"
],
"content_scripts": [
{
"matches": [
"<all_urls>"
],
"js": [
"content.js"
],
"run_at": "document_idle"
}
]
}

View File

@@ -0,0 +1,20 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>HttpOnly Cookie Grabber</title>
<script src="popup.js" defer></script>
<style>
body { font-family: Arial, sans-serif; padding: 10px; }
ul { padding-left: 20px; }
li { margin: 5px 0; }
pre { background-color: #f8f8f8; padding: 10px; border: 1px solid #ccc; max-height: 150px; overflow-y: auto; }
button { margin-top: 10px; }
</style>
</head>
<body>
<h1>Get All Cookies</h1>
<ul id="cookiesDisplay">No available cookies</ul>
<button id="refresh">Refresh and Copy Cookies</button>
</body>
</html>

View File

@@ -0,0 +1,56 @@
document.addEventListener('DOMContentLoaded', () => {
// 当刷新按钮被点击时,获取当前页面的 cookies
document.getElementById('refresh').addEventListener('click', fetchCookies);
// 加载时显示当前页面的 cookies
fetchCookies();
});
// 从 cookies 存储中获取当前页面的 cookies
function fetchCookies() {
// 获取当前活动的标签页
chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
const activeTab = tabs[0]; // 获取活动标签页
const currentUrl = activeTab.url; // 当前页面的 URL
console.log("当前活动的 URL:", currentUrl);
// 双查: 普通 + partitioned
const origin = currentUrl.match(/^https?:\/\/[^\/]+/)[0];
chrome.cookies.getAll({ url: currentUrl }, (cookies) => {
chrome.cookies.getAll({ url: currentUrl, partitionKey: { topLevelSite: origin } }, (pCookies) => {
const map = {};
cookies.forEach(c => map[c.name] = c.value);
pCookies.forEach(c => map[c.name] = c.value);
const allCookies = Object.entries(map);
const cookiesDisplay = document.getElementById('cookiesDisplay');
cookiesDisplay.innerHTML = '';
if (allCookies.length === 0) {
cookiesDisplay.innerHTML = '<li>No available cookies</li>';
} else {
let cookiesString = '';
allCookies.forEach(([name, value]) => {
const li = document.createElement('li');
li.textContent = `${name}: ${value}`;
cookiesDisplay.appendChild(li);
cookiesString += `${name}=${value}; `;
});
console.log('cookies:', allCookies.length);
copyCookiesToClipboard(cookiesString.trim());
}
});
});
});
}
// 将 cookies 复制到剪贴板
function copyCookiesToClipboard(cookiesString) {
// 使用 Clipboard API 复制到剪贴板
navigator.clipboard.writeText(cookiesString)
.then(() => {
console.log("Cookies copied to clipboard:", cookiesString);
})
.catch(err => {
console.error("Unable to copy to clipboard:", err);
});
}

View File

@@ -1,9 +1,9 @@
# 自主行动 SOP (探测-报告-执行) [2026年] # 自主行动 SOP (探测-报告-执行)
授权你进行自主行动,只要不对环境造成副作用都可进行。 授权你进行自主行动,只要不对环境造成副作用都可进行。
请先选择核心目标,再选择一个小目标进行。最终探测结果形成报告(含操作申请),待用户回来确认后再进行可能的写入或修改操作。 请先选择核心目标,再选择一个小目标进行。最终探测结果形成报告(含操作申请),待用户回来确认后再进行可能的写入或修改操作。
> **启动时写入工作记忆**`自主探索≤15回合只有cwd内可写用户不在(问题存报告)|收尾:重读本SOP检查遗漏+更新history产出=报告+记忆提案` > **启动时写入工作记忆**`自主探索≤15回合只有cwd内可写用户不在(问题存报告)|收尾:重读本SOP确认报告目录+更新history产出=报告+记忆提案`
## 🎯 核心目标(按价值优先级排序) ## 🎯 核心目标(按价值优先级排序)

View File

@@ -9,6 +9,10 @@
- JS dispatch的事件`isTrusted=false`,敏感操作(文件上传/部分按钮)会被浏览器拦截 - JS dispatch的事件`isTrusted=false`,敏感操作(文件上传/部分按钮)会被浏览器拦截
- 文件上传JS无法填充`<input type=file>`必须ljqCtrl物理点击+Win32轮询文件对话框 - 文件上传JS无法填充`<input type=file>`必须ljqCtrl物理点击+Win32轮询文件对话框
- 流程SetForegroundWindow→ljqCtrl点上传按钮→FindWindow轮询对话框→输入路径→轮询关闭 - 流程SetForegroundWindow→ljqCtrl点上传按钮→FindWindow轮询对话框→输入路径→轮询关闭
- 元素→屏幕物理坐标(ljqCtrl点击前必算)JS一次取rect+窗口信息,公式:
- `physX = (screenX + rect中心x) * dpr``physY = (screenY + chromeH + rect中心y) * dpr`
- chromeH = outerHeight - innerHeightdpr = devicePixelRatio
- 注意screenX/Y也是CSS像素所有值先加后统一乘dpr
- 结论:读信息+普通操作用TMWebDriver文件上传等敏感操作需配合ljqCtrl - 结论:读信息+普通操作用TMWebDriver文件上传等敏感操作需配合ljqCtrl
## 导航 ## 导航
@@ -31,3 +35,7 @@ fetch('PDF_URL').then(r=>r.blob()).then(b=>{
}); });
``` ```
注意需同源或CORS允许跨域先导航到目标域再执行 注意需同源或CORS允许跨域先导航到目标域再执行
## Cookie提取(含HttpOnly)
前提:需先安装`assets/cookie_grabber/`扩展
机制:注入`id="__ljqcg__"`的div→扩展检测后自动将完整cookie写回该元素textContent含HttpOnly

View File

@@ -904,7 +904,6 @@ def execute_js_rich(script, driver):
if isinstance(error, dict): error.pop('stack', None) if isinstance(error, dict): error.pop('stack', None)
error_msg = str(error) error_msg = str(error)
print(f"Error: {error_msg}") print(f"Error: {error_msg}")
if driver.default_session_id != curr_session: if driver.default_session_id != curr_session:
print('Session changed') print('Session changed')
new_tab = True new_tab = True