> For the complete documentation index, see [llms.txt](https://docs.hex-rays.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.hex-rays.com/add-ons/malware/how-tos/unpack-a-malware-sample.md).

# Unpack a Malware Sample

This how-to shows how to unpack a malware sample that is packed with UPX, a free and open-source executable packer. UPX compresses the code of a program and adds a small stub that decompresses the code in memory when the program starts. The sample is a 32-bit x86 PE console program of 4.5 KB with the SHA-256 hash `5113294e08c69103ded6ebe3faadec64c601ee611d434fba62a17472e9d75ccf`. You can download it from [MalwareBazaar](https://bazaar.abuse.ch/sample/5113294e08c69103ded6ebe3faadec64c601ee611d434fba62a17472e9d75ccf/) or [VirusTotal](https://www.virustotal.com/gui/file/5113294e08c69103ded6ebe3faadec64c601ee611d434fba62a17472e9d75ccf).

{% hint style="warning" %}
The sample is live malware. Work on a copy of the sample, and open the copy in IDA. With the Bochs engine, the unpacker runs the sample only inside the emulator, never on your system. Do not unpack this sample with the `win32` debugger, which runs the sample on your system.
{% endhint %}

Before you start, make sure that the unpacker uses [Bochs](/add-ons/malware/concepts/emulators/bochs.md). Select **Extensions → Malware Analysis → Unpacking → Configure unpacker...** and check that **Default debugger** is `bochs`. This is the default value. You select the heuristic later, when the unpack starts.

## Open the sample

Open the copy of the sample in IDA and wait for the initial auto-analysis to finish. IDA finds only 1 function, `start` at `0x405890`. This is the UPX stub in the `UPX1` segment (4 KB). The `UPX0` segment (16 KB, from `0x401000` to `0x405000`) has no code. At run time, the stub decompresses the program into this segment.

The import table also looks like a packed sample. It has the 4 `KERNEL32` functions that the UPX stub needs to load the real imports (`LoadLibraryA`, `GetProcAddress`, `VirtualProtect`, and `ExitProcess`) and 1 function from `MSVCRT` (`exit`).

After the auto-analysis, the unpacker checks if the sample looks packed. A sample looks packed when functions use 10% or less of the bytes in its executable segments. For this sample, functions use about 2% of these bytes, so the unpacker asks if you want to unpack it:

![The prompt that asks if you want to unpack the packed sample](https://492083732-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FFP6ibt8r6WPBHTqekG9u%2Fuploads%2Fgit-blob-49fbf01e59662d3abc6d1565a3dd81b2631e2fbc%2Funpack-dialogue-1.png?alt=media\&token=776bb5c5-a542-473e-8161-e9b3b876371d)

## Unpack the sample

Click **Yes** to unpack the sample now. If you click **No**, you can unpack it later. To do this, select **Malware Analysis → Unpacking → Unpack now\...** or press <kbd>Shift</kbd> + <kbd>P</kbd>. In this case, the unpacker first asks you to confirm, because unpacking replaces the contents of the loader segments. Click **Yes**.

Before it unpacks, the unpacker takes a database snapshot. If the result is not useful, you can go back to the packed sample with **View → Database snapshot manager...**.

Then the unpacker shows the **Choose unpacking heuristic** dialog. With no API keys set, the list has 4 rows. For this sample, `run-to-exit-point` is the first row, because the unpacker sees that the stub is one function with one exit, which is typical for UPX. Make sure that `run-to-exit-point` is selected and click **OK**.

The `vt-unpack` and `vmray-unpack` heuristics show in the list only when you set a VirusTotal or VMRay API key. For a description of all heuristics, see [Automated Unpacking](/add-ons/malware/concepts/automated-unpacking.md).

The unpacker starts the sample in the Bochs debugger and sets a breakpoint on the last instruction of the stub, the jump at `0x405A1B` to the decompressed code. IDA opens its debugger views, and the Output window shows the debugger messages. When Bochs stops at the breakpoint, the unpacker steps one instruction to `0x401820`, the original entry point. For this sample, the unpack takes a few seconds.

## Look at the result

When the heuristic is done, the unpacker stops the debugger, analyzes the unpacked code again, rebuilds the imports, and looks for the original entry point. It names the original entry point `OriginalEntryPoint` and jumps to it, or to `main()` if it finds it.

For this sample, the unpacker names `0x401820` `OriginalEntryPoint` and jumps to it. The database has 17 functions instead of 1, and 15 of them are in `UPX0`. Functions use about 15% of the bytes in `UPX0`. `OriginalEntryPoint` is the start code of the Microsoft C runtime. It calls `__getmainargs` and then the `main` function of the program at `0x401440`, which IDA names `_main`.

The unpacker finds the import address table (IAT) and names its entries, so calls to the Windows API show their names. For this sample, the IAT is in `UPX0` from `0x402004` to `0x402064`. The unpacker names 24 entries: 9 `kernel32` functions, such as `CreateFileA`, `MapViewOfFile`, `FindFirstFileA`, and `CopyFileA`, and 15 `msvcrt` functions, such as `malloc` and `_stricmp`.

You can now analyze the unpacked code as usual. The decompiler shows the API names in the pseudocode. For example, the pseudocode of `main` shows calls to `CreateFileA`, `CreateFileMappingA`, `MapViewOfFile`, and `CopyFileA`.

If the unpacker cannot unpack the sample, the Output window shows a warning that starts with `unpacker:`, for example when it finds no original entry point. Restore the snapshot with **View → Database snapshot manager...** and try a different heuristic.

If you have a question, an idea, or a problem, email <support@hex-rays.com>. The Malware Analysis team reads every message and replies quickly.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.hex-rays.com/add-ons/malware/how-tos/unpack-a-malware-sample.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
