Library / SDK
jtsylve/LiME avatar
jtsylve/LiME

LiME: forensic memory acquisition from Linux and Android as a kernel module

LiME (formerly DMD) is a Loadable Kernel Module (LKM), which allows the acquisition of volatile memory from Linux and Linux-based devices, such as those powered by Android. The tool supports acquiring memory either to the file system of the device or over the network. LiME is unique in that it is the first tool that allows full memory captures from Android devices. It also minimizes its interaction between user and kernel space processes during acquisition, which allows it to produce memory captures that are more forensically sound than those of other tools designed for Linux memory acquisition.

2,053 stars376 forksCGPL-2.0

At a glance

What is it?
LiME is a Loadable Kernel Module that captures volatile memory from Linux and Android systems to a local file or over TCP in three output formats. Its optional digest and compression flags both disturb more of the target system's memory than a baseline acquisition, which is the central tension in its design.
Who is it for?
LiME fits when you need forensic memory acquisition from a Linux or Android system and can compile a kernel module for the running kernel. The module approach reduces interaction with the target system compared to userspace alternatives.
Can I use it commercially?
Yes, with conditions. GPL-2.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
Is it still maintained?
Activity is slowing. The repository last received commits 6 months ago.
What is it written in?
Mainly C, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

From daily snapshots

Star history

  • jtsylve/LiME2,053 ★ · +6
Star history
Repository2026-10-112026-10-23
jtsylve/LiME2k2.1k

6 Stars in the last 12 days, measured from the daily GitHub snapshot. Compare with other projects

Editorial analysis

Kernel module placement reduces interaction with the system under acquisition

Loading LiME as a kernel module is a design choice about where the acquisition process lives. An acquisition tool that runs in userspace makes kernel API calls to read memory, and those calls can alter contents before the snapshot is complete. Keeping the acquisition path inside the kernel removes that interaction, which is why the project claims its captures are more forensically sound than those of other tools designed for Linux memory acquisition.

Joe Sylve first presented LiME at Shmoocon 2012 under the name DMD. Android support is described in the project as a category first: it is the first tool that allows full memory captures from Android devices. That distinction held because Android devices run Linux kernels but existing memory acquisition tools could not capture their full memory. Loading the kernel module via adb and insmod closes that gap without introducing a separate agent process.

Module file naming includes the running kernel version string: lime-$(uname -r).ko. A LiME module compiled for one kernel version will not load on a different one, which makes the build step non-trivial for incident response on unfamiliar hardware. Source lives in the src/ directory at the repository root, and the docs/ directory holds more detail on internals and usage.

Three output formats, and why raw loses position information

The format parameter accepts three values and is required. Lime prepends each memory range with a fixed-size header containing address space information. Padded fills all non-System RAM ranges with zeros, starting from physical address 0. Raw concatenates all System RAM ranges without any structure.

Raw gets an explicit warning in the documentation: without position headers, any forensics tool that needs to know which physical address a byte came from cannot reconstruct that from the output. Lime and padded avoid this by embedding structural data alongside the memory contents. Raw is documented as not suited for general use.

Lime is the format every example in the repository uses. Choosing raw requires knowing how your specific analysis tool reconstructs position from a bare stream, and the project documentation does not describe that reconstruction process.

Loading the module and writing a local memory capture

Loading uses insmod with its arguments as a quoted string. To write a full memory capture to a local file:

bash
insmod ./lime-$(uname -r).ko "path=/tmp/ram.lime format=lime"

Both path and format are required arguments. Omitting either will prevent the module from loading. For network acquisition, the path argument takes a tcp: prefix followed by a port number:

bash
insmod ./lime-$(uname -r).ko "path=tcp:4444 format=lime"

Then on the receiving machine:

bash
nc <target-ip> 4444 > ram.lime

The localhostonly parameter defaults to 0, which binds the TCP listener on all network interfaces. Setting localhostonly=1 restricts it to listen on localhost only. For acquisitions in shared network environments, this flag provides the only documented access restriction on who can connect to the listening port.

A timeout parameter defaults to 1000 milliseconds per page. When a page read or write exceeds that threshold, the rest of the memory range is skipped rather than blocking indefinitely. This feature is available on kernels 2.6.35 and newer. Setting timeout=0 disables the limit entirely, allowing slow memory regions to be fully read.

TCP acquisition and the two-connection requirement for network digest collection

Digest collection over TCP requires two separate connections to the target. An operator following only the main TCP example would miss this: the requirement appears in the Available Digests section, not in the Examples section. On the receiving machine, two separate netcat calls collect the dump and the hash file:

bash
nc localhost 4444 > ram.lime
nc localhost 4444 > ram.sha1

Each connection receives a different stream. The dump arrives on the first connection, and the digest connection must be established while the module is still running. The sidecar file name is the output path with the digest algorithm appended, for example ram.lime.sha256.

Algorithm availability follows kernel version boundaries. SHA-1, SHA-256 and the MD family require kernel 2.6.11 or newer. RIPEMD variants including rmd128, rmd160, rmd256 and rmd320 require kernel 3.0 or newer. SHA-3 variants including sha3-224, sha3-256, sha3-384 and sha3-512 require kernel 4.10 or newer. Any algorithm available in the running kernel's crypto library can be used; the above lists serve as quick reference.

Android memory capture via adb, port forwarding and insmod

