2006 Unpacking FSG
2006 Unpacking FSG
First it uses an xchg instruction to swap esp with the dword at offset 4094E8h. Also see
below the value here is 4094CCh. This effectively points the program’s stack pointer into
the program’s own segment where it has hard-coded additional data. Note: the second
xchg restores the original stack…but leaves esi and edi in tact (read on to see why this is
significant).
Notice how after the xchg instruction, these values are on the top of the program’s stack,
as well as a bunch of other junk
Now take a look at the registers, esi and edi in particular, after the popa:
So, edi (401000h) and esi (407000h) are the addresses of seg001 and seg002 sections,
respectively. See how much the file is packed by focusing on the “dd 1800h dup”
instruction inside seg001.
When unpacked, we can expect seg001 to be 1800h (6144 dec) bytes long. Seg002 virtual
size is 3600h (12288 dec) – exactly twice the size of seg001. Looking a little further into
the start code, you can see data taken from esi and moved into edi – this happens pretty
much right after the popa above and then enters a loop where esi and edi increment while
the bytes are read from esi, processed, and written to edi.
HEADER:0040015D movsb
HEADER:0040015E mov dh, 80h
It follows this pattern until seg001 contains all the DLL names and the names of the
exports in those DLLs that it wants to use, then calls LoadLibrary() and
GetProcAddress() to resolve them and stores the function addresses to the remaining
vacant space in seg001.
wsprintfA
InternetCloseHandle
InternetGetConnectedState
InternetOpenA
InternetOpenUrlA
InternetQueryDataAvailable
InternetReadFile
CloseHandle
CopyFileA
CreateEventA
CreateFileA
CreateMutexA
CreateThread
DeleteFileA
EnterCriticalSection
ExitProcess
ExitThread
FreeConsole
GetLastError
GetModuleFileNameA
GetModuleHandleA
GetSystemDirectoryA
GetThreadContext
GetTickCount
GetVersionExA
GlobalAlloc
GlobalFree
InitializeCriticalSection
LeaveCriticalSection
LoadLibraryA
ReleaseMutex
ResumeThread
SetEvent
SetFileAttributesA
SetThreadContext
Sleep
TerminateProcess
VirtualAllocEx
WaitForSingleObject
WaitForSingleObjectEx
WinExec
WriteFile
WriteProcessMemory
lstrcatA
lstrcpyA
lstrlenA
WSACleanup
WSAStartup
__WSAFDIsSet
accept
closesocket
connect
gethostbyname
gethostname
getsockname
htons
inet_ntoa
listen
ntohs
recvfrom
select
sendto
socket
URLDownloadToCacheFileA
URLDownloadToFileA
RegCloseKey
RegOpenKeyExA
RegQueryValueExA
RegSetValueExA
Also to do this, it loads these DLLs (and a few others not listed too):
user32.dll
wininet.dll
ws2_32.dll
urlmon.dll
advapi32.dll
To further unpack without wasting tons of time figuring out when the resolution loop
finishes, locate one of the exports that would reasonably be called before any of the real
malicious behavior starts (WSAStartup, InitializeCriticalSection, and WinExec are good
choices). Set a breakpoint at the beginning of each function inside the DLL that exports
them using OllyDbg and let the program run. You should be able to catch it red-handed
doing bad things.