Sample: e243501c80312a4fa376ddb7f86a4d318d9992bac583dccc7cf7ff99d14d30a0

In order to unpack this sample, the unpacked binary must first be pulled out of memory. This is done by monitoring VirtualAlloc to see where things in memory are being written to.

The first step is to set a breakpoint on entry and continue to execute until the entry point.

> radare2.exe -d C:\Users\IEUser\Desktop\89yhFA
Spawned new process with pid 3260, tid = 416
= attach 3260 416
bin.baddr 0x00400000
Using 0x400000
asm.bits 32
 -- Sharing your latest session in Facebook ...
[0x777770d8]> aaaa
[x] Analyze all flags starting with sym. and entry0 (aa)
TODO: esil-vm not initialized
[x] Analyze len bytes of instructions for references (aar)
[x] Analyze function calls (aac)
[x] Emulate code to find computed references (aae)
[Cannot find section boundaries in here
[x] Analyze consecutive function (aat)
[x] Constructing a function name for fcn.* and sym.func.* functions (aan)
[x] Type matching analysis for all functions (afta)
= attach 3260 416
[0x777770d8]> db entry0
[0x777770d8]> dc
(3260) loading library at 77730000 (C:\Windows\System32\ntdll.dll) ntdll.dll
(3260) loading library at 77880000 (C:\Windows\winsxs\x86_microsoft-windows-kernel32_31bf3856ad364e35_6.1.7601.18409_none_95d507dcb48120f5\kernel32.dll) kernel32.dll
(3260) loading library at 75AB0000 (C:\Windows\winsxs\x86_microsoft-windows-kernelbase_31bf3856ad364e35_6.1.7601.18409_none_29199aef12c9a8e1\KernelBase.dll) KernelBase.dll
(3260) loading library at 770A0000 (C:\Windows\winsxs\x86_microsoft-windows-advapi32_31bf3856ad364e35_6.1.7601.18247_none_e5323035e4d993bf\advapi32.dll) advapi32.dll
(3260) loading library at 77490000 (C:\Windows\System32\msvcrt.dll) msvcrt.dll
(3260) loading library at 75C10000 (C:\Windows\System32\sechost.dll) sechost.dll
(3260) loading library at 76BC0000 (C:\Windows\winsxs\x86_microsoft-windows-rpc-local_31bf3856ad364e35_6.1.7601.18532_none_b5ea51cea368873f\rpcrt4.dll) rpcrt4.dll
(3260) loading library at 75DD0000 (C:\Windows\System32\shell32.dll) shell32.dll
(3260) loading library at 75CA0000 (C:\Windows\System32\shlwapi.dll) shlwapi.dll
(3260) loading library at 76FA0000 (C:\Windows\System32\gdi32.dll) gdi32.dll
(3260) loading library at 76D10000 (C:\Windows\System32\user32.dll) user32.dll
(3260) loading library at 77090000 (C:\Windows\System32\lpk.dll) lpk.dll
(3260) loading library at 76C70000 (C:\Windows\System32\usp10.dll) usp10.dll
(3260) loading library at 6AF10000 (C:\Windows\System32\modemui.dll) modemui.dll
(3260) loading library at 76A20000 (C:\Windows\System32\setupapi.dll) setupapi.dll
(3260) loading library at 75A80000 (C:\Windows\System32\cfgmgr32.dll) cfgmgr32.dll
(3260) loading library at 77540000 (C:\Windows\System32\oleaut32.dll) oleaut32.dll
(3260) loading library at 775D0000 (C:\Windows\System32\ole32.dll) ole32.dll
(3260) loading library at 75940000 (C:\Windows\System32\devobj.dll) devobj.dll
(3260) loading library at 6B370000 (C:\Windows\System32\uniplat.dll) uniplat.dll
(3260) loading library at 6E1A0000 (C:\Windows\System32\comsvcs.dll) comsvcs.dll
(3260) loading library at 73C40000 (C:\Windows\System32\atl.dll) atl.dll
[0x777d05a7]> dc
(3260) loading library at 75C80000 (C:\Windows\System32\imm32.dll) imm32.dll
(3260) loading library at 75D00000 (C:\Windows\System32\msctf.dll) msctf.dll
(3260) loading library at 748C0000 (C:\Windows\winsxs\\comctl32.dll) comctl32.dll
(3260) loading library at 75810000 (C:\Windows\winsxs\x86_microsoft-windows-cryptbase_31bf3856ad364e35_6.1.7600.16385_none_653c2b9c0f4d8ca6\cryptbase.dll) cryptbase.dll
hit breakpoint at: 40287a

Next, a breakpoint is set on Virtual Alloc.

[0x0040287a]> dmi KERNEL32~VirtualAlloc
vaddr=0x76fa6970 paddr=0x00007970 ord=1463 fwd=NONE sz=0 bind=GLOBAL type=FUNC name=KERNEL32.dll_VirtualAlloc
vaddr=0x76fa6990 paddr=0x00007990 ord=1464 fwd=NONE sz=0 bind=GLOBAL type=FUNC name=KERNEL32.dll_VirtualAllocEx
vaddr=0x76fa69b0 paddr=0x000079b0 ord=1465 fwd=NONE sz=0 bind=GLOBAL type=FUNC name=KERNEL32.dll_VirtualAllocExNuma
vaddr=0x77001170 paddr=0x00062170 ord=013 fwd= sz=0 bind=NONE type=FUNC name=imp.api-ms-win-core-memory-l1-1-2.dll_VirtualAllocExNuma
vaddr=0x77001174 paddr=0x00062174 ord=014 fwd= sz=0 bind=NONE type=FUNC name=imp.api-ms-win-core-memory-l1-1-2.dll_VirtualAllocEx
vaddr=0x77001178 paddr=0x00062178 ord=015 fwd= sz=0 bind=NONE type=FUNC name=imp.api-ms-win-core-memory-l1-1-2.dll_VirtualAlloc
[0x0040287a]> db 0x76fa6970
[0x0040287a]> dc

Now, the sample will run until the VirtualAlloc breakpoint is hit. After the VirtualAlloc breakpoint is hit, the reserved memory can be checked for a unpacked sample. This is done by checking the stack for the dwSize as well as lpAddress.

hit breakpoint at: 76fa6970
[0x76fa6970]> *esp+8 # dwSize
[0x76fa6970]> *esp+4 # lpAddress

At esp+4, the Virtual Alloc lpAddress can be seen. At esp+8, the dwSize can be seen. According to the Virtual Alloc MSDN page, if lpAddress is 0x00, the system will determine where to allocate the memory. In order to see this address, the execution must continue until the end of the current function (dcr).

[0x76fa6970]> dcr
hit breakpoint at: 76e75481
[0x76e7548e]> dr eax # lpAddress

The reserved memory size and the reserved memory address are both known at this point, so now a hardware breakpoint needs to be set on a write to this memory location.

[0x76e7548e]> drx 0 0x021e0000+0x815FF 1 w
[0x0090009e]> dc
[0x00900571]> px @ 0x021e0000
- offset -   0 1  2 3  4 5  6 7  8 9  A B  C D  E F  0123456789ABCDEF
0x021e0000  4d5a 9000 0300 0000 0400 0000 ffff 0000  MZ..............
0x021e0010  b800 0000 0000 0000 4000 0000 0000 0000  ........@.......
0x021e0020  0000 0000 0000 0000 0000 0000 0000 0000  ................
0x021e0030  0000 0000 0000 0000 0000 0000 e800 0000  ................
0x021e0040  0e1f ba0e 00b4 09cd 21b8 014c cd21 5468  ........!..L.!Th
0x021e0050  6973 2070 726f 6772 616d 2063 616e 6e6f  is program canno
0x021e0060  7420 6265 2072 756e 2069 6e20 444f 5320  t be run in DOS
0x021e0070  6d6f 6465 2e0d 0d0a 2400 0000 0000 0000  mode....$.......
0x021e0080  9a0a d093 de6b bec0 de6b bec0 de6b bec0  .....k...k...k..
0x021e0090  b174 b4c0 dc6b bec0 cd63 e3c0 db6b bec0  .t...k...c...k..
0x021e00a0  5d63 e3c0 fb6b bec0 244f fec0 c66b bec0  ]c...k..$O...k..
0x021e00b0  244f fec0 8b6b bec0 d848 b4c0 c96b bec0  $O...k...H...k..
0x021e00c0  de6b bfc0 146b bec0 db67 e3c0 df6b bec0  .k...k...g...k..
0x021e00d0  214b bbc0 df6b bec0 5269 6368 de6b bec0  !K...k..Rich.k..
0x021e00e0  0000 0000 0000 0000 5045 0000 4c01 0500  ........PE..L...
0x021e00f0  2e95 6f44 0000 0000 0000 0000 e000 2201  ..oD..........".

Now that the unpacked binary is in memory, the last step is to write this to a file. This can be done with Radare’s wtf command.

[0x00900571]> wtf unpacked_sample 0x81600 @ 0x021e0000
Dumped 529920 bytes from 0x021e0000 into unpacked_sample

Now, the sample has been unpacked. An analysis of the unpacked sample can be viewed here.