The Android acquisition path uses adb to push the module to the device, set up port forwarding, and load the module:

bash
adb push lime.ko /sdcard/lime.ko
adb forward tcp:4444 tcp:4444
adb shell
su
insmod /sdcard/lime.ko "path=tcp:4444 format=lime"

Then on the host machine:

bash
nc localhost 4444 > ram.lime

The adb forward command routes port 4444 on the host to port 4444 on the device, so netcat reads through the adb tunnel rather than connecting to the device's IP directly. Root is required: the su step grants kernel module loading rights, and LiME provides no documented path for unrooted Android devices.

Acquiring directly to the SD card is also documented, which removes the network step entirely:

bash
insmod /sdcard/lime.ko "path=/sdcard/ram.lime format=lime"

This is useful when network transfer is unavailable or when keeping the capture on the device before extracting it separately. Local storage access after acquisition lets you retrieve the file via adb pull rather than streaming it through netcat.

Digest and compression both disturb more memory than a baseline acquisition

LiME's stated design goal is forensic soundness through minimizing interaction with the target system, and both optional parameters document trade-offs that work against that goal.

For the digest parameter, the documentation states: 'enabling digest increases code complexity during acquisition and will overwrite additional memory. Only use when integrity verification is required.'

For the compress parameter, the documentation states: 'enabling compression allocates additional kernel memory (~24 KB) and increases code complexity during acquisition, disturbing more of the target system's memory. Only use when the speed or size benefit is required.'

Neither warning appears in the example commands. An operator adding compress=1 to reduce transfer time over a slow network is explicitly trading forensic soundness for throughput, per the project's own documentation. The digest trade-off is the more counterintuitive one: running SHA-256 to verify the dump's integrity itself overwrites a portion of the memory being preserved.

Compression uses the zlib format rather than gzip or zip. The deflate library embedded in the kernel does not support gzip or zip formats, which means standard gunzip will not decompress the output. Decompression requires pigz or another zlib-compatible library. When receiving a compressed stream over TCP:

bash
nc localhost 4444 | unpigz > ram.lime

Only the memory dump is compressed; the digest sidecar file is not, and its hash value matches the uncompressed data.

Kernel configuration gates compression, and LiME's approach against userspace acquisition tools

Compression requires CONFIG_ZLIB_DEFLATE to be enabled in the kernel build configuration. When the kernel was built without it, the compress=1 option is unavailable. The documentation does not describe LiME's behavior when compression is requested on a kernel lacking that configuration flag, so checking the kernel config before running an acquisition on an unfamiliar system avoids that uncertainty.

LiME's design rationale positions it against userspace memory acquisition tools on a specific axis. A userspace tool that reads /proc/kcore or /dev/mem goes through the kernel interface, creating interaction between user and kernel space that can alter memory contents before they are captured. LiME's kernel module approach removes that layer by running entirely in kernel space during acquisition. No specific alternative tools are named in the project documentation, but the design rationale assumes any competitor with a userspace component has this interaction cost.

Version 1.12.0 was released on 2026-03-31 and version 1.11.0 on 2026-03-15, with the last push to the repository on 2026-04-05. Source code is distributed under GPL-2.0, with REUSE-compatible licensing metadata in REUSE.toml and a LICENSES/ directory at the repository root.

Editorial conclusion

LiME fits when you need forensic memory acquisition from a Linux or Android system and can compile a kernel module for the running kernel. The module approach reduces interaction with the target system compared to userspace alternatives. Skip it when the device is unrooted or when loading kernel modules is unavailable. Before acquisition, confirm which output format your pipeline expects: lime carries address space metadata that raw loses, and raw is documented as preventing analysis in most forensics tools. Enabling digest or compress both disturb more memory than a baseline dump, which is the trade-off to weigh against their benefits.

Frequently asked questions

What is LiME used for?

LiME is a Loadable Kernel Module for acquiring volatile memory from Linux and Android devices, used in digital forensics. It was originally named DMD and first presented at Shmoocon 2012 by Joe Sylve.

Does LiME work on Android devices?

Yes. LiME can be pushed to an Android device via adb and loaded with insmod, acquiring memory either to the SD card or over TCP. A rooted device is required.

What output formats does LiME support?

LiME supports three formats: lime, which prepends each range with a fixed-size header containing address space information; padded, which fills non-System RAM ranges with zeros from physical address 0; and raw, which concatenates ranges without position data and is not recommended except for advanced users.

Does enabling the digest or compression option affect the capture's forensic quality?

According to the parameter documentation, enabling digest increases code complexity and overwrites additional memory, and enabling compress allocates roughly 24 KB of additional kernel memory and disturbs more of the target system's memory than a baseline acquisition.

How do I collect a digest file when acquiring memory over TCP?

Collecting a digest over TCP requires two separate netcat connections: one for the memory dump and one for the digest sidecar file. The sidecar file is named after the output path with the digest algorithm appended, for example ram.lime.sha256.

Official sources

  1. Issues
  2. jtsylve/LiME on GitHub
  3. License: GPL-2.0
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/jtsylve-lime.svg)](https://hysenlabs.com/projects/jtsylve-lime)

Star history chart for your README

markdown
[![Star history](https://hysenlabs.com/chart/jtsylve-lime.svg)](https://hysenlabs.com/projects/jtsylve-lime)

Was this useful?