03.01
This is the second "Ask a developer Monday," in which we answer the most common question we've received recently. The current No. 1 question is: "Why is the entry point after unpacking located in the section named UPX0?"
This is a more complex question than you might think, because it requires understanding the memory models used by software packers, which makes it a perfect question for "Ask a developer Monday"! To answer it we must explore the memory models used, and the possible results that an unpacker could produce.
The first memory model is the one typically used by software packers. Its main characteristic is a greatly reduced number of portable executable sections - lowered to only two or three, depending on the packer solution itself. With this model, all sections in the file before packing are merged into a single section that is always the first section in the packed file. Most commonly this first section in the packed file holds no data and it is used just as a slot to reserve memory which will be filled after the packer stub finishes the decompression. The virtual size of this first packed file section is equal to the SizeOfImage of the file before it was packed. This gives the packers a powerful option for compressing all code and data in one pass as a single compressed data stream. It also speeds up the time needed to decompress the entire packed content and lowers the compressed file's size because it needs only a single decompression dictionary. The compressed data is commonly stored in the packer section which is either in the second or the third section of the packed file. Since resources must be aligned to SectionAlignment, they commonly get their own section - usually the last section of the file packed using this memory model.
Although the first model brings faster decompression and smaller files to the table, it has the disadvantage of slightly increasing the memory usage for the packed file. Since memory usage is only increased by the size of the compressed content if that content is displaced from its original location and moved to the packer section, the problem can be avoided by using a packer that uses a memory model in which the compressed data is stored at its original location. This kind of packer individually compresses the portable executable sections and stores the compressed data inside the same section. With this model, the packer preserves the section layout the file had prior to packing. Commonly, only one section is added to the original file layout, and that section only contains the packer stub. Compression here is achieved by reducing the physical size of the individual sections. There is a hybrid approach which combines these two memory models, but there isn't a software compression solution that uses it.
Now how does this apply to dynamic unpackers? Since a dynamic unpacker executes the file until it reaches its original entry point and performs a memory dump once that point is reached, it has no impact whatsoever on the memory model used by the packer. That means that the file section layout before and after unpacking will remain the same, with exception of the sections added to the file by the unpacker. These new sections contain the import and relocation data, while the old sections hold the decompressed code, resources and data. There is no way to restore the memory model to its original layout if that kind of data isn't preserved in the packer stub. Since that data isn't commonly preserved by any software packers, a dynamic unpacker can't restore the original memory model layout. And since UPX uses the first memory model as its entry point after the file is unpacked, it will be moved from the section UPX1 to UPX0. The thing to remember is that section names are not important, what is important is that the data and the code itself are decompressed and this is achieved by the dynamic unpackers.
- Examples for the fist memory model are: UPX, FSG, RLPack, etc.
- Examples for the second memory model are: PackMan, ASPack, AlexProtector, etc.
That is it for this weeks Q&A, until next time...