diff --git a/.claude/settings.local.json b/.claude/settings.local.json new file mode 100644 index 0000000..c6a693a --- /dev/null +++ b/.claude/settings.local.json @@ -0,0 +1,19 @@ +{ + "permissions": { + "allow": [ + "Bash(grep -E \"\\\\.py$|\\\\.md$\")", + "Bash(git checkout:*)", + "Bash(python3 -c \"import ast; ast.parse\\(open\\(''wx_daemon.py''\\).read\\(\\)\\); print\\(''wx_daemon.py OK''\\)\")", + "Bash(python3 -c \"import ast; ast.parse\\(open\\(''wx.py''\\).read\\(\\)\\); print\\(''wx.py OK''\\)\")", + "Bash(pip install:*)", + "Bash(pip show:*)", + "Bash(pip3 install:*)", + "Bash(python3 -c \"import click; print\\(''click'', click.__version__\\)\")", + "Bash(python3 wx.py --help)", + "Bash(python3 wx.py sessions --help)", + "Bash(python3 -c \"import sys; print\\(sys.executable\\)\")", + "Bash(uv pip:*)", + "Bash(uv venv:*)" + ] + } +} diff --git a/.claude/worktrees/agent-aa71385e b/.claude/worktrees/agent-aa71385e new file mode 160000 index 0000000..69a2f44 --- /dev/null +++ b/.claude/worktrees/agent-aa71385e @@ -0,0 +1 @@ +Subproject commit 69a2f442405d35393bec4b807540af4782cfa6dc diff --git a/Cargo.toml b/Cargo.toml index 75aa5f4..fc17ffb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -49,7 +49,7 @@ md5 = "0.7" # 正则表达式 regex = "1" -[target.'cfg(target_os = "macos")'.dependencies] +[target.'cfg(unix)'.dependencies] libc = "0.2" [target.'cfg(target_os = "windows")'.dependencies] diff --git a/find_all_keys_macos b/find_all_keys_macos new file mode 100755 index 0000000..43c2cd3 Binary files /dev/null and b/find_all_keys_macos differ diff --git a/src/crypto/wal.rs b/src/crypto/wal.rs index abd7fc0..4e3d85d 100644 --- a/src/crypto/wal.rs +++ b/src/crypto/wal.rs @@ -61,7 +61,9 @@ pub fn apply_wal(wal_path: &Path, out_path: &Path, enc_key: &[u8; 32]) -> Result page_buf.resize(PAGE_SZ, 0); } - let dec = decrypt_page(enc_key, &page_buf, pgno)?; + // WAL 帧中的页数据不含 SALT 头,所以对 pgno=1 的帧也用普通页解密路径 + // (区别于主数据库第一页需要跳过 SALT 并写入 SQLite 魔数) + let dec = decrypt_page(enc_key, &page_buf, if pgno == 1 { 2 } else { pgno })?; let file_offset = (pgno as u64 - 1) * PAGE_SZ as u64; db_file.seek(SeekFrom::Start(file_offset))?; db_file.write_all(&dec)?; diff --git a/src/daemon/query.rs b/src/daemon/query.rs index 8793a28..29c6406 100644 --- a/src/daemon/query.rs +++ b/src/daemon/query.rs @@ -259,13 +259,14 @@ pub async fn q_search( let until2 = until; let limit2 = limit * 3; + let names_map2 = names.map.clone(); let found: Vec = tokio::task::spawn_blocking(move || { let conn = Connection::open(&db_path)?; let mut all = Vec::new(); for (tname, display, uname) in &table_list { let is_group = uname.contains("@chatroom"); let rows = search_in_table(&conn, tname, &uname, is_group, - &HashMap::new(), &kw2, since2, until2, limit2)?; + &names_map2, &kw2, since2, until2, limit2)?; for mut row in rows { if row.get("chat").map(|v| v.as_str().unwrap_or("")).unwrap_or("").is_empty() { if let Some(obj) = row.as_object_mut() { diff --git a/src/scanner/macos.rs b/src/scanner/macos.rs index a98cecd..f0734e7 100644 --- a/src/scanner/macos.rs +++ b/src/scanner/macos.rs @@ -152,9 +152,8 @@ fn scan_memory(task: mach_port_t) -> Result> { let mut results: Vec<(String, String)> = Vec::new(); let mut addr: mach_vm_address_t = 0; - // VM_REGION_BASIC_INFO_COUNT_64 = sizeof(vm_region_basic_info_64) / sizeof(int32_t) - let info_count_expected: mach_msg_type_number_t = - (std::mem::size_of::() / 4) as u32; + // VM_REGION_BASIC_INFO_COUNT_64 = 9(来自 ,固定值,不能用 sizeof 计算) + let info_count_expected: mach_msg_type_number_t = 9; loop { let mut size: mach_vm_size_t = 0;