Say I have a binary that I'm not able to execute (for example it runs on some device that I don't have one of), but I can disassemble it. I can get the docs on the architecture. (It's MIPS little endian in my case.) But the binary has very few imports, very few strings, etc., so it really seems like it's packed.

How can I go about statically unpacking it? (Edit: I mean, unpacking it without any access to the original device.)

  • 1
    You could try running it with one of the user mode emulators supplied with QEMU... it would help if you knew more about it probably a disassembler would help like IDA perhaps it is one of the types the free version can work with. Also I am not sure what you mean by "static unpacking" – cb88 Mar 21 '13 at 4:37
  • Ida Pro and the Bochs emulator seems like a way to go, see here for a tutorial. – Remko Mar 21 '13 at 7:43
  • @Remko: alas Bochs only emulates x86 so it's unlikely to help here – Igor Skochinsky Mar 21 '13 at 11:18
  • @cb88, I have a copy of IDA Pro. And what I mean is I wish to unpack the binary but I don't have the device it was originally intended for. Seems like QEMU+mipsel is the way to go; I'm downloading debian-mipsel now. – EfForEffort Mar 26 '13 at 4:16
  • You could probably do it in a chroot as well,with gentoo mips and a static qemu usermode emulator, if qemu system emulation is too buggy or hard to get data back out of. gentoo.org/proj/en/base/embedded/handbook/?part=1&chap=5 – cb88 Mar 26 '13 at 13:09

Over the 30+ embedded device firmwares I've seen in the past I have rarely seen them using anything proprietary. Often it's just gzip/LZMA or a similar compression they're using (albeit sometimes with modified or stripped headers).

Thus as a first step I would try something like binwalk to search for known compression algorithms. If that doesn't help try tools for finding crypto constants such as Find Crypt or Sign search. This only works if the crypto is a software implementation. If it's a more sophisticated device, say a set-top-box, with a hardware accelerated decryption engine and OTP memory for storing the key then you're out of luck without run-time access (unless they greatly screw up passing the key from OTP to the decryption engine).

Finally you could try to find out if they use some proprietary algorithm and either emulate that algorithm using QEMU or gxemul or write your own decompressor in higher level language.

  • This is a good idea. I ran binwalk and it found nothing except that it's an ELF (i.e., it reported only what file(1) reported). Sign search also didn't find anything. I guess the next step is QEMU. – EfForEffort Mar 26 '13 at 4:31

In The Ida Pro Book, Chris Eagle demonstrates use of a plugin called ida-x86emu, which can be used to statically unpack binaries by simulating execution within the IDA database. Check it out; it's open-source, and it's pretty easy to use.

  • Unfortunately doesn't help as this is a MIPS binary =[ – EfForEffort Mar 26 '13 at 4:23

several possible ways:

  1. identify the packer

    • get standard packers of your platform (UPX for example), check if it's not the one used.
    • If it's a standard packer, then maybe you've already won, as it might be documented, or even better, like UPX, it can unpack itself and is open-source.
  2. identify the algorithm

    • there are not so many good+widespread packer algorithms (NRV, LZMA, JCAlg, ApLib, BriefLZ). they're usually easily identifiable by their body size or their constants. (I implemented several of them in pure python in Kabopan)
    • if you can easily identify the packing/encryption algorithm, then you can probably find a clean implementation for static unpacking
  3. get your hands dirty

    • if you still don't know the algorithm and it's apparently really a custom one, then read another packer for the same platform (ie once again, read UPX Mips binary and its source), so it can make you familiar with similar (packer) tricks used on your platform.
    • then look for the likely compression algorithm (likely a different-looking piece of code, people very rarely mess with them, and re-implement the algorithm in your favorite language, and unpack externally (locate parameters, apply algorithms, modify/reconstruct binary)
  4. Lazy method by bruteforcing: some algorithms like ApLib don't have any header nor parameter (not even a size): the algorithm just requires a pointer to a compressed buffer, so it's sometimes enough to just blindly try it on any offset of your binary, and check if we get a decent decompressed buffer (not too small, not huge+full of 00s).


My general answer would be "by simulating self-modifying operations against the packed binary". So for example, this would encompass removing the compression that most packers are veiled under. Doing so will require "statically tracing" the execution flow through the packer, whose code may be subject to self-modification.

That explanation works for a traditional style of packing, wherein the sections of the binary are merely compressed/encrypted. It might be the case that more sophisticated unpacking strategies are required, for example as described in my paper "Unpacking Virtualization Obfuscators" 1.

Your Answer

