I'm trying to look inside some D-link modem firmware using a LIF image. I get:

v@debian:~/lifutils# src/progs/lifstat /home/v/Downloads/DSL-25
Volume : �SI 
Tracks: 0 Surfaces: 0 Blocks per Track: 0.
Warning the medium was not initialized properly!
Directory start : 1191378964 (37230592/1/5) end : 1191395347 (37231104/1/4)
Error reading block 1191378964 from file. (Success)

How would you go about reversing this? The modem expects the file to be uploaded using the web interface so I assume there's some offset I need to specify? But the modem doesn't allow me to peek.

Dlink-firmware LIF-utils

  • There is no LIF file in the D-Link binary file containing the firmware image. file returns a false positive. Since there is no LIF file present, tools in the lifutils package will fail or produce erroneous results
  • Do not trust tools implicitly. Tools can return false positives if they rely on magic numbers, particular byte sequences and the like. When analyzing new, unknown or unfamiliar files, especially files that do not conform to a known standard, verify the results of the tools using manual techniques such as analyzing a hexdump and visualization of the structure of the binary

We can claim with a high degree of confidence that a HP-UX LIF file cannot be present in a D-Link binary without even analyzing the file.

HP and the Logical Interchange Format

Starting with the LIF:

From the lif manual page:

LIF (Logical Interchange Format) is a Hewlett-Packard standard mass-storage format that can be used for interchange of files among various HP computer systems. A LIF volume contains a header (identifying it as a LIF volume) and a directory that defines the contents (i.e. files) of the volume. The size of the directory is fixed when the volume is initialized (see lifinit(1)) and sets an upper bound on the number of files that can be created on the volume. HP-UX contains a set of utilities (referred to as lif*(1)) that can be used to:

  • Initialize a LIF volume (i.e. create a header and an empty directory),
  • Copy files to and from LIF volumes,
  • List the contents of LIF volumes,
  • Remove LIF files,
  • Rename LIF files.

The lif*(1) utilities are the only utilities within HP-UX where the internal structure of a LIF volume is known. To the rest of HP-UX, a LIF volume is simply a file containing some unspecified data. The term LIF volume should in no way be confused with the HP-UX notion of a file system volume or mountable volume.

More info from an HP forum: Understanding boot programs and LIF area....

LIF files are designed to be used on HP-UX systems.

Now to HP-UX:

From Wikipedia:

HP-UX (from "Hewlett Packard Unix") is Hewlett Packard Enterprise's proprietary implementation of the Unix operating system, based on UNIX System V (initially System III) and first released in 1984. Recent versions support the HP 9000 series of computer systems, based on the PA-RISC processor architecture, and HP Integrity systems, based on Intel's Itanium architecture.

HP-UX is proprietary (the opposite of open-source) and runs on systems with a unique instruction set architecture called PA-RISC.

Armed with this knowledge, we can conclude that unless

  1. D-Link has some kind of agreement with HP allowing D-Link to use proprietary HP hardware and software
  2. D-Link devices use HP processors and HP-UX

LIF files actually cannot be present in D-Link firmware.

How to go about reversing the file

In statistics there is an approach called exploratory data analysis in which the data is explored using various techniques in order to gain insight about the data prior to formal analysis. A similar approach can be taken in binary analysis and reversing, in which static techniques are employed prior to dynamic techniques.

Here is a good reference: Reverse Engineering Firmware: Linksys WAG120N

1. file can be used, but do not expect it to be helpful

In general, file is basically useless when analyzing binary files that contain firmware images because these binaries often have many different files embedded within them, such as HTML documents, image files such as GIF and JPEG files, compressed file systems, bootloaders and of course the firmware itself. These do not conform to any standard and their structure and contents vary across devices and manufacturers, hence no magic bytes or standard headers or signatures. Sometimes file is worse than useless because it returns false positives.

2. strings and hexdump

There may be useful strings embedded in the binary, such as pathnames to interesting files, names of functions, error messages, etc. If no human-readable ASCII sequences are produced by running strings it is a strong indicator that the binary is encoded in some way (compression, obfuscation, encryption). hexdump provides a way to quickly determine if there is a discernible header structure within the binary.

3. Scan the binary with a firmware analysis tool like binwalk

