{"record":{"id":"890b685cfb1507eb","repo":"moonD4rk/HackBrowserData","slug":"scan-master-key-candidates-w","errorCode":null,"errorMessage":"scan master key candidates: %w","messagePattern":"scan master key candidates: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"masterkey/gcoredump_darwin.go","lineNumber":93,"sourceCode":"\t// gcore appends \".PID\" to the -o prefix, e.g. prefix.123\n\tcorePrefix := filepath.Join(os.TempDir(), fmt.Sprintf(\"securityd-core-%d\", time.Now().UnixNano()))\n\tcorePath := fmt.Sprintf(\"%s.%d\", corePrefix, pid)\n\tdefer os.Remove(corePath)\n\n\tcmd := exec.Command(\"gcore\", \"-d\", \"-s\", \"-v\", \"-o\", corePrefix, strconv.Itoa(pid))\n\tif err := cmd.Run(); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to dump securityd memory: %w\", err)\n\t}\n\n\t// vmmap identifies MALLOC_SMALL heap regions where securityd stores keys\n\tregions, err := findMallocSmallRegions(pid)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to find malloc small regions: %w\", err)\n\t}\n\n\tcandidates, err := scanMasterKeyCandidates(corePath, regions)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"scan master key candidates: %w\", err)\n\t}\n\tif len(candidates) == 0 {\n\t\treturn nil, fmt.Errorf(\"no master key candidates found in securityd memory\")\n\t}\n\n\t// read keychain file once, reuse buffer for each candidate\n\tkeychainBuf, err := os.ReadFile(loginKeychainPath)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"read keychain: %w\", err)\n\t}\n\n\tfor _, candidate := range candidates {\n\t\tkc, err := keychainbreaker.Open(keychainbreaker.WithBytes(keychainBuf))\n\t\tif err != nil {\n\t\t\tcontinue\n\t\t}\n\t\tif err := kc.Unlock(keychainbreaker.WithKey(candidate)); err != nil {\n\t\t\tcontinue","sourceCodeStart":75,"sourceCodeEnd":111,"githubUrl":"https://github.com/moonD4rk/HackBrowserData/blob/0503d04d7a8d0379d060268a74f1b149e5a0aad5/masterkey/gcoredump_darwin.go#L75-L111","documentation":"This wraps errors from scanMasterKeyCandidates, the only fallible step of which is macho.Open on the gcore-produced core dump. It means the core file could not be parsed as a Mach-O core, so no key candidates could be extracted.","triggerScenarios":"Calling DecryptKeychainRecords when the gcore output file at corePath is missing, truncated, empty, or not a valid Mach-O core dump — e.g. gcore wrote a partial file, the dump was cleaned up concurrently, or disk pressure corrupted the write.","commonSituations":"/tmp cleanup daemons deleting the file between gcore and macho.Open; gcore partially failing but exiting 0 on some systems; architecture mismatch or unusual core layout confusing debug/macho; disk-full during the dump leaving a truncated file.","solutions":["Check the core file exists and is non-empty right after gcore runs (`ls -la $TMPDIR/securityd-core-*`).","Free disk space in $TMPDIR; re-run if a previous dump was truncated by ENOSPC.","Verify the file is a Mach-O core: `file <corePath>` should report 'Mach-O 64-bit core'.","Re-run the whole DecryptKeychainRecords flow — a transient gcore failure may have produced a bad dump.","Unwrap the %w chain for the underlying macho.Open cause (e.g. 'unknown load command', 'not a Mach-O file') to pinpoint the corruption."],"exampleFix":"// before\nif err := cmd.Run(); err != nil {\n    return nil, fmt.Errorf(\"failed to dump securityd memory: %w\", err)\n}\n// after\nif err := cmd.Run(); err != nil {\n    return nil, fmt.Errorf(\"failed to dump securityd memory: %w\", err)\n}\nif fi, statErr := os.Stat(corePath); statErr != nil || fi.Size() == 0 {\n    return nil, fmt.Errorf(\"core dump %s missing or empty\", corePath)\n}","handlingStrategy":"validation","validationCode":"fi, err := os.Stat(corePath)\nif err != nil || fi.Size() == 0 {\n    return fmt.Errorf(\"core dump missing or empty\")\n}\nif _, err := macho.Open(corePath); err != nil {\n    return fmt.Errorf(\"core dump is not a valid Mach-O file: %v\", err)\n}","typeGuard":null,"tryCatchPattern":"_, err := masterkey.DecryptKeychainRecords()\nif err != nil && strings.Contains(err.Error(), \"scan master key candidates\") {\n    // inspect underlying macho.Open failure; re-dump if file corrupt\n}","preventionTips":["Verify core file exists and is non-empty before parsing (or upstream, right after gcore).","Avoid concurrent runs that race on tmp cleanup.","Watch for disk-full conditions truncating dumps.","Confirm with `file <corePath>` that dumps are Mach-O cores on your OS version."],"tags":["macos","macho","core-dump","file-parse"],"backgroundTag":"file-open-failed","analyzedSha":"0503d04d7a8d0379d060268a74f1b149e5a0aad5","analyzedAt":"2026-09-06T13:38:28.707Z","contentChangedAt":"2026-09-06T13:38:28.707Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}