Skip to content

feat(image_key): implement Linux V2 AES key derivation via /proc/mem + brute-force fallback#110

Open
RoseCamel wants to merge 1 commit into
jackwener:mainfrom
RoseCamel:feat/linux-image-key
Open

feat(image_key): implement Linux V2 AES key derivation via /proc/mem + brute-force fallback#110
RoseCamel wants to merge 1 commit into
jackwener:mainfrom
RoseCamel:feat/linux-image-key

Conversation

@RoseCamel

Copy link
Copy Markdown

Summary

This PR fills the last remaining platform gap in the image_key module — Linux V2 .dat image AES key extraction.

Approach

Two-path strategy, symmetric with the existing macOS implementation:

Primary: process memory extraction

  1. Auto-detect WeChat PID via /proc/<pid>/comm
  2. Scan readable memory regions for uin=<base64> URL parameters (where UIN appears base64-encoded in WeChat's network request URLs)
  3. Derive AES key: md5(str(uin) + normalize(wxid)).hex()[:16] (16 ASCII bytes, same formula as macOS)
  4. Derive XOR key: uin & 0xff
  5. Verify against V2 template ciphertexts from the attach directory

Fallback: brute-force enumeration

When /proc/<pid>/mem is unreadable (no CAP_SYS_PTRACE):

  1. Extract 4-hex-char wxid suffix from the xwechat_files/<wxid_XXXX> directory name
  2. With XOR hint (from .dat tail voting, same as macOS): enumerate 2^24 space — uin & 0xff == xor_key + md5(str(uin))[:4] == suffix — verify each candidate against AES templates
  3. Without XOR hint: full range enumeration (10,000 ~ 50,000,000)

Changes

  • src/attachment/image_key/linux.rs: 438-line implementation replacing the 6-line stub
  • src/attachment/image_key/mod.rs: one-line fix to call ::from_current_config() constructor

Verification

  • cargo check — compiles cleanly
  • cargo test image_key — 8/8 tests pass, including known-value key derivation verification
  • No new dependencies (all crates already in Cargo.toml)
  • Reuses existing shared infrastructure: verify_aes_key(), find_v2_template_ciphertexts(), derive_xor_key_from_v2_dat(), normalize_wxid()

Notes for reviewer

The implementation deliberately mirrors the macOS provider's structure — same caching pattern, same derive_key_for_pathsfind_via_*bruteforce_* flow, same ImageKeyProvider trait impl shape. This keeps the three platform providers easy to compare and maintain in parallel.

Two-path strategy, symmetric with macOS implementation:

Primary path — process memory extraction:
- Auto-detect WeChat PID via /proc/<pid>/comm
- Scan readable memory regions for base64-encoded UIN in 'uin=' URL
  parameters
- Derive AES key: md5(str(uin) + normalize(wxid)).hex()[:16]
- Derive XOR key: uin & 0xff
- Verify against V2 template ciphertexts from attach directory

Fallback — brute-force enumeration:
- Extract 4-hex-char wxid suffix from db_dir path
- Option 1 (with XOR hint): enumerate 2^24 space using
  uin & 0xff == xor_key + md5 suffix match, full AES template verify
- Option 2 (no XOR hint): enumerate 10000..50_000_000 range,
  filter by md5 suffix, verify AES key against templates

Reuses existing shared infrastructure:
- verify_aes_key(), find_v2_template_ciphertexts(),
  derive_xor_key_from_v2_dat()
- normalize_wxid(), wxid_from_db_dir(), same_wxid()

8 tests pass including known-value key derivation verification.

Co-Authored-By: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant