Today I’m taking a look at different packers used to pack malware, how to identify them and how to unpack them.
A packer is software used to protect other software, by means of encryption, obfuscation, compression, virtualization and so on. Most malware samples are packed to evade detection and make it harder for malware analysts to analyze the code.
There are 3 main categories of packers, each with a different level of difficulty to unpack.
- Free packers
- easy to unpack
- commonly used
- examples: UPX, nPack, MEW, PolyCryptor, MPRESS, PE Protector
- Malware packers
- medium difficulty to unpack
- regularly used
- examples: Warzone Crypter, Yakuza Crypter, Atilla Crypter, Aspire Crypt, Spartan Crypter
- Commercial packers - difficult to unpack
- difficult to unpack
- rarely used
- examples: VMProtect, Themida, Obsidium, Armadillo, ASPack, PELock
There are a couple of different ways to detect if a malware sample has been packed and to possibly identify which packer was used.
- one way is to utilize tools like PEiD and YaraScan to look for signatures, or identify packers based on rules.
- we can also look at strings present in the sample. A lack of strings or a bunch of random looking strings are usually an indication a packer was used.
- similar to strings, a lack of imports or an unsual high amount of imports that don’t make sense, could indicate a packer.
- another way to detect if a packer was used, is to look at the section names of the binary. Packers commonly add extra sections which could be named after the packer or be completely random.
- a binary with a very high entropy usually means it is encrypted.
- finally the raw and virtual section sizes of the binary could indicate if a packer was used. The raw section size is the size of the sections while not running, the virtual section size is the size of the sections while the binary is being executed. If there is a notable difference between them, the sample might be packed.
Packing and Unpacking Process
When a malicious executable is packed, the packer will encrypt, compress or otherwise obfuscate the executable. After the packing process, the packer will add a so called “unpacking stub” to the executable. This unpacking stub is responsible for unpacking the executable at runtime and loading it into memory to execute.
The unpacking stub will first allocate a region of memory inside the process memory. Next it will copy shellcode to the allocated memory, this can either be plain text or encrypted. Then it will jump to the shellcode and execute it. This shellcode will allocate another region of memory and then decrypt the executable and copy it to the allocated memory. With the unpacked executable in memory, it can overwrite the process, or inject it into another process,…
Manually unpacking with x32/64dbg
- jump to user code
- set breakpoint on VirtualProtect
- set breakpoint on CreateProcessInternalW
- run until hitting breakpoint
- execute until return
- follow EAX in dump
- repeat until unpacked
- dump process memory
- unmap the executable by adjusting the raw addresses to match the virtual addresses and adjust raw size
- change image base to offset it was dumped from