WinDbg/Examples

From aldeid
Jump to navigation Jump to search
You are here:
Examples

Description

In this example, we will analyze Lab10-01 from Practical Malware Analysis.

First step: analyze code in IDA Pro

Before we analyze the code in WinDbg, let's analyze it in IDA-Pro. We start with Lab10-01.exe. The malware first calls OpenSCManager to get a handle to the Windows service manager:

.text:00401000                 sub     esp, 1Ch
.text:00401003                 push    edi
.text:00401004                 push    0F003Fh         ; dwDesiredAccess
.text:00401009                 push    0               ; lpDatabaseName
.text:0040100B                 push    0               ; lpMachineName
.text:0040100D                 call    ds:OpenSCManagerA
.text:00401013                 mov     edi, eax
.text:00401015                 test    edi, edi
.text:00401017                 jnz     short loc_401020
.text:00401019                 pop     edi
.text:0040101A                 add     esp, 1Ch
.text:0040101D                 retn    10h

Then CreateService is called with dwServiceType set to 0x1, which corresponds to a kernel driver service (SERVICE_KERNEL_DRIVER). The code for the service is stored in the C:\Windows\System32\Lab10-01.sys file.

.text:00401020                 push    esi
.text:00401021                 push    0               ; lpPassword
.text:00401023                 push    0               ; lpServiceStartName
.text:00401025                 push    0               ; lpDependencies
.text:00401027                 push    0               ; lpdwTagId
.text:00401029                 push    0               ; lpLoadOrderGroup
.text:0040102B                 push    offset BinaryPathName ; "C:\\Windows\\System32\\Lab10-01.sys"
.text:00401030                 push    1               ; dwErrorControl
.text:00401032                 push    3               ; dwStartType
.text:00401034                 push    1               ; dwServiceType
.text:00401036                 push    0F01FFh         ; dwDesiredAccess
.text:0040103B                 push    offset ServiceName ; "Lab10-01"
.text:00401040                 push    offset ServiceName ; "Lab10-01"
.text:00401045                 push    edi             ; hSCManager
.text:00401046                 call    ds:CreateServiceA
.text:0040104C                 mov     esi, eax
.text:0040104E                 test    esi, esi
.text:00401050                 jnz     short loc_401069

If the function isn't successful (service may already exist), OpenService is called to open the existing service named "Lab10-01":

.text:0040104E                 test    esi, esi
.text:00401050                 jnz     short loc_401069
.text:00401052                 push    0F01FFh         ; dwDesiredAccess
.text:00401057                 push    offset ServiceName ; "Lab10-01"
.text:0040105C                 push    edi             ; hSCManager
.text:0040105D                 call    ds:OpenServiceA
.text:00401063                 mov     esi, eax
.text:00401065                 test    esi, esi
.text:00401067                 jz      short loc_401086

The service is then started:

.text:00401069                 push    0               ; lpServiceArgVectors
.text:0040106B                 push    0               ; dwNumServiceArgs
.text:0040106D                 push    esi             ; hService
.text:0040106E                 call    ds:StartServiceA
.text:00401074                 test    esi, esi
.text:00401076                 jz      short loc_401086

And the service is then immediately stopped (ControlService called with dwControl set to SERVICE_CONTROL_STOP):

.text:00401078                 lea     eax, [esp+24h+ServiceStatus]
.text:0040107C                 push    eax             ; lpServiceStatus
.text:0040107D                 push    1               ; dwControl
.text:0040107F                 push    esi             ; hService 0x1 = SERVICE_CONTROL_STOP
.text:00401080                 call    ds:ControlService

This latest instruction will unload the driver and call the driver's unload function.

WinDbg on the debuggee's side

Now we can open our debuggee's virtual machine and load Lab10-01.exe in WinDbg (Ctrl+E). Prior to opening WinDbg, move the Lab10-01.sys file to C:\Windows\System32

We set a breakpoint to 0x401080, just before the driver is unloaded, and reach the breakpoint:

0:000> bp 0x401080
*** WARNING: Unable to verify checksum for image00400000
*** ERROR: Module load completed but symbols could not be loaded for image00400000
0:000> g
Breakpoint 0 hit
eax=0012ff1c ebx=7ffd6000 ecx=77dbfb6d edx=00000000 esi=00143fe8 edi=00144ef8
eip=00401080 esp=0012ff08 ebp=0012ffc0 iopl=0         nv up ei pl nz na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206
image00400000+0x1080:
00401080 ff1510404000    call    dword ptr [image00400000+0x4010 (00404010)] ds:0023:00404010={ADVAPI32!ControlService (77dc49dd)}