Using binwalk with no arguments other than the name of the file to scan will cause binwalk to search for various signatures within the binary that indicate the beginning of compressed regions, as well as additional information such as the presence of other files. Running binwalk against the firmware image from the link in the question produces quite a bit of useful output:

44468         0xADB4          ZyXEL rom-0 configuration block, name: "dbgarea", compressed size: 0, uncompressed size: 0, data offset from start of block: 16
44504         0xADD8          ZyXEL rom-0 configuration block, name: "dbgarea", compressed size: 0, uncompressed size: 0, data offset from start of block: 16
85043         0x14C33         LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 66696 bytes
118036        0x1CD14         Unix path: /usr/share/tabset/vt100:\
118804        0x1D014         ZyXEL rom-0 configuration block, name: "spt.dat", compressed size: 0, uncompressed size: 0, data offset from start of block: 16
118824        0x1D028         ZyXEL rom-0 configuration block, name: "autoexec.net", compressed size: 25972, uncompressed size: 11886, data offset from start of block: 16
128002        0x1F402         GIF image data, version "89a", 125 x 25
136194        0x21402         GIF image data, version "87a", 153 x 55
173900        0x2A74C         Copyright string: "Copyright © 2007 D-Link System, Inc."
188042        0x2DE8A         Copyright string: "Copyright © 2007 D-Link System, Inc."
213304        0x34138         Copyright string: "Copyright © 2007 D-Link System, Inc."
350259        0x55833         LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: 2659840 bytes

4. Confirm the results of the scan using additional techniques

  1. Manual analysis using hexdump

Like file, binwalk searches for specific sequences of bytes, which means it also can produce false positives. In the output of the scan, 2 LZMA compression signatures were found, one at offset 0x14C33 and another at offset 0x55833. If the region immediately following the compression signature is structurally distinct from the region prior to the compression signature and looks random, it is a sign that it is not a false positive. Additional verification is required, however.

output of hexdump -C -s 0x14900 (the compression signature is at 0x14C33):

00014900  74 20 20 31 20 20 20 20  20 00 43 77 6d 70 41 74  |t  1     .CwmpAt|
00014910  74 72 32 20 20 20 20 20  20 31 00 52 65 73 65 72  |tr2      1.Reser|
00014920  76 65 5f 33 20 20 20 20  20 20 20 31 00 52 65 73  |ve_3       1.Res|
00014930  65 72 76 65 5f 34 09 09  09 09 31 00 53 65 72 76  |erve_4....1.Serv|
00014940  65 72 56 36 09 09 09 09  31 00 53 65 72 76 65 72  |erV6....1.Server|
00014950  56 36 5f 65 78 74 09 09  31 00 41 63 63 65 73 73  |V6_ext..1.Access|
00014960  53 65 63 48 6f 73 74 56  36 09 31 00 41 63 63 65  |SecHostV6.1.Acce|
00014970  73 73 53 65 63 48 6f 73  74 56 36 5f 65 78 74 09  |ssSecHostV6_ext.|
00014980  31 00 52 65 73 65 72 76  65 5f 35 09 09 09 09 31  |1.Reserve_5....1|
00014990  00 50 43 50 09 09 09 09  09 09 31 00 42 77 43 74  |.PCP......1.BwCt|
000149a0  72 6c 52 75 6c 65 09 09  31 36 00 00 00 00 00 00  |rlRule..16......|
000149b0  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00014c00  00 00 00 00 00 00 53 49  47 04 00 01 04 88 00 00  |......SIG.......|
00014c10  41 cf e0 00 cb 32 d5 a5  48 54 50 5f 54 43 20 56  |A....2..HTP_TC V|
00014c20  20 30 2e 30 35 00 00 00  00 00 00 00 00 00 00 00  | 0.05...........|
00014c30  00 00 00 5d 00 00 80 00  88 04 01 00 00 00 00 00  |...]............|
00014c40  00 1e 02 1a 10 f9 e9 ec  c2 6e a7 ff e6 17 33 0d  |.........n....3.|
00014c50  5c ae 0c 00 3f 33 0b dd  d4 9a 4d 26 de e8 35 ed  |\...?3....M&..5.|
00014c60  8a dc 50 d0 60 18 b3 a3  6d 95 ff 45 c1 7f 15 94  |..P.`...m..E....|
00014c70  d0 12 90 ae ec 09 a6 1d  75 6e 41 b3 b6 43 24 6d  |........unA..C$m|
00014c80  55 cb bd 11 32 f9 54 f1  96 d5 9f f1 21 d1 39 b6  |U...2.T.....!.9.|
00014c90  d3 44 2d 74 9d 5d ff fc  3c 7f 53 84 86 03 df 84  |.D-t.]..<.S.....|
00014ca0  2c 5b 25 94 c2 60 f4 66  01 c1 62 9d 05 af 43 34  |,[%..`.f..b...C4|
00014cb0  9e 57 6c 8b e8 41 24 80  48 c5 5a 56 27 1a 1c c3  |.Wl..A$.H.ZV'...|

