{"id":20167389,"url":"https://github.com/throwaway96/downgr8","last_synced_at":"2025-07-04T23:35:00.740Z","repository":{"id":217548930,"uuid":"743554179","full_name":"throwaway96/downgr8","owner":"throwaway96","description":"LG webOS downgrade tool","archived":false,"fork":false,"pushed_at":"2024-03-19T01:57:52.000Z","size":27,"stargazers_count":18,"open_issues_count":2,"forks_count":5,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-06-10T01:16:30.159Z","etag":null,"topics":["downgrade","firmware","lg","tv","webos"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/throwaway96.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","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},"funding":{"github":["throwaway96"],"ko_fi":"throwaway96"}},"created_at":"2024-01-15T13:38:18.000Z","updated_at":"2025-05-28T11:24:59.000Z","dependencies_parsed_at":null,"dependency_job_id":"412638f7-14b3-4477-8290-e0a770e4a64d","html_url":"https://github.com/throwaway96/downgr8","commit_stats":null,"previous_names":["throwaway96/downgr8"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/throwaway96%2Fdowngr8","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/throwaway96%2Fdowngr8/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/throwaway96%2Fdowngr8/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/throwaway96%2Fdowngr8/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/throwaway96","download_url":"https://codeload.github.com/throwaway96/downgr8/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/throwaway96%2Fdowngr8/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259112354,"owners_count":22807070,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["downgrade","firmware","lg","tv","webos"],"created_at":"2024-11-14T00:51:43.093Z","updated_at":"2025-06-10T16:36:18.665Z","avatar_url":"https://github.com/throwaway96.png","language":"C","funding_links":["https://github.com/sponsors/throwaway96","https://ko-fi.com/throwaway96"],"categories":[],"sub_categories":[],"readme":"# downgr8\n\nThis is a tool for launching the \"expert mode\" update UI on LG webOS TVs. It\nworks on firmware versions where the [easier method](#old-method) of\naccessing expert mode has been removed. So far, little to no provision has been\nmade for novice users.\n\n**Note that this tool requires you to already have root access on your TV.**\n\n\n## Warning\n\n**Use this tool at your own risk.** It has not been thoroughly tested\u0026mdash;or,\nin some cases, tested at all. It's intended for people who already know what\nthey're doing. I will probably not provide any support.\n\nThe C part is pretty reliable, and the service seems to mostly work. However,\nthe app, which consists of a script that makes a series of requests to the\nservice, may or may not work. I recommend using it primarily as an example of\nthe order in which to call the service's methods.\n\n\n### General downgrade warning\n\nBe aware that firmware downgrades have never really been supported by LG. I have\nnot personally encountered any issues, but it's possible that you could get your\nTV into an unrecoverable state (i.e., \"brick\" it). Be especially careful on\nwebOS 4+ TVs, as it's easier to get those into a state where\n[recovery](#recovery) is impossible.\n\nI would suggest using USB rather than NSU images whenever possible. Because they\nare intended to update a TV from one mostly known state to another, NSU images\noften do not contain data for all of the TV's partitions. In some situations,\nNSU updates are intended to be applied in a certain order, and I don't know if\nor how this could affect downgrading. USB images, which are the kind you can\ndownload from LG's support site, seem to always contain all partitions.\n\nMake sure you are using the right firmware image for your TV. In particular,\nensure you have the correct:\n\n  1. **Version** \u0026ndash; Keep in mind exactly what version you intend to install.\n  2. **Region** \u0026ndash; Through webOS 5, there are separate firmware images for\n   each tuner type (`atsc`, `dvb`, `arib`). Starting with webOS 6, there should\n   only be universal (`global`) images.\n  3. **SoC** \u0026ndash; I'm not sure whether `update` will let you install firmware\n   for the wrong SoC, but I'd rather not find out.\n\nEvery TV and firmware image have an identifier called an OTAID that encodes the\nSoC and tuner type. Don't try to install any firmware that doesn't match your\nTV's OTAID. You can get your TV's OTAID by running this command from a root\nshell:\n\n```sh\nluna-send -q 'model_name' -n 1 'luna://com.webos.service.update/getCurrentSWInformation' '{}'\n```\n\nThe OTAID of a firmware image is displayed when extracting it using\n[`epk2extract`](https://github.com/openlgtv/epk2extract).\n\n\n## Requirements\n\n1. TV running LG webOS 3.0+ and firmware that has the [old method](#old-method)\n   of accessing expert mode patched.\n2. Root access to your TV.\n3. [Homebrew Channel](https://github.com/webosbrew/webos-homebrew-channel)\n   installed and elevated (i.e., showing \"root status: ok\") on your TV.\n\nHomebrew Channel is not strictly necessary as long as you can make sure the\n`lol.downgr8.service` service is running as root.\n\n\n## Details\n\nIn order to install older firmware versions (downgrade) or install firmware\nimages with a type other than \"USB\" (e.g., NSU images), the webOS `update`\nservice needs to be in \"expert mode\".\n\nPrior to early 2022, this could be accomplished [relatively simply](#old-method)\nwithout root access. However, around the same time LG patched the\nvulnerabilities used by\n[RootMyTV](https://github.com/RootMyTV/RootMyTV.github.io/), they also changed\n`update` to no longer rely on an easily modifiable external file to control\nexpert mode.\n\nSince this patch, `update` keeps track of the state of expert mode internally\nand refuses to enable it unless one of LG's \"Access USB\" devices is connected\nand authenticated. Obtaining or emulating Access USB hardware is not feasible,\nbut with root access it is not necessary. We can simply convince `update` that\nan Access USB device is present and authenticated regardless of reality.\n\nThere are multiple ways to accomplish this, and the method I chose was inspired\nby [David Buchanan's](https://github.com/DavidBuchanan314)\n[`sampatcher.py`](https://github.com/webosbrew/webos-homebrew-channel/blob/main/services/bin/sampatcher.py).\n\nBy editing a Luna URI in `update`'s memory, we can redirect future Access USB\nrequests to our own service. We then trigger `update` to recheck the current\nAccess USB status and reply that it is authenticated. Now we can successfully make\na request to enable expert mode.\n\nAll that remains is launching the update UI app with the correct parameters.\n\n\n## Old Method \u003ca id=\"old-method\"\u003e\u003c/a\u003e\n\nFor older firmware, this tool is not necessary because the following still\nworks:  \n\n```sh\ntouch /tmp/usb-expertmode\nluna-send -n 1 'luna://com.webos.applicationManager/launch' '{\"id\":\"com.webos.app.softwareupdate\",\"params\":{\"mode\":\"expert\",\"flagUpdate\":true}}'\n```\n\nThis method was also never removed on webOS 1 and 2.\n\nIt works because the `update` service uses the existence of the file\n`/tmp/usb-expertmode` to track whether expert mode is enabled. Since it's\nlocated in `/tmp`, which is writable by anyone, root access is not required to\ncreate it.\n\nYou can check whether this has been patched on your TV by running the following\nas root:\n\n```sh\nstrings /usr/sbin/update | fgrep -e /tmp/usb-expertmode\n```\n\nIf you get any output, this method should still work on your TV.\n\n\n## Recovery from failed downgrade/upgrade \u003ca id=\"recovery\"\u003e\u003c/a\u003e\n\nIt *may* be possible to recover a non-booting TV if you can get into the\nbootloader (U-Boot or lxboot). Bootloader access requires that the TV be in\nDEBUG mode.\n\nOn webOS 3.x and earlier (i.e., 2015‒2017 models), you can enable DEBUG by\n[directly modifying the setting in\nNVM](https://gist.github.com/throwaway96/827ff726981cc2cbc46a22a2ad7337a1).\nWhile the process is relatively straightforward, it does require certain\nhardware tools and physical access to a chip on the TV's main board. On webOS 4\nand newer, you will not be able to enable DEBUG if the system does not boot.\n\nFrom the bootloader, you can manually rewrite the contents of each corrupted\npartition on the eMMC. Partition data files can be extracted from firmware\nimages using [`epk2extract`](https://github.com/openlgtv/epk2extract).\nPotential methods for transferring these files to the TV include USB drives,\nTFTP over Ethernet, and Xmodem.\n\nIf you have webOS 4 or later and did not previously enable DEBUG, the only\noption for recovery is directly reprogramming the eMMC. That would involve\neither soldering wires to the board on the necessary signals (if you can find\nthem; accessing them may involve scraping away soldermask) or desoldering and\nresoldering the eMMC IC.\n\n\n## License\n\nThis program is free software: you can redistribute it and/or modify it under\nthe terms of the GNU Affero General Public License as published by the Free\nSoftware Foundation, either version 3 of the License, or (at your option) any\nlater version.\n\nThis program is distributed in the hope that it will be useful, but WITHOUT ANY\nWARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A\nPARTICULAR PURPOSE. See the GNU Affero General Public License for more details.\n\nYou should have received a copy of the GNU Affero General Public License along\nwith this program. If not, see \u003chttps://www.gnu.org/licenses/\u003e.\n\nSee `LICENSE` for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthrowaway96%2Fdowngr8","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthrowaway96%2Fdowngr8","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthrowaway96%2Fdowngr8/lists"}