WinDbg on the debugger's side

Find driver's address

Now, start WinDbg on the debugger's side, invoke kernel debugging (Ctrl+K) to connect to the debuggee's machine (refer to for more information). and select Debug > Break. You should get something similar to this:

In the command prompt, enter the following command to search for the driver:

kd> !drvobj Lab10-01
Driver object (861acb90) is for:
 \Driver\Lab10-01
Driver Extension List: (id , addr)

Device Object list:

Find driver function's address

Now that we know the driver is at offset 0x861acb90, we can display its structure:

kd> dt nt!_DRIVER_OBJECT 0x861acb90
   +0x000 Type             : 0n4
   +0x002 Size             : 0n168
   +0x004 DeviceObject     : (null) 
   +0x008 Flags            : 0x12
   +0x00c DriverStart      : 0xf7c80000 Void
   +0x010 DriverSize       : 0xe80
   +0x014 DriverSection    : 0x85f8df00 Void
   +0x018 DriverExtension  : 0x861acc38 _DRIVER_EXTENSION
   +0x01c DriverName       : _UNICODE_STRING "\Driver\Lab10-01"
   +0x024 HardwareDatabase : 0x80670ae0 _UNICODE_STRING "\REGISTRY\MACHINE\HARDWARE\DESCRIPTION\SYSTEM"
   +0x028 FastIoDispatch   : (null) 
   +0x02c DriverInit       : 0xf7c80959     long  +fffffffff7c80959
   +0x030 DriverStartIo    : (null) 
   +0x034 DriverUnload     : 0xf7c80486     void  +fffffffff7c80486
   +0x038 MajorFunction    : [28] 0x804f354a     long  nt!IopInvalidDeviceRequest+0

The driver's unload function is called DriverUnload and is at offset 0x34 to the beginning of the driver's start address. We can now set a breakpoint at 0x95191486 where the function is called:

kd> bp 0xf7c80486
kd> g

Don't forget to also resume (kd> g) WinDbg on the debuggee's side. Back to the debugger's side, here's what we should see:

Breakpoint 0 hit
f7c80486 8bff            mov     edi,edi

Analyze driver's function in WinDbg

Press Alt+7 or go to View > Disassembly to display the assembly code. Press F10 (step over) to see the different functions that are called.

[SNIP]
f7c804a0 ffd6            call    esi {nt!RtlCreateRegistryKey (805ddafe)}
[SNIP]
f7c804a8 ffd6            call    esi {nt!RtlCreateRegistryKey (805ddafe)}
[SNIP]
f7c804b0 ffd6            call    esi {nt!RtlCreateRegistryKey (805ddafe)}
[SNIP]
f7c804b9 ffd6            call    esi {nt!RtlCreateRegistryKey (805ddafe)}
[SNIP]
f7c804d6 ffd6            call    esi {nt!RtlWriteRegistryValue (805dda74)}
[SNIP]
f7c804e4 ffd6            call    esi {nt!RtlWriteRegistryValue (805dda74)}
[SNIP]

The program is calling RtlCreateRegistryKey several times to create registry keys and RtlWriteRegistryValue to set EnableFirewall value to 0.

Analysis of the function in IDA Pro

Now, we can analyze the function in IDA-Pro. Let's open the Lab01-01.sys file and rebase it (because the ImageBase is set to 0x00010000 by default).

The lm instruction can provide us with the driver start adddress:

kd> lm
start    end        module name
804d7000 806cfe00   nt         (pdb symbols)          c:\websymbols\ntkrnlpa.pdb\30B5FB31AE7E4ACAABA750AA241FF3311\ntkrnlpa.pdb

Unloaded modules:
f7c80000 f7c81000   Lab10-01.sys
ee683000 ee6ae000   kmixer.sys
f7bcc000 f7bcd000   drmkaud.sys
ee74e000 ee771000   aec.sys 
eebfe000 eec0b000   DMusic.sys
f76cd000 f76db000   swmidi.sys
f7bab000 f7bad000   splitter.sys
f794d000 f7952000   Cdaudio.SYS
f72ca000 f72cd000   Sfloppy.SYS

Now we want to rebase our driver in IDA-Pro. To do that, go to Edit > Segments > Rebase program... and enter "0xf7c80000". Now, we can easily find (at offset 0xf7c80486) the driver's function (DriverUnload) that has been called:

Comments

Keywords: windbg kernel debugging