File Name: LZNT1 Tools (bootmgr/ntfs)
File Submitter: joakim
File Submitted: 11 Jan 2012
File Updated: 14 Jan 2012
File Category: Tools
BOOTMGR compression explained
The compression used in BOOTMGR is a variant of LZ77 called LZNT1. The apis used to handle this are found in ntdll.dll and are named RtlDecompressBuffer and RtlCompressBuffer. Additionally, RtlGetCompressionWorkSpaceSize are also used with the compression. Moreover, RtlCompressBuffer's parameter CompressionFormatAndEngine uses COMPRESSION_FORMAT_LZNT1 | COMPRESSION_ENGINE_MAXIMUM (258). The decompressor api handles this on the fly.
Now for BOOTMGR you need to locate the compressed data before you can attempt decompression. As a matter in fact, BOOTMGR has a 16-bit stub and a mini exe as a header that needs to be removed first. Or maybe better just save it as a separate file so that it can be reattached later after you have recompressed the file. So to find the magic offset of where to separate bootmgr, you will need to locate the second ASCII string of "MZ". The first instance of "MZ" is the mini exe attached right before the comressed data. Also include the 3 bytes right before the second ASCII instance of "MZ", which is necessary for the decompression to work. Look at the included image and notice the offset 0x7bf0.
That is Windows 7 RTM version 6.1.7600.16385 by the way. The second "MZ" is at 0x7bf3 and there is 3 needed bytes right before that. That means the data 0x0 - 0x7bef is the header that can be removed and saved separately as for instance bootmgr.header. The data from 0x7bf0 - EOF (0x5da49 in this case) is the actual compressed data that also can be saved separately as for instance bootmgr.compressed. Now run LZNT1_Decompress.exe and open bootmgr.compressed. The program will name the output file as the input, but with an extension of "decomp.bin". Rename this decompressed file to whatever with an exe extension, for instance BOOTMGR.EXE and verify that the digital signature is good. For a proof of concept you can then try recompressing the file and test it. To do so, run the program LZNT1_Compress.exe and open BOOTMGR.EXE. If everything goes well, you should get a compressed file that given the extension "comp.bin". That is your BOOTMGR.exe will be compressed into BOOTMGR.exe.comp.bin. Now remember to reattach the header that was removed before decompression. That can be done by this command;
copy /b bootmgr.header+BOOTMGR.exe.comp.bin bootmgr
The reassembled file is now saved as bootmgr. For those paying attention to details, maybe noticed that the new bootmgr actually is smaller in size than the original by 1 byte. Microsoft's strange implementation actually has an uneeded byte (00) at EOF that can be safely removed. It serves no purpose and must be considered junk data. Also notice that when finding the magic offset, all these BOOTMGR's will look mostly the same around that offset, as seen in the image. There will thus be a large chunk of 00's right before the compressed part.
The method of compressing bootmgr was introduced in Vista SP1 and has been the same since. The versions from Longhorn and till Vista SP0 was different in that it was not compressed. I have successfully tried to decompress and recompress BOOTMGR from Vista version 6.0.6001.16606 and up until Windows 8 version 6.2.7955.0. It is done in the exact same way. In the latest Windows 8 (ie sometime after 7955) the compression method changed to a different method I am unfamiliar with. But it would not surprise me if the necessary apis are found inside a dll of the relevant Windows 8 version.
Interestingly, the same compression algorith as used with BOOTMGR are used with NTFS compression, but with COMPRESSION_ENGINE_STANDARD instead of COMPRESSION_ENGINE_MAXIMUM. That means if you extract 1 run/chunk off a compressed file from NTFS, you can use the included decompressor to decompress that data chunk (an interesting point is for use with rare cases of data recovery/forensics when carved parts of a compressed file can actually be decompressed). I found this out when developing my NTFS file extracter, and was surprised to find out that an NTFS compressed file are built of several individually compressed chunks, instead of 1 compressed file spliced up in chunks (for the runs). The extraction of such files are therefore done by decompressing every datachunk before concatenating them together in a final decompressed file. Try it out for yourself! Cheers.
And thanks to trancexx for nice code samples as always.
There have existed a program called bmzip for some time that also does this, but it is closed sources, implemented completely differently and has an issue with the compression; http://www.coderforl...t/extras/#bmzip Latest news from Jeff Bush, the authos of that program, is that he will likely have a solution for Xpress Huffman too within a few weeks.
Full sources are included in this download though, as is x86 and x64 binaries.
It turns out that support for Xpress Huffman in the newest Windows 8 are present in the same functions as explained above. Until it's solved correctly (although I think the current implementation in ntdll.dll is broken), there is a funny workaround for experimenting. Take the latest bootmgr.exe ver 6.2.8102 (or any Xpress Huffman based) and compress it with LZNT1 with the compressor posted above, and use this custom stub to load it; http://www.mediafire...vcw32esjvwxc339 (using similar commands as explained above to reassemble the two parts).
You may want to notice what extremely important role the minimal exe (in this case just a bunch of 00's) placed in between the 16-stub and the compressed data has..
Click here to download this file