{"id":37134241,"url":"https://github.com/aoiflux/libxfat","last_synced_at":"2026-05-17T02:15:28.330Z","repository":{"id":203802735,"uuid":"599508739","full_name":"aoiflux/libxfat","owner":"aoiflux","description":"libxfat is a Go library offering a robust and efficient solution for parsing and manipulating ExFAT filesystems. It provides comprehensive tools for extracting data and accessing metadata.","archived":false,"fork":false,"pushed_at":"2026-04-24T16:33:44.000Z","size":576,"stargazers_count":2,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-04-24T18:24:52.320Z","etag":null,"topics":["filesystem","forensics","go","library"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aoiflux.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2023-02-09T09:37:40.000Z","updated_at":"2026-04-24T16:33:47.000Z","dependencies_parsed_at":null,"dependency_job_id":"31c2f20b-9c43-4d2c-a8f4-1063d34b7af4","html_url":"https://github.com/aoiflux/libxfat","commit_stats":null,"previous_names":["aoiflux/libxfat"],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/aoiflux/libxfat","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aoiflux%2Flibxfat","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aoiflux%2Flibxfat/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aoiflux%2Flibxfat/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aoiflux%2Flibxfat/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aoiflux","download_url":"https://codeload.github.com/aoiflux/libxfat/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aoiflux%2Flibxfat/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33125184,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-16T18:38:32.183Z","status":"online","status_checked_at":"2026-05-17T02:00:05.366Z","response_time":107,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["filesystem","forensics","go","library"],"created_at":"2026-01-14T15:39:49.599Z","updated_at":"2026-05-17T02:15:28.324Z","avatar_url":"https://github.com/aoiflux.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# libxfat\n\nlibxfat is a Go library for reading exFAT filesystem images. It is aimed at\nforensics and inspection workflows: opening an image, parsing the VBR, walking\ndirectories, reading metadata, and extracting file contents.\n\nThe library is read-oriented. It does not create or modify exFAT volumes.\n\n## Highlights\n\n- Parse exFAT images directly from an `*os.File`.\n- Read the root directory or recursively walk indexable entries.\n- Extract regular files while preserving directory structure.\n- Report volume statistics such as cluster size, used space, and allocation\n  bitmap counts.\n- Surface exFAT metadata entries such as `$BitMap`, `$UpCase`, `$Volume GUID`,\n  `$TexFAT`, and `$ACT`.\n- Add virtual metadata entries such as `$MBR`, `$FAT1`, and `$FAT2` to the root\n  listing.\n- Handle truncated and malformed images more defensively than the original\n  implementation.\n\n## Install\n\n\u003c!-- default option, no dependency badges. --\u003e\n\n\u003c!-- default option, no dependency badges. --\u003e\n\n\u003c/div\u003e\n\u003cbr\u003e\n\n---\n\n## Table of Contents\n\n- [Table of Contents](#table-of-contents)\n- [Overview](#overview)\n- [Features](#features)\n- [Project Structure](#project-structure)\n  - [Project Index](#project-index)\n- [Internal Parsing Notes](#internal-parsing-notes)\n- [Getting Started](#getting-started)\n  - [Prerequisites](#prerequisites)\n  - [Installation](#installation)\n- [Contributing](#contributing)\n- [Cite Paper](#cite)\n- [Read Paper](#paper)\n\n---\n\n## Overview\n\nlibxfat is a Go library offering a robust and efficient solution for parsing and\nmanipulating ExFAT filesystems. It provides comprehensive tools for extracting\ndata and accessing metadata.\n\n**Why libxfat?**\n\nThis project simplifies ExFAT filesystem interaction for developers. The core\nfeatures include:\n\n- **🟢 Robust ExFAT Parsing:** Handles both contiguous and chained cluster\n  allocation schemes for reliable data extraction.\n- **🔵 Comprehensive Metadata Access:** Easily retrieve file size, attributes,\n  timestamps, and generate directory listings.\n- **🟡 Efficient Data Extraction:** Optimized for speed and performance when\n  working with large ExFAT volumes.\n- **🔴 Clear Data Structures:** Well-defined structs (VBR, Entry) simplify ExFAT\n  data manipulation and understanding.\n- **🟣 Thorough Error Handling:** Includes integrity checks and robust error\n  handling to prevent data loss.\n- **🟠 Well-Documented Code:** Clean, well-commented code ensures easy\n  integration and maintainability.\n\n## Internal Parsing Notes\n\nThe internal parser architecture and zero-copy boundaries are documented in\n[INTERNAL_PARSING.md](./INTERNAL_PARSING.md).\n\n---\n\n## Features\n\n|    | Component         | Details                                                                                                                                                                                |\n| :- | :---------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| ⚙️ | **Architecture**  | \u003cul\u003e\u003cli\u003ePure Go implementation\u003c/li\u003e\u003cli\u003eModular design with separate packages for different FAT functionalities\u003c/li\u003e\u003c/ul\u003e                                                               |\n| 🔩 | **Code Quality**  | \u003cul\u003e\u003cli\u003eGenerally well-structured code\u003c/li\u003e\u003cli\u003eUses descriptive variable and function names\u003c/li\u003e\u003cli\u003eSome areas could benefit from more comments\u003c/li\u003e\u003c/ul\u003e                              |\n| 📄 | **Documentation** | \u003cul\u003e\u003cli\u003eLimited documentation\u003c/li\u003e\u003cli\u003eRelies heavily on code comments for explanation\u003c/li\u003e\u003cli\u003eNo formal API documentation\u003c/li\u003e\u003c/ul\u003e                                                    |\n| 🔌 | **Integrations**  | \u003cul\u003e\u003cli\u003eDesigned to be easily integrated into other Go projects\u003c/li\u003e\u003cli\u003eNo external library dependencies beyond Go's standard library\u003c/li\u003e\u003c/ul\u003e                                        |\n| 🧩 | **Modularity**    | \u003cul\u003e\u003cli\u003eGood modularity with distinct packages for file system operations, directory handling, etc.\u003c/li\u003e\u003cli\u003eFacilitates independent testing and maintainability\u003c/li\u003e\u003c/ul\u003e              |\n| ⚡️ | **Performance**   | \u003cul\u003e\u003cli\u003ePerformance not explicitly optimized in the code\u003c/li\u003e\u003cli\u003eFurther analysis required to determine performance characteristics\u003c/li\u003e\u003c/ul\u003e                                          |\n| 🛡️ | **Security**      | \u003cul\u003e\u003cli\u003eNo explicit security measures implemented (e.g., input validation)\u003c/li\u003e\u003cli\u003eSecurity considerations need to be addressed for production use\u003c/li\u003e\u003c/ul\u003e                           |\n| 📦 | **Dependencies**  | \u003cul\u003e\u003cli\u003eOnly relies on the Go standard library\u003c/li\u003e\u003cli\u003eNo external dependencies, reducing complexity and potential conflicts\u003c/li\u003e\u003c/ul\u003e                                                 |\n| 🚀 | **Scalability**   | \u003cul\u003e\u003cli\u003eScalability depends on the application using the library\u003c/li\u003e\u003cli\u003eThe library itself is not inherently limited in scalability\u003c/li\u003e\u003cli\u003eTested with datasets up to 1TiB\u003c/li\u003e\u003c/ul\u003e |\n\n---\n\n## Project Structure\n\n```sh\n└── libxfat/\n    ├── README.md\n    ├── cluster.go\n    ├── const.go\n    ├── entry.go\n    ├── exfat.go\n    ├── go.mod\n    ├── go.sum\n    ├── struct.go\n    ├── util.go\n    └── vbr.go\n```\n\nThe module currently targets Go 1.25 as declared in `go.mod`.\n\n## Quick Start\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\n\t\"github.com/aoiflux/libxfat\"\n)\n\nfunc main() {\n\timageFile, err := os.Open(\"disk.exfat\")\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tdefer imageFile.Close()\n\n\tfs, err := libxfat.New(imageFile, false)\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\trootEntries, err := fs.ReadRootDir()\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\tfor _, entry := range rootEntries {\n\t\tfmt.Printf(\"name=%q size=%d dir=%t special=%t virtual=%t\\n\",\n\t\t\tentry.GetName(),\n\t\t\tentry.GetSize(),\n\t\t\tentry.IsDir(),\n\t\t\tentry.IsSpecialFile(),\n\t\t\tentry.IsVirtualEntry(),\n\t\t)\n\t}\n\n\tallocated, err := fs.GetAllocatedClusters()\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\tfmt.Printf(\"cluster size: %d bytes\\n\", fs.GetClusterSize())\n\tfmt.Printf(\"allocated clusters: %d\\n\", allocated)\n\tfmt.Printf(\"used space: %s\\n\", fs.GetUsedSpace())\n}\n```\n\nThe second argument to `libxfat.New` is `optimistic`:\n\n- `false`: strict mode, preferred for forensic use.\n- `true`: skip strict VBR offset verification when working with less reliable\n  images or embedded volumes.\n\nYou can also pass an optional sector offset if the exFAT filesystem starts\ninside a larger image:\n\n```go\nfs, err := libxfat.New(imageFile, false, 2048)\n```\n\n## Core API\n\n### Open And Inspect\n\n- `New(imagefile *os.File, optimistic bool, offset ...uint64) (ExFAT, error)`\n- `ReadRootDir() ([]Entry, error)`\n- `ReadDir(entry Entry) ([]Entry, error)`\n- `ReadDirs(entries []Entry) ([]Entry, error)`\n- `GetAllEntries(rootEntries []Entry, indexable ...bool) ([]Entry, error)`\n- `GetFullPathIndexableEntries(entries []Entry, path string) ([]Entry, error)`\n\n### Extract Data\n\n- `ExtractEntryContent(entry Entry, dstpath string) error`\n- `ExtractAllFiles(rootEntries []Entry, dstdir string) error`\n\n### Deleted Entry Recovery\n\n- `RecoverDeletedEntries() ([]Entry, error)`\n\n### Volume Statistics\n\n- `GetVolumeLabel() string`\n- `GetClusterSize() uint64`\n- `GetAllocatedClusters() (uint32, error)`\n- `GetFreeClusters() (uint32, error)`\n- `GetUsedSpace() string`\n- `CountClusters(entry Entry) (int, error)`\n- `GetClusterList(entry Entry) ([]uint32, uint64, error)`\n- `GetClusterOffset(cluster uint32) uint64`\n\n### Entry Helpers\n\nEach parsed directory item is represented by `Entry`. Common helpers include:\n\n- `GetName()`\n- `GetSize()`\n- `GetEntryCluster()`\n- `IsDir()` and `IsFile()`\n- `IsDeleted()`\n- `IsIndexed()`\n- `IsSpecialFile()`\n- `IsVirtualEntry()`\n- `HasFatChain()` and `DoesNotHaveFatChain()`\n\n## Special And Virtual Entries\n\n`ReadRootDir()` returns both normal filesystem entries and metadata entries.\n\nSpecial entries are real exFAT metadata records found in the image, including:\n\n- `$BitMap`\n- `$UpCase`\n- `$Volume GUID`\n- `$TexFAT`\n- `$ACT`\n\nVirtual entries are synthetic helpers added by the library to make filesystem\nmetadata easier to inspect from the root listing, including:\n\n- `$MBR`\n- `$FAT1`\n- `$FAT2`\n\nUse `entry.IsSpecialFile()` and `entry.IsVirtualEntry()` to distinguish them\nfrom regular files and directories.\n\n## Examples\n\nRunnable examples live under `examples/`.\n\n```bash\ngo run ./examples/list-root -image /path/to/volume.exfat\ngo run ./examples/list-all -image /path/to/volume.exfat\ngo run ./examples/volume-stats -image /path/to/volume.exfat\ngo run ./examples/extract-all -image /path/to/volume.exfat -out ./recovered\n```\n\nCommon flags:\n\n- `-image`: path to the exFAT image file.\n- `-optimistic`: skip strict VBR offset verification.\n- `-offset`: sector offset where the exFAT volume begins.\n\nThe example programs cover:\n\n- Listing root directory entries, including metadata and virtual entries.\n- Walking the full filesystem and printing full paths for indexable entries.\n- Reporting volume and allocation statistics.\n- Extracting all regular files into an output directory.\n\n## Testing\n\nRun the full test suite with:\n\n```bash\ngo test ./...\n```\n\nThe repository includes both package-level tests and higher-level tests under\n`tests/` that exercise:\n\n- VBR validation.\n- FAT loop and EOF-range handling.\n- Root directory parsing.\n- Virtual and special entry behavior.\n- Allocation bitmap counting.\n- Path-preserving extraction behavior.\n\n## Notes On Robustness\n\nRecent parser improvements in this repository include:\n\n- Better bounds checking when reading cluster-backed records.\n- Safer UTF-16 filename decoding.\n- Directory-set checksum validation.\n- Validation helpers for key exFAT directory record types.\n- More reliable handling of short bitmaps, FAT loops, and truncated images.\n\nSee `IMPROVEMENTS.md` for a more detailed implementation summary.\n\n## Repository Layout\n\n```text\n.\n|-- exfat.go          # high-level filesystem operations\n|-- vbr.go            # VBR parsing and volume metadata\n|-- cluster.go        # cluster traversal and content reads\n|-- entry.go          # directory-entry formatting helpers\n|-- struct.go         # core ExFAT, VBR, and Entry types\n|-- util.go           # shared parsing and formatting helpers\n|-- validators.go     # exFAT directory-record validation helpers\n|-- examples/         # runnable example programs\n`-- tests/            # higher-level behavioral tests\n```\n\n## Contributing\n\n- **🐛 [Report Issues](https://github.com/aoiflux/libxfat/issues)**: Submit bugs\n  found or log feature requests for the `libxfat` project.\n- **💡\n  [Submit Pull Requests](https://github.com/aoiflux/libxfat/blob/main/CONTRIBUTING.md)**:\n  Review open PRs, and submit your own PRs.\n\nIssues and pull requests are welcome. If you change parsing behavior, prefer\nadding or updating tests in the same change so malformed-image handling and\nmetadata behavior remain covered.\n\n## Citation\n\nGogia, G., \u0026 Rughani, P. (2024). Parex: A novel exfat parser for file system\nforensics. Computación y Sistemas, 28(2). https://doi.org/10.13053/cys-28-2-4804\n\n## Paper\n\n## [PAREX: A Novel exFAT Parser for File System Forensics](https://www.scielo.org.mx/scielo.php?script=sci_arttext\u0026pid=S1405-55462024000200421#:~:text=This%20research%20proposes%20a%20novel%20open-source%20exFAT%20file,of%20disk%20images%20ranging%20from%201MiB%20to%201TiB)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faoiflux%2Flibxfat","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faoiflux%2Flibxfat","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faoiflux%2Flibxfat/lists"}