Intro

A while back, in work, I was looking at a malware sample. It was a DLL that expects to run as a Windows service.

I hadn’t tried debugging a service DLL much so this was relatively new to me. Starting with my normal of approach of IdaPro and x64dbg (it was a 64-bit DLL), I found myself going no where fast. After some posts online, discussion with colleagues and furious Googling I got to where I wanted to be and brought along a ton of notes.

Soon after my initial foray, the article below was posted online and I highly recommend reading it. Lasha’s post focuses on debugging a service executable file rather than a DLL, as is the focus on my post.

Debugging Windows Services For Malware Analysis / Reverse Engineering

For the purpose of my article I am going to work with the following file, MD5: 42c63de7dac16366dfea14fa9ddac3cd , dropped by the following sample: 750f4a9ae44438bf053ffb344b959000ea624d1964306e4b3806250f4de94bc8.dll

Methodology

Before starting out with dynamic analysis I tend to load my sample up in IdaPro or your disassembler of choice and get a feel for the sample.

Identify what you want to answer using a debugger. What started me off on this journey was a decoding routine (in my work sample). Understanding the routine was going to take me longer than just having the sample work through it’s routine and do the decoding for me. Understanding the decoding was important but I needed the answer faster then I needed to understand how it was decoding. Once you know what you want to debug, setup the service and get going.

My steps were:

Setup a Windows service using my sample DLL Configure a debugger for the service with the Global Flags Editor Start the service Attach to the listening debugger with WinDBG

Setup

For analysing my sample(s) I was using a Windows 7 64-bit virtual machine provisioned using the FireEye FlareVM.

Windows Service Setup

The process laid out here is heavily influenced by Tarik Soulami and his book “Inside Windows Debugging” READ IT!

When debugging Windows services it’s common to adjust the ServicesPipeTimeout registry value so that when starting the service Windows won’t terminate the service process if it hasn’t started in a timely fashion. Usually 30 seconds. I’ve added a command to do this into the Batch script below.

Before this setting takes effect you must REBOOT.

To setup and create the Windows service I created a Batch script to carry out the necessary steps.

Place your sample somewhere and edit BINPATH in the Batch script.

@echo off set SERVICENAME = MALSERVICE set BINPATH = "C:\Users\user\Desktop\sample.dll" sc create %SERVICENAME% binPath = " %SYSTEMROOT% \system32\malsvchost.exe -k %SERVICENAME% " type = share start = demand reg add "HKLM\System\CurrentControlSet\Services\ %SERVICENAME% \Parameters" /v ServiceDLL /t REG_EXPAND_SZ /d %BINPATH% /f reg add "HKLM\Software\Microsoft\Windows NT\CurrentVersion\SvcHost" /v %SERVICENAME% /t REG_MULTI_SZ /d " %SERVICENAME% \0" /f reg add "HKLM\SYSTEM\CurrentControlSet\Control" /v ServicesPipeTimeout /t REG_DWORD /d 86400000 /f

For debugging a service DLL I use a copy of svchost.exe under a different file name, this make sense later on when we use gflags to set the GlobalFlag on a per-process basis. I tend to copy svchost.exe to malsvchost.exe within the system32 directory. The reason for this is so that ONLY the service I am interested in is started under a debugger and no other service’s operation is affected.

Configure a debugger

We want to use gflags to configure the GlobablFlag for malsvchost.exe so that the process is started inside of a debugger.

In my VM gflags was found at the following path (this path will vary for people depending on your VM and your version of the debugging tools):

C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\gflags.exe

Remember if you’re on a 32-bit platform use gflags under the x86 folder and not x64 .

Launch gflags as an admin and go to the Image File tab. In the text field to the right of “Image: (TAB to refresh) enter in malsvchost.exe and hit TAB.

At the bottom of the screen tick the box next to “Debugger:” and in the text field to the immiediate right we want to configure our debugger.

I use the Windows Console Debugger “cdb.exe” in server mode. Once this is running I connect to it as a client using WindDBG.

In my VM I configured the setting as follows:

C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\cdb.exe -server tcp:port=5505

Start the service

Now that everything is in place we should be in a good poisition to start the service. You may wish to have additional tools running. Fakenet, Process Monitor, Process Explorer, etc….

Start the service:

sc start MALSERVICE

We can verify everything went as planned with process explorer.

Here we can see that malsvchost is a child of cdb. We can also see that cdb.exe is listening on TCP port 5505.

Attach the debugger

Now we want to attach to the listening cdb with WinDBG.

Open WinDBG

Go to File -> Connect to Remote Session…

Enter in the following: tcp:Port=5005,Server=localhost

All going to plan you should see something similar to the following (your WinDBG layout will vary):

A important piece to remember here is that we are debugging the copy of svchost.exe - malsvchost.exe but we want to debug the ServiceDLL - our sample.

We can have WinDBG break when a specific module is loaded with the following command:

sxe ld sample.dll

Enter the command g to allow execution to continue. When malsvchost loads sample.dll WinDBG will break:

Looking at Process Explorer again we can see that malsvchost.exe has indeed loaded our sample.dll.

Once you get going you can carry on using WinDBG or you can immobilise your sample with WinDBG and attach with a debugger you’re more comfortable with.

Special Thanks

Just a few thanks to some people who helped me out or inspired me to write this post.

And so many others.