First, we observe that there is a series of ASCII strings followed by an empty region (many 0x00 bytes) followed by random-looking data.

Second, we observe that the sequence at offset 0x14C33 is 5d 00 00 80 00. This is indeed consistent with LZMA compression.

Third, we observe that the strings and null data region precede the LZMA compression signature and random-looking data.

These together are a good indication of the presence of a compressed region.

  1. Confirm the presence of compressed regions using entropy analysis

Compressed data typically has much higher entropy than non-random uncompressed data. We can take advantage of this by locating compressed regions in a binary using entropy analysis. This can be done by using binwalk with the -E option like so:

$ binwalk -E DSL-2520U

0             0x0             Falling entropy edge (0.778887)
84992         0x14C00         Rising entropy edge (0.971648)   <----Notice
101376        0x18C00         Falling entropy edge (0.600073)
138240        0x21C00         Falling entropy edge (0.000000)
350208        0x55800         Rising entropy edge (0.966418)   <----Notice

We observe here that the offsets at which there is a rising entropy edge are very close to the offsets at which the LZMA compression signatures were found.

Here is the entropy plot: binary entropy plot

We can see in the plot that there are 2 areas within the binary with entropy close to 1, consistent with compression.

5. Visualize the binary with a visualization tool like binvis.io

Here are some binary visualization tools to choose from: Visualizing ELF Binaries. I like using binvis.io because it is fast, convenient and has some useful features.

Visualization can assist in quickly identifying interesting regions within binaries.

ASCII data (blue) | | v v byteclass ^ ^ | | compressed compressed | | v v entropy ^ ^ | | regions of 0x00 bytes

6. Extract data from the binary

What is in those compressed regions? We can find out by extracting them.

$ binwalk -Me DSL-2520U

performs the extraction and scans each extracted block. The extracted data is in a new directory called _DSL-2520U.extracted.

7. Analyze the extracted data

Repeat the preceding steps for each extracted binary, but this time look for code (which will identify executable files like a kernel or bootloader), and file systems, which will contain utilities like web servers and .cgi software.

One way of locating code is by using the -A argument with binwalk:

$ binwalk -A 14C33

304           0x130           MIPS instructions, function epilogue
612           0x264           MIPS instructions, function epilogue
676           0x2A4           MIPS instructions, function epilogue
2576          0xA10           MIPS instructions, function epilogue
3548          0xDDC           MIPS instructions, function epilogue
3592          0xE08           MIPS instructions, function epilogue
3636          0xE34           MIPS instructions, function epilogue
3672          0xE58           MIPS instructions, function epilogue
4252          0x109C          MIPS instructions, function epilogue
4336          0x10F0          MIPS instructions, function epilogue
4420          0x1144          MIPS instructions, function epilogue
4936          0x1348          MIPS instructions, function epilogue

Excellent. It looks like the binary contains MIPS assembly code. This can be disassembled with radare2 or IDA or some other tool.

That should be enough information to get started.


These don't have to do with the device/firmware asked about in the question specifically, but devttys0 is a pro and reading his posts will give you an idea of how to approach many challenges faced when reversing firmware.

Extracting Non-Standard SquashFS Images

Reverse Engineering Firmware: Linksys WAG120N

Reverse Engineering VxWorks Firmware: WRT54Gv8

Exploiting Embedded Systems – Part 1

firmware.re is experimental

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.