Analysis, extraction, and rebuild tool for .lgu firmware files of LG Gen5 head
units (NXP i.MX6 / Windows CE, Aerith updater, LG EU20 format).
A single self-contained Windows executable, usable as a graphical application or as a command-line tool. No Python or external dependency required to run it.
Downloads the executable from the latest release.
Warning
A rebuilt or modified .lgu is not validated for flashing. A byte-identical
round trip (selftest) proves that the tool understands the file format. It does
not prove that the head unit's flasher will accept a file whose content you
changed, or that the device will boot afterwards. Do not flash a rebuilt or
modified file until it has been tested on a bench unit, following the
bench test and rollback procedure below.
Home screen — choose Decompile, Recompose, or Compile:
Content view — files carved from a firmware dump:
- Recognizes an LG EU20
.lgufile, decrypts its header and zone blocks, and shows every zone with its position, size, and CRC. - Checks a whole file: structure, the checks done by the head unit, and the CRC-32 of the 7 zones.
- Unpacks a
.lguinto one image per zone plus amanifest.json, and repacks that folder into a.lgu. An unchanged folder repacks to a byte-identical file. - Builds a
.lgufrom 7 zone images and metadata. - Recomposes a
.lgu: replaces, adds, extracts, or deletes programs and folders in the SYS and USER partitions (exFAT), then rebuilds the file. Zone sizes stay unchanged. - Refuses any zone image whose size differs from the sizes hard-coded in the head unit, before writing anything.
- Reads, extracts, or replaces the embedded Aerith (the program run by the head unit's "Update" button).
- Lists the embedded files (programs / DLLs) with name, type, architecture, offset, and size; filter and sort.
- Entropy map (colored, also in the terminal), full-file search in ASCII, UTF-16, or HEX, extraction of a file, of all files, or of a raw byte range.
- Per-version password profiles, managed from the UI.
- Nine interface languages with automatic detection and a manual selector.
Run lgu-manager.exe (double-click, or launch with no arguments).
- Decompile: open a
.lgu. The Overview tab shows its zones; the Extract tab can unpack it to a folder or verify all its zones. - Recompose: open a
.lgu(it is unpacked into a work folder) or an already unpacked folder. Browse the SYS or USER partition, then replace, add, extract, or delete files and create folders. Changes are written immediately to the images in the work folder; the original.lguis never modified. Compile the .lgu checks both partitions, then repacks the folder. - Compile: build a
.lgufrom 7 zone images, repack an unpacked folder, or run the round-trip self-test on a.lgu.
lgu-manager info file.lgu
lgu-manager verify file.lgu [--profile NAME]
lgu-manager unpack file.lgu --out DIR [--profile NAME]
lgu-manager pack DIR --out file.lgu [--profile NAME]
lgu-manager build --zone NAME=PATH ... --out file.lgu [--meta KEY=VAL ...] [--profile NAME]
lgu-manager selftest file.lgu [--work DIR] [--keep] [--profile NAME]
lgu-manager aerith file.lgu [--out Aerith.exe] [--profile NAME]
lgu-manager set-aerith file.lgu NEW_Aerith.exe [--profile NAME]
lgu-manager list file.lgu [--filter NAME] [--sort name|type|machine|offset|size] [--json]
lgu-manager map file.lgu [--width N] [--no-color]
lgu-manager search file.lgu PATTERN [--mode ascii|utf16|hex] [--limit N]
lgu-manager crc file.lgu --off 0x.. --len 0x.. [--expect N]
lgu-manager extract file.lgu (--off 0x.. --len 0x.. | --index N | --name NAME) --out PATH
lgu-manager extract-all file.lgu --out DIR [--filter NAME]
lgu-manager header file.lgu [--profile NAME]
lgu-manager decrypt-header file.lgu --out out.lgu [--profile NAME]
lgu-manager sign-header file.lgu --out out.lgu [--profile NAME]
lgu-manager profiles
lgu-manager fs-ls DIR ZONE[:/path]
lgu-manager fs-get DIR ZONE:/path --out FILE
lgu-manager fs-put DIR ZONE:/folder FILE [FILE ...]
lgu-manager fs-mkdir DIR ZONE:/path
lgu-manager fs-rm DIR ZONE:/path
lgu-manager fs-check DIR [ZONE]
verifydecrypts every block, applies the header checks of the head unit, and recomputes the CRC-32 of the 7 zones.unpackwritesOS.img,SYS.img,USER.img,TTS.img,UBACKUP.img,DATALOGS.img,Aerith.exe, andmanifest.json(the 11 header texts). Replace images or edit the header texts, thenpackthe folder.buildneeds all 7 zones:OS,SYS,USER,TTS,UBACKUP,DATALOGS,AERITH. Metadata keys:OS_VER,HW,SYS_VER,NAVI,TTS_VER,AERITH_VER,MICOM_VER(15 values separated by commas),GPS_VER,DAB_VER,CAR,LOC,GATE,DATE,OPT. Defaults are neutral values; unpacking an official file and repacking it is the safer way to get a valid header.packandbuildrefuse any zone image whose size is not exactly the size hard-coded in the head unit. The message gives the expected and the received size, and no file is written. Output is written to<out>.partand renamed only when complete.selftestis the round-trip test: it unpacks the file, repacks it, and checks that the MD5 is identical; then it runsset-aerithwith the extracted Aerith on a copy, and checks that the MD5 is identical again. It needs about twice the file size of free space in its work folder (system temp folder by default), which it deletes at the end unless--keepis given.aerithreads and checks the embedded Aerith.set-aerithreplaces it in place, exactly as the Aerith writer would (header size, CRC block, end-of-slot bytes, end flag).fs-*work on a folder produced byunpack.ZONEisSYS(the\MMCMemory\Storage Cardpartition: Lisa, Homer…) orUSER(the\USERpartition: Aerith…).fs-putadds the files to the folder, or replaces a file with the same name (case-insensitive). Free space is checked before anything is written.fs-rmdeletes a file or an empty folder.fs-checkchecks the consistency of the partitions (entry checksums, name hashes, allocation bitmap, cluster chains). Then runpackon the folder.decrypt-headerwrites a copy with a plaintext header, for analysis only: the head unit refuses it.sign-headerre-encrypts it.
Global options: --lang {en,fr,es,de,it,ru,zh,ja,ko}, --no-color, placed
before the command. Run lgu-manager --help for the full reference.
Examples:
lgu-manager verify eu20_upgrade.lgu
lgu-manager unpack eu20_upgrade.lgu --out work
lgu-manager pack work --out eu20_upgrade_new.lgu
lgu-manager extract eu20_upgrade.lgu --name Lisa --out Lisa.exe
lgu-manager fs-put work "SYS:/storage card/SYSTEM" MyProgram.exe
lgu-manager fs-check work
lgu-manager pack work --out eu20_upgrade_new.lgu
Everything below was established on an official LG .lgu, and confirmed in the
code that reads it on the head unit: the HMI (Lisa.exe, class CExtraction)
and the flasher (Aerith.exe 5.1.4.0).
| Offset | Size | Content |
|---|---|---|
0x0000 |
11 × 0x200 |
Header: one text slot per zone (OS, SYS, USER, TTS, UBACKUP, DATALOGS, MICOM, GPS, DAB, AERITH, INFO) |
0x1600 |
0x200 + 0x8c00000 + 0x20 |
OS zone (raw eMMC sectors 0 to 0x46000) |
| … | 0x200 + 0x2ee00000 + 0x20 |
SYS zone (written to both SYS_1 and SYS_2) |
| … | 0x200 + 0x3200000 + 0x20 |
USER zone |
| … | 0x200 + 0x67c28000 + 0x20 |
TTS zone |
| … | 0x200 + 0x3200000 + 0x20 |
UBACKUP zone |
| … | 0x200 + 0xcedd400 + 0x20 |
DATALOGS zone |
0xb29076c0 |
0x200 + exe size + 0x20 |
Embedded Aerith, end of file |
- Each zone is
[CRC block 0x200][data][end flag 0x20]. MICOM, GPS, and DAB always have size 0 and take no bytes. - Fixed sizes. The zone sizes and positions are hard-coded in both readers; only the Aerith size is free, because it is the last zone.
- Encryption. Every header slot, CRC block, and end flag is RC4-encrypted,
with key
MD5(password.encode("utf-16le")[:len(password)])and one password per (zone, block type). Both readers decrypt unconditionally, so a plaintext header is refused. - CRC. Plain CRC-32 (zlib, seed 0) of the whole zone data. The OS block
carries two values: the first covers its first
0x3d88400bytes, the second the whole zone. - No signature. There is no signature anywhere.
- End flags. They are written but never checked by either reader.
| Zone | File system | Mount point on the head unit | Free space (official EU20 file) |
|---|---|---|---|
| SYS | exFAT, 4 KB clusters, boot sector at +0x200 |
\MMCMemory\Storage Card |
about 4.4 MB |
| USER | exFAT, 512-byte clusters, boot sector at +0x400 |
\USER |
about 39.8 MB |
The SYS partition is almost full: a larger program only fits if it replaces a file of a similar size. The other zones (TTS, UBACKUP, DATALOGS: FAT32; OS: raw boot sectors and OS image) cannot be edited by the tool.
A .lgu built or modified by this tool (pack with changed content, build,
set-aerith, Recompose / fs-*) is experimental. A byte-identical round trip only shows that
the tool reproduces the format. Before using such a file on a device:
- Check the file. Run
verifyon it andselfteston the official file you started from. Both must pass. - Keep the official file. Keep an untouched copy of the official
.lgu(note its MD5) on a separate SD card. - Use a bench unit. Test on a head unit powered from a bench supply, never in a vehicle first. Start with the smallest possible change.
- Watch the update. Do not cut the power during an update.
Rollback. Put the untouched official .lgu back on the SD card and run the
update again: the flasher rewrites every zone. The Aerith flasher also writes
the OS to the inactive bank (A/B) before switching, keeps a USER backup
partition, and has a recovery mode for interrupted updates. These mechanisms are
read from the Aerith code, but have not been exercised with files produced
by this tool.
Requires Python 3.9+ (standard library only). To produce the executable:
pip install pyinstaller
python build.py
The build output goes to dist/lgu-manager.exe. The version number lives in
lgu_core.VERSION; build.py writes it into the executable's Windows file
properties. lgu-manager --version prints it.
python -m unittest test_lgu
The fast tests need no .lgu file. Set LGU_FILE to an official .lgu to also
run the tests on a real file, including the byte-identical round trip:
LGU_FILE=path/to/eu20_upgrade.lgu python -m unittest test_lgu
- Password profiles: the default profile opens the EU20 files studied; other versions may use other passwords.
- Windows only.

