Packed Code is frequent ingredient of armored malware. Here we demonstrate a few WinDbg commands to detect UPX packed modules with little or no expected strings:
0:000> !dh 00000000`00fd40b0 File Type: DLL FILE HEADER VALUES 14C machine (i386) 3 number of sections time date stamp Fri Jan 18 21:27:25 2013 0 file pointer to symbol table 0 number of symbols E0 size of optional header 2102 characteristics Executable 32 bit word machine DLL
OPTIONAL HEADER VALUES 10B magic # 11.00 linker version 6000 size of code 1000 size of initialized data F000 size of uninitialized data 15600 address of entry point 10000 base of code ----- new ----- 0000000010000000 image base 1000 section alignment 200 file alignment 2 subsystem (Windows GUI) 6.00 operating system version 0.00 image version 6.00 subsystem version 17000 size of image 1000 size of headers 0 checksum 0000000000100000 size of stack reserve 0000000000001000 size of stack commit 0000000000100000 size of heap reserve 0000000000001000 size of heap commit 140 DLL characteristics Dynamic base NX compatible 16274 [ AC] address [size] of Export Directory 161DC [ 98] address [size] of Import Directory 16000 [ 1DC] address [size] of Resource Directory 0 [ 0] address [size] of Exception Directory 0 [ 0] address [size] of Security Directory 16320 [ 10] address [size] of Base Relocation Directory 0 [ 0] address [size] of Debug Directory 0 [ 0] address [size] of Description Directory 0 [ 0] address [size] of Special Directory 0 [ 0] address [size] of Thread Storage Directory 157CC [ 48] address [size] of Load Configuration Directory 0 [ 0] address [size] of Bound Import Directory 0 [ 0] address [size] of Import Address Table Directory 0 [ 0] address [size] of Delay Import Directory 0 [ 0] address [size] of COR20 Header Directory 0 [ 0] address [size] of Reserved Directory
SECTION HEADER #1 UPX0 name F000 virtual size 1000 virtual address 0 size of raw data 400 file pointer to raw data 0 file pointer to relocation table 0 file pointer to line numbers 0 number of relocations 0 number of line numbers E0000080 flags Uninitialized Data (no align specified) Execute Read Write
SECTION HEADER #2 UPX1 name 6000 virtual size 10000 virtual address 5A00 size of raw data 400 file pointer to raw data 0 file pointer to relocation table 0 file pointer to line numbers 0 number of relocations 0 number of line numbers E0000040 flags Initialized Data (no align specified) Execute Read Write
SECTION HEADER #3 .rsrc name 1000 virtual size 16000 virtual address 400 size of raw data 5E00 file pointer to raw data 0 file pointer to relocation table 0 file pointer to line numbers 0 number of relocations 0 number of line numbers C0000040 flags Initialized Data (no align specified) Read Write
0:000> s-sa 00000000`00fd40b0 L6600 00000000`00fd40fd "!This program cannot be run in D" 00000000`00fd411d "OS mode." 00000000`00fd4188 "Rich" 00000000`00fd4290 "UPX0" 00000000`00fd42b8 "UPX1" 00000000`00fd42e0 ".rsrc" 00000000`00fd448b "3.08" 00000000`00fd4490 "UPX! " 00000000`00fd449b "YhHM4" 00000000`00fd44d1 "vqx" [...]
Such in-memory modules (not yet initialized by a loader) can be saved to disk using .writemem command and unpacked. Once loaded and relocated into some address they still have UPX sections but they now have more strings:
0:000> s-sa 00000000`691c0000 L300 00000000`691c004d "!This program cannot be run in D" 00000000`691c006d "OS mode." 00000000`691c00d8 "Rich" 00000000`691c01e0 "UPX0" 00000000`691c0207 "`UPX1" 00000000`691c022f "`.rsrc" [...] 00000000`691d620b "uGC" 00000000`691d621c "KERNEL32.DLL" 00000000`691d622a "LoadLibraryA" 00000000`691d6238 "GetProcAddress" 00000000`691d6248 "VirtualProtect" 00000000`691d6258 "VirtualAlloc" 00000000`691d6266 "VirtualFree" [...]
0:000> s-su 00000000`691c0000 L(00000000`691d7000-00000000`691c0000) [...] 00000000`691c8178 “http://www.patterndiagnostics.com” 00000000`691c8260 “mscoree.dll” [...]