fix: add file size validation and clarify Method 2 intent

- decrypt_images.c: validate aes_ct_size + xor_size fits within file
  before reading, preventing out-of-bounds reads on corrupt files
- decrypt_images.c: remove unused bytes2hex function
- find_image_key.c: add comment explaining Method 2 design intent —
  hex ASCII bytes used directly as AES key (not hex-decoded)
feat/daemon-cli
bbingz 2026-03-05 23:21:09 +08:00 committed by ylytdeng
parent 03582dd82c
commit 96c1a5ac2e
2 changed files with 12 additions and 7 deletions

View File

@ -55,11 +55,6 @@ static int hex2bytes(const char *hex, unsigned char *out, int maxlen) {
return len;
}
static void bytes2hex(const unsigned char *d, int n, char *out) {
for (int i = 0; i < n; i++) sprintf(out + i*2, "%02x", d[i]);
out[n*2] = '\0';
}
/* Minimal JSON string extractor (for simple unescaped string values only). */
static int json_get_string(const char *json, const char *key,
char *value, int maxlen) {
@ -248,12 +243,17 @@ static int decrypt_v2_file(const char *input_path, const char *output_dir,
? (size_t)aes_size + 16
: ((size_t)aes_size + 15) / 16 * 16;
/* Get total file size to calculate raw_data segment */
/* Get total file size and validate header claims fit within it */
long cur_pos = ftell(fin);
fseek(fin, 0, SEEK_END);
long file_size = ftell(fin);
fseek(fin, cur_pos, SEEK_SET);
if ((long)aes_ct_size + (long)xor_size > file_size - HEADER_SIZE) {
fclose(fin);
return -6; /* header claims more data than file contains */
}
unsigned char *aes_ct = malloc(aes_ct_size);
if (!aes_ct) { fclose(fin); return -1; }
size_t rd = fread(aes_ct, 1, aes_ct_size, fin);

View File

@ -433,7 +433,12 @@ static int scan_pid(pid_t pid) {
}
}
/* Method 2: hex string [0-9a-f]{16+} at unaligned positions */
/* Method 2: hex string [0-9a-f]{16+} at unaligned positions.
* WeChat may store the AES key as a hex-encoded ASCII string
* in memory (e.g. "cfcd208495d565ef" = 16 ASCII bytes).
* We use the raw ASCII bytes directly as the 16-byte AES key,
* since the key is arbitrary bytes and the hex representation
* itself is 16 bytes for a 64-bit key half. */
int run = 0, run_start = 0;
for (mach_msg_type_number_t j = 0;
j <= data_cnt && !stop_flag; j++) {