{"id":48190498,"url":"https://github.com/vmallet/pakler","last_synced_at":"2026-04-04T17:55:09.607Z","repository":{"id":57450352,"uuid":"402487506","full_name":"vmallet/pakler","owner":"vmallet","description":"Tool to manipulate PAK firmware files for Swann and Reolink devices","archived":false,"fork":false,"pushed_at":"2024-11-19T07:45:04.000Z","size":44,"stargazers_count":22,"open_issues_count":2,"forks_count":1,"subscribers_count":4,"default_branch":"main","last_synced_at":"2024-11-19T08:37:16.392Z","etag":null,"topics":["firmware-tools","reolink","reverse-engineering","swann"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/vmallet.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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}},"created_at":"2021-09-02T16:21:02.000Z","updated_at":"2024-11-19T07:45:09.000Z","dependencies_parsed_at":"2024-11-19T08:26:40.092Z","dependency_job_id":"bd56e8bd-589b-4b58-92e1-972d1d4bfbb1","html_url":"https://github.com/vmallet/pakler","commit_stats":{"total_commits":24,"total_committers":1,"mean_commits":24.0,"dds":0.0,"last_synced_commit":"727af2ecf8c2afad3be13208c1f460ab0ff3c0e0"},"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/vmallet/pakler","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vmallet%2Fpakler","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vmallet%2Fpakler/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vmallet%2Fpakler/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vmallet%2Fpakler/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vmallet","download_url":"https://codeload.github.com/vmallet/pakler/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vmallet%2Fpakler/sbom","scorecard":{"id":925715,"data":{"date":"2025-08-04","repo":{"name":"github.com/vmallet/pakler","commit":"62dc878ff06326c8a92febbbcf2c15ea0d7db62d"},"scorecard":{"version":"v5.2.1-28-gc1d103a9","commit":"c1d103a9bb9f635ec7260bf9aa0699466fa4be0e"},"score":4.6,"checks":[{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#binary-artifacts"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#maintained"}},{"name":"Code-Review","score":3,"reason":"Found 7/18 approved changesets -- score normalized to 3","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#code-review"}},{"name":"Token-Permissions","score":9,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/release.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#token-permissions"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#dangerous-workflow"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:19: update your workflow using https://app.stepsecurity.io/secureworkflow/vmallet/pakler/release.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:21: update your workflow using https://app.stepsecurity.io/secureworkflow/vmallet/pakler/release.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/release.yml:31: update your workflow using https://app.stepsecurity.io/secureworkflow/vmallet/pakler/release.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/release.yml:37: update your workflow using https://app.stepsecurity.io/secureworkflow/vmallet/pakler/release.yml/main?enable=pin","Warn: pipCommand not pinned by hash: .github/workflows/release.yml:26","Warn: pipCommand not pinned by hash: .github/workflows/release.yml:27","Info:   0 out of   3 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   1 third-party GitHubAction dependencies pinned","Info:   0 out of   2 pipCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#security-policy"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#vulnerabilities"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#fuzzing"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#signed-releases"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#license"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#packaging"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'main'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 19 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-25T11:55:40.826Z","repository_id":57450352,"created_at":"2025-08-25T11:55:40.826Z","updated_at":"2025-08-25T11:55:40.826Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31407655,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-04T10:20:44.708Z","status":"ssl_error","status_checked_at":"2026-04-04T10:20:06.846Z","response_time":60,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["firmware-tools","reolink","reverse-engineering","swann"],"created_at":"2026-04-04T17:55:08.925Z","updated_at":"2026-04-04T17:55:09.598Z","avatar_url":"https://github.com/vmallet.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# pakler\n\nPakler is a command-line tool and library used to manipulate `.pak` firmware files\nused by Swann and Reolink devices. You can list, extract, and replace their\ncontent. It makes it easy to explore and patch firmwares used by various\nNVRs, DVRs and IP cameras.\n\n## Installing\n\nNote: pakler requires Python 3.6+\n\n### Recommended\n\n```shell\npip install pakler\n```\n\n### Manual\n\n```shell\ngit clone https://github.com/vmallet/pakler\ncd pakler\npip install .\n```\n\n## Usage\n\nThe main commands are:\n * get help: `pakler -h`\n * [list content](#viewing-content-of-pak-files): `pakler file.pak` (or `pakler -l file.pak`)\n * [extract content](#extracting-content-of-pak-files): `pakler file.pak -e -d \u003cdirectory\u003e`\n * [replace content](#replacing-content-of-pak-files): `pakler file.pak -r -n ... -f ... -o newfile.pak`\n\nHelp can be had with:\n```shell\npakler -h\n```\n\nNote: list and extract also work with ZIPs that contain `.pak` files.\n\n### Viewing content of `.pak` files\n\nListing the contents of a `.pak` file is pretty straightforward: invoke the\ntool with the name of the firmware file on the command line.\n\n```shell\npakler NVR8-7400_1705_3438_1103.pak\n```\n\n```\nHeader  magic=32725913  crc32=0250e72d  type=00002302  sections=\u003c10\u003e  mtd_parts=\u003c10\u003e\n    Section  0 name=\"uboot1\"         version=\"v1.0.0.1\"       start=0x00000584  len=0x000437d0  (start=    1412 len=  276432)\n    Section  1 name=\"\"               version=\"\"               start=0x00043d54  len=0x00000000  (start=  277844 len=       0)\n    Section  2 name=\"bootargs\"       version=\"v1.0.0.1\"       start=0x00043d54  len=0x00020000  (start=  277844 len=  131072)\n    Section  3 name=\"kernel\"         version=\"v1.0.0.1\"       start=0x00063d54  len=0x0023fdc8  (start=  408916 len= 2358728)\n    Section  4 name=\"fs\"             version=\"v1.0.0.442\"     start=0x002a3b1c  len=0x00402000  (start= 2767644 len= 4202496)\n    Section  5 name=\"app\"            version=\"v1.0.0.421\"     start=0x006a5b1c  len=0x00947000  (start= 6970140 len= 9728000)\n    Section  6 name=\"\"               version=\"\"               start=0x00fecb1c  len=0x00000000  (start=16698140 len=       0)\n    Section  7 name=\"logo\"           version=\"v1.0.0.1\"       start=0x00fecb1c  len=0x0000f1fd  (start=16698140 len=   61949)\n    Section  8 name=\"\"               version=\"\"               start=0x00ffbd19  len=0x00000000  (start=16760089 len=       0)\n    Section  9 name=\"\"               version=\"\"               start=0x00ffbd19  len=0x00000000  (start=16760089 len=       0)\n    Mtd_part name=\"uboot1\"         mtd=\"/dev/mtd9\"       a=0x00000000  start=0x00000000  len=0x00080000\n    Mtd_part name=\"uboot2\"         mtd=\"/dev/mtd9\"       a=0x00080000  start=0x00080000  len=0x001e0000\n    Mtd_part name=\"bootargs\"       mtd=\"/dev/mtd9\"       a=0x00260000  start=0x00260000  len=0x00020000\n    Mtd_part name=\"kernel\"         mtd=\"/dev/mtd9\"       a=0x00280000  start=0x00280000  len=0x00440000\n    Mtd_part name=\"fs\"             mtd=\"/dev/mtd9\"       a=0x006c0000  start=0x006c0000  len=0x00c00000\n    Mtd_part name=\"app\"            mtd=\"/dev/mtd9\"       a=0x012c0000  start=0x012c0000  len=0x02000000\n    Mtd_part name=\"para\"           mtd=\"/dev/mtd9\"       a=0x032c0000  start=0x032c0000  len=0x00800000\n    Mtd_part name=\"logo\"           mtd=\"/dev/mtd9\"       a=0x03ac0000  start=0x03ac0000  len=0x00200000\n    Mtd_part name=\"ipc_img\"        mtd=\"/dev/mtd9\"       a=0x03cc0000  start=0x03cc0000  len=0x00b00000\n    Mtd_part name=\"version\"        mtd=\"/dev/mtd9\"       a=0xffffffff  start=0xffffffff  len=0x00000000\nFile passes CRC check: NVR8-7400_1705_3438_1103.pak\n```\n\n### Extracting content of `.pak` files\n\nContents of a `.pak` file can be extracted using the `-e` command. If no\noutput directory is specified using the `-d` parameter, a default unique\noutput directory will be created by appending `.extracted` to the name of\nthe `.pak` file.\n\nexample:\n```shell\npakler ./NT98312_NVR_8IP_REOLINK_L300_130_21060706.pak -e -d newdir\n```\n```\noutput: newdir\nExtracting section 0 (131072 bytes) into newdir/00_header.bin\nExtracting section 1 (18096 bytes) into newdir/01_loader.bin\nExtracting section 2 (26404 bytes) into newdir/02_fdt.bin\nExtracting section 3 (414552 bytes) into newdir/03_uboot.bin\nExtracting section 4 (3022896 bytes) into newdir/04_kernel.bin\nExtracting section 5 (12210176 bytes) into newdir/05_fs.bin\nExtracting section 6 (17113088 bytes) into newdir/06_app.bin\nSkipping empty section 7\nExtracting section 8 (122036 bytes) into newdir/08_logo.bin\nSkipping empty section 9\nSkipping empty section 10\n```\n\n### Replacing content of `.pak` files\n\nA `.pak` file is made up of multiple sections, and at the moment you can\nreplace only one section at a time. To replace a section you need to \nuse the `-r` command, specify the number of the section to replace with `-n`,\nthe file to use as a replacement with `-f`, and the output file to write\nthe resulting patched file with `-o`.\n\nHere is an example where we replace the `.pak` file's section #5 with the\nfile `patched_fs.bin`\n\n```shell\npakler NT98312_NVR_8IP_REOLINK_L300_130_21060706.pak -r -n 5 -f patched_fs.bin -o patched_fw.pak\n````\n\n```\nInput            : NT98312_NVR_8IP_REOLINK_L300_130_21060706.pak\nOutput           : patched_fw.pak\nReplacing section: 5\nReplacement file : new_fs.bin\nCopying section 0 (131072 bytes)\nCopying section 1 (18096 bytes)\nCopying section 2 (26404 bytes)\nCopying section 3 (414552 bytes)\nCopying section 4 (3022896 bytes)\nReplacing section 5 (12210176 bytes) with 12211578 bytes\nCopying section 6 (17113088 bytes)\nCopying section 7 (0 bytes)\nCopying section 8 (122036 bytes)\nCopying section 9 (0 bytes)\nCopying section 10 (0 bytes)\nWriting header... (1552 bytes)\nUpdating CRC...\nReplacement completed. New header:\nHeader  magic=32725913  crc32=41ee801c  type=00006202  sections=\u003c11\u003e  mtd_parts=\u003c11\u003e\n    Section  0 name=\"header\"         version=\"v1.0.0.0\"       start=0x00000610  len=0x00020000  (start=    1552 len=  131072)\n    Section  1 name=\"loader\"         version=\"v1.0.0.0\"       start=0x00020610  len=0x000046b0  (start=  132624 len=   18096)\n    Section  2 name=\"fdt\"            version=\"v1.0.0.0\"       start=0x00024cc0  len=0x00006724  (start=  150720 len=   26404)\n    Section  3 name=\"uboot\"          version=\"v1.0.0.0\"       start=0x0002b3e4  len=0x00065358  (start=  177124 len=  414552)\n    Section  4 name=\"kernel\"         version=\"v1.0.0.0\"       start=0x0009073c  len=0x002e2030  (start=  591676 len= 3022896)\n    Section  5 name=\"fs\"             version=\"v1.0.0.0\"       start=0x0037276c  len=0x00ba557a  (start= 3614572 len=12211578)\n    Section  6 name=\"app\"            version=\"v1.0.0.0\"       start=0x00f17ce6  len=0x01052000  (start=15826150 len=17113088)\n    Section  7 name=\"\"               version=\"\"               start=0x01f69ce6  len=0x00000000  (start=32939238 len=       0)\n    Section  8 name=\"logo\"           version=\"v1.0.0.0\"       start=0x01f69ce6  len=0x0001dcb4  (start=32939238 len=  122036)\n    Section  9 name=\"\"               version=\"\"               start=0x01f8799a  len=0x00000000  (start=33061274 len=       0)\n    Section 10 name=\"\"               version=\"\"               start=0x01f8799a  len=0x00000000  (start=33061274 len=       0)\n    Mtd_part name=\"header\"         mtd=\"/dev/mtd9\"       a=0x00000000  start=0x00000000  len=0x00020000\n    Mtd_part name=\"loader\"         mtd=\"/dev/mtd9\"       a=0x00020000  start=0x00020000  len=0x00080000\n    Mtd_part name=\"fdt\"            mtd=\"/dev/mtd9\"       a=0x000a0000  start=0x000a0000  len=0x00080000\n    Mtd_part name=\"uboot\"          mtd=\"/dev/mtd9\"       a=0x00120000  start=0x00120000  len=0x000e0000\n    Mtd_part name=\"kernel\"         mtd=\"/dev/mtd9\"       a=0x00200000  start=0x00200000  len=0x00500000\n    Mtd_part name=\"fs\"             mtd=\"/dev/mtd9\"       a=0x00700000  start=0x00700000  len=0x00f00000\n    Mtd_part name=\"app\"            mtd=\"/dev/mtd9\"       a=0x01600000  start=0x01600000  len=0x02000000\n    Mtd_part name=\"para\"           mtd=\"/dev/mtd9\"       a=0x03600000  start=0x03600000  len=0x00800000\n    Mtd_part name=\"logo\"           mtd=\"/dev/mtd9\"       a=0x03e00000  start=0x03e00000  len=0x00100000\n    Mtd_part name=\"uid\"            mtd=\"/dev/mtd9\"       a=0x03f00000  start=0x03f00000  len=0x00100000\n    Mtd_part name=\"version\"        mtd=\"/dev/mtd9\"       a=0xffffffff  start=0xffffffff  len=0x00000000\n```\n\n### As a library\n\nHere are a few things you can do with pakler's API:\n\n```py\nfrom pakler import PAK\n\nwith PAK.from_file(\"firmware.pak\") as pak:  # Also from_bytes() and from_fd()\n    assert pak.crc == pak.calc_crc()\n    pak.extract(\"firmware_extracted\")\n    print(pak.partitions)\n    section = pak.sections[0]\n    pak.save_section(section, f\"{section.name}.bin\")\n    section_bytes = pak.extract_section(section)\n```\n\n## Naming\n\nWhy pakler? Take a **pak** and **L**ist it, **E**xtract it, or **R**eplace \nparts of it... pakler? Makes sense! (Naming suggestions are welcome :) )\n\n## Version history\n\n* v0.2.0 - 2023/05/31 - The [AT0myks](https://github.com/AT0myks) release\n  \n  A big thanks to AT0myks for all the changes brought in this release.\n  - Make Pakler usable as a library (author: AT0myks)\n  - Support for 64-bit PAK files (author: AT0myks)\n  - Support for handling PAK files directly from ZIP archives (author: AT0myks)\n  - Several code layout and packaging improvements (author: AT0myks)\n\n* v0.1.0 - 2021/09/03 - Initial release\n\n## Licensing\n\npakler is licensed under MIT license. See [LICENSE](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvmallet%2Fpakler","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvmallet%2Fpakler","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvmallet%2Fpakler/lists"}