Gone with the Exception...SX* to the Rescue!

Gone with the Exception...SX* to the Rescue!

Rate This
  • Comments 1

 

Hi, my name is Anurag Sarin, and I'm an Escalation Engineer from the Platforms Global Escalation Services 24x7 Team, located in Bangalore, India.

 

I recently worked a case dealing with a component that reported an exception. But it was not critical enough to crash the system and it was simply logged in a file. Because the root cause of the problem was not yet known, we did not have a deterministic way to reproduce the exception. The exception would just come and go. So catching the exception became a challenge. Do we take a dump? How do we break into the debugger to catch the exception when it occurs? Manual dumps wouldn't help because we didn't know when the exception would occur, and even if we did, it happened too fast to use Ctrl + Scroll Lock  + Scroll Lock.

 

A similar challenge is when you want to start debugging just after a module loads without knowing when the module load will happen. You can run into this while reverse engineering code or while live debugging. You may want to save all debugging efforts until a particular module gets loaded. Sometimes you just want to know if a module ever gets loaded in a particular code path.

 

In these situations, the ‘sx*’ command comes to our rescue. Below you will find a couple of nuggets to assist with these types of scenarios.

Break on exception

 

Let's say Windows Media Player reports “RPC Server is unavailable” when a user clicks "File\Open" and attempts to browse to a remote computer. In this situation the ‘sxe’ command is your friend. This command ‘sets an exception’ from the debugger. When this is set the target breaks into the debugger before any other error handlers are activated

 

By the way, RPC_S_SERVER_UNAVAILABLE is win32 error 1722 (0x06ba) with the description “RPC Server is unavailable” and is a common networking issue.

 

This is how WinError.h in Windows SDK documents it

 

//

// MessageId: RPC_S_SERVER_UNAVAILABLE

//

// MessageText:

//

// The RPC server is unavailable.

//

#define RPC_S_SERVER_UNAVAILABLE         1722L

 

Here are the steps to catch the “RPC Server is unavailable” exception. 

 

1. Attach the debugger to the process with the RPC_S_SERVER_UNAVAILABLE error.  In our example we’ll attach to wmplayer.exe.

 

2. Break into debugger to set or verify the symbol path.

 

3. Reload the symbols.

 

.reload

 

4. Clear any previously set exceptions.

 

sdx  *

 

5. Set the exception on 1722 (0x06ba) i.e. RPC_S_SERVER_UNAVAILABLE “RPC Server is unavailable”.

 

sxe 06ba

 

6. Let the process run until we hit the exception. You may hit a different exception before the one you’re looking for in which case you hit 'g' to continue execution.

 

g

 

7. This is the output from the debugger on a Vista RTM machine.

 

(b2c.f28): Unknown exception - code 000006ba (first chance) 

First chance exceptions are reported before any exception handling.

This exception may be expected and handled.

eax=0601e47c ebx=00000000 ecx=00000000 edx=049cd488 esi=000006ba edi=0601e5a4

eip=76dbb09e esp=0601e47c ebp=0601e4cc iopl=0         nv up ei pl zr na pe nc

cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246

kernel32!RaiseException+0x58:

76dbb09e c9              leave

0:036> kv100

ChildEBP RetAddr  Args to Child             

0601e4cc 76ea0911 000006ba 00000001 00000000 kernel32!RaiseException+0x58 (FPO: [4,20,0])

0601e4e4 76ea08e9 000006ba 0601e9dc 76f2e07d RPCRT4!RpcpRaiseException+0x1e (FPO: [0,0,0])

0601e4f0 76f2e07d 000006ba f61cdc85 05545938 RPCRT4!RpcRaiseException+0x16

0601e9dc 760a9e12 760a8908 760a95ea 0601e9fc RPCRT4!NdrClientCall2+0xd51                       

0601e9f4 760a9e5b 0553fee0 00000064 0601ea54 NETAPI32!NetrWkstaGetInfo+0x19 (FPO: [3,1,0])

0601ea40 75106f02 0553fee0 00000064 0601ea54 NETAPI32!NetWkstaGetInfo+0x3b (FPO: [SEH])      ßNetWkstaGetInfo called for request on information on workstation.

0601ea5c 75106f86 0553fee0 0601ea84 0601eb5c ntlanman!ServerExists+0x19 (FPO: [2,2,0])

0601ea98 75e24ede 0601ec00 05545938 0601ec44 ntlanman!NPDfsLmGetResourceInformation+0x177 (FPO: [4,8,4])

0601eab0 75e23bb9 055939f0 caa0f4a6 00000000 MPR!CGetResourceInformation::TestProvider+0x1a (FPO: [1,0,0])

0601eb08 75e23ac7 caa0f4ea 0601ec44 0601eb5c MPR!CRoutedOperation::GetResult+0xf6 (FPO: [SEH])

0601eb44 75e23a79 0601ec54 0601eb90 75e24f0d MPR!CMprOperation::Perform+0x65 (FPO: [SEH])

0601eb50 75e24f0d 00000001 75e24f5c 000000a4 MPR!CRoutedOperation::Perform+0x22 (FPO: [1,0,4])

0601eb90 76f5978a 0601ec00 05545938 0601ec44 MPR!WNetGetResourceInformationW+0x26 (FPO: [4,13,0])

0601ebb4 76f597f5 0601ec00 00000000 00000000 SHELL32!SHWNetGetResourceInformationAlloc+0x40 (FPO: [4,0,4])

0601ebd8 76f63d75 0601ec00 0601ec54 0601ec44 SHELL32!CNetFolder::_GetResourceInformationAlloc+0xf4 (FPO: [5,0,4])

0601f278 76f63bc3 001d019a 05560288 0553db08 SHELL32!CNetFolder::_ParseUNCName+0x1a7 (FPO: [7,414,4])

0601f4c4 76fe2c3e 0553db50 001d019a 05560288 SHELL32!CNetFolder::ParseDisplayName+0x123 (FPO: [7,135,4])

0601f52c 6de11f8c 05547c94 001d019a 05560288 SHELL32!CRegFolder::ParseDisplayName+0x90 (FPO: [7,14,4])

0601f5b0 6de11e0d 001d019a 05560288 0553db08 NetworkExplorer!CNetworkExplorerFolder::_IsValidServer+0x9f (FPO: [5,21,4])

0601f5e0 76fe58ab 0553da98 001d019a 05560288 NetworkExplorer!CNetworkExplorerFolder::ParseDisplayName+0x68 (FPO: [7,2,4])

0601f608 76fe2d13 0553da98 049d0008 001d019a SHELL32!CDesktopFolder::_ChildParseDisplayName+0x22 (FPO: [8,0,4])

0601f654 76fe2c3e 0553da98 001d019a 049d0008 SHELL32!CDesktopFolder::ParseDisplayName+0x8c (FPO: [7,6,4])

0601f6bc 76fe2b91 0559544c 001d019a 05560288 SHELL32!CRegFolder::ParseDisplayName+0x90 (FPO: [7,14,4])

0601f6f4 76c8c0f3 00000000 30c10000 0601f788 SHELL32!SHParseDisplayName+0x98 (FPO: [5,2,4])

0601f734 76c8c03a 0601f994 0601f788 0601f780 COMDLG32!CAsyncParser::_ParseFromDesktop+0x73 (FPO: [3,7,0])

0601fba0 76c808d8 0556b850 00000000 00000000 COMDLG32!CAsyncParser::_ParseOneItem+0x2e1 (FPO: [2,275,4])

0601fbbc 76c80bc6 0601fc40 77c1b132 0555b088 COMDLG32!CAsyncParser::_Parse+0x4a (FPO: [0,1,0])

0601fbc4 77c1b132 0555b088 00000000 00000000 COMDLG32!CAsyncParser::s_ThreadProc+0xd (FPO: [1,0,0])

0601fc40 76de3833 0023c72c 0601fc8c 77b1a9bd SHLWAPI!WrapperThreadProc+0x10f (FPO: [1,25,4])

0601fc4c 77b1a9bd 0023c72c 0601b824 00000000 kernel32!BaseThreadInitThunk+0xe (FPO: [1,0,0])

0601fc8c 00000000 77c1b09a 0023c72c 00000000 ntdll!_RtlUserThreadStart+0x23 (FPO: [SEH])

 

 

8. After you break into the stack for the 6ba exception, you might want to get a dump using the following command.

 

0:000> .dump /ma c:\dump1.dmp

Creating c:\dump2.dmp - mini user dump used

Dump successfully written

 

9. Now that we have a dump in the exception code path, it might be a good idea to tell the debugger to stop breaking for this exception.  

 

sxd 06ba

 

 

Now the debugger does not break for this exception.

Note: To detach the debugger from the process do a ‘.detach’. If you just close the debugger it will exit the process too.

 

Looking at the top of the stack, we see that wmplayer sent a request for a share access and failed due to (what looks like a network problem). I say this as we see that MRP  invokes ntlanman (Windows Redirector for Network Shares) which further request information on workstation.name ( NetWkstaGetInfo ) on the network (a Remote RPC call RPCRT4!NdrClientCall2). The next step should be to take a network trace and investigate if there are any networking problems on the network.

 

And it would make root cause determination much easier if you knew the user was attempting to connect to a nonexistent machine name (\\<Bad Machine Name>) while doing the File\Open in Windows Media Player. J

Break on Module load

 

Now let’s talk about a scenario where we want to start debugging when a particular DLL gets loaded. Let’s take the example of mpr.dll loading using the scenario above.

 

1.       Follow steps 1 through 4 mentioned above, to attach to wmplayer.exe

 

2.        In this case we set an exception on ‘module load of MRP.DLL‘.

 

sxe ld mpr.dll

 

3. Now let the process run. It will break back into the debugger when the DLL is loaded.

 

 g

 

This is the debugger output on a Windows 2008 machine when MPR.DLL gets loaded into the wmplayer process.

 

0:001> g

ModLoad: 753d0000 753e4000   C:\Windows\system32\MPR.dll

eax=75a3b111 ebx=00000000 ecx=00000000 edx=75a7275c esi=7ffad000 edi=20000000

eip=771a9a94 esp=0291df74 ebp=0291dfb8 iopl=0         nv up ei pl zr na pe nc

cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246

ntdll!KiFastSystemCallRet:

771a9a94 c3              ret

0:014> kvn ffff

 #   Memory  ChildEBP RetAddr  Args to Child             

00           0291df70 771a8764 7717df04 000003d4 ffffffff ntdll!KiFastSystemCallRet (FPO: [0,0,0])

01         4 0291df74 7717df04 000003d4 ffffffff 0291e0a0 ntdll!ZwMapViewOfSection+0xc (FPO: [10,0,0])

02        44 0291dfb8 7717c855 000003d4 0291e0a0 0291e088 ntdll!LdrpMapViewOfDllSection+0x67 (FPO: [5,2,4])

03       108 0291e0c0 7717fab9 01e2f640 0291e100 01e66a58 ntdll!LdrpMapDll+0x417 (FPO: [SEH])

04       274 0291e334 7717610e 01e2f640 72410321 0291e378 ntdll!LdrpLoadImportModule+0x206 (FPO: [4,145,4])

05        4c 0291e380 77176233 01e2f640 01e4f020 0291e3ac ntdll!LdrpHandleOneNewFormatImportDescriptor+0x84 (FPO: [4,10,4])

06        1c 0291e39c 77176248 01e2f640 01e4f020 724102c0 ntdll!LdrpHandleNewFormatImportDescriptors+0x1d (FPO: [3,0,4])

07        7c 0291e418 7717c5ba 01e2f640 01e4f020 75a35de0 ntdll!LdrpWalkImportDescriptor+0x1f2 (FPO: [SEH])

08       288 0291e6a0 77177a52 00000000 01e2f640 0291e994 ntdll!LdrpLoadDll+0x2f1 (FPO: [SEH])

09       284 0291e924 76d031ba 01e2f640 0291e994 0291e954 ntdll!LdrLoadDll+0x22a (FPO: [SEH])

0a        64 0291e988 75a4b34f 0291ea04 00000000 00000008 kernel32!LoadLibraryExW+0x252 (FPO: [SEH])

0b        24 0291e9ac 75a4b239 0291ea04 0291e9d0 0291e9d4 ole32!CClassCache::CDllPathEntry::LoadDll+0xae (FPO: [4,1,4])

0c        30 0291e9dc 75a469fe 0291ea04 0291ecec 0291e9fc ole32!CClassCache::CDllPathEntry::Create_rl+0x37 (FPO: [3,3,4])

0d       24c 0291ec28 75a46913 00000001 0291ecec 0291ec58 ole32!CClassCache::CClassEntry::CreateDllClassEntry_rl+0xd4 (FPO: [3,139,4])

0e        48 0291ec70 75a467b4 00000001 00505350 0291ec9c ole32!CClassCache::GetClassObjectActivator+0x224 (FPO: [3,10,4])

0f        38 0291eca8 75a474c0 0291ecec 00000000 0291f2f4 ole32!CClassCache::GetClassObject+0x30 (FPO: [1,3,4])

10        7c 0291ed24 75a4705b 75b4e428 00000000 0291f2f4 ole32!CServerContextActivator::CreateInstance+0x110 (FPO: [4,25,4])

11        40 0291ed64 75a4772d 0291f2f4 00000000 0291f85c ole32!ActivationPropertiesIn::DelegateCreateInstance+0x108 (FPO: [3,7,4])

12        54 0291edb8 75a4764f 75b4e4ac 00000000 0291f2f4 ole32!CApartmentActivator::CreateInstance+0x112 (FPO: [4,13,4])

13        20 0291edd8 75a47609 75b4e48c 00000001 00000000 ole32!CProcessActivator::CCICallback+0x6d (FPO: [6,1,4])

14        20 0291edf8 75a475ba 75b4e48c 0291f150 00000000 ole32!CProcessActivator::AttemptActivation+0x2c (FPO: [7,0,0])

15        3c 0291ee34 75a476af 75b4e48c 0291f150 00000000 ole32!CProcessActivator::ActivateByContext+0x4f (FPO: [6,3,4])

16        28 0291ee5c 75a4705b 75b4e48c 00000000 0291f2f4 ole32!CProcessActivator::CreateInstance+0x49 (FPO: [4,1,4])

17        40 0291ee9c 75a47121 0291f2f4 00000000 0291f85c ole32!ActivationPropertiesIn::DelegateCreateInstance+0x108 (FPO: [3,7,4])

18       260 0291f0fc 75a4705b 75b4e4b4 00000000 0291f2f4 ole32!CClientContextActivator::CreateInstance+0xb0 (FPO: [4,6,4])

19        40 0291f13c 75a472c5 0291f2f4 00000000 0291f85c ole32!ActivationPropertiesIn::DelegateCreateInstance+0x108 (FPO: [3,7,4])

1a       7d4 0291f910 75a6e2a2 0291f9f4 00000000 00000017 ole32!ICoCreateInstanceEx+0x403 (FPO: [8,50,4])

1b        60 0291f970 75a6e203 0291f9f4 00000000 00000017 ole32!CComActivator::DoCreateInstance+0xd9 (FPO: [7,11,4])

1c        24 0291f994 75a6e1bc 0291f9f4 00000000 00000017 ole32!CoCreateInstanceEx+0x38 (FPO: [6,0,0])

1d        30 0291f9c4 72751489 0291f9f4 00000000 00000017 ole32!CoCreateInstance+0x37 (FPO: [5,3,4])

1e        44 0291fa08 727550b9 00000000 022cd14c 022cd140 FunDisc!CQueryWorker::CreateProvider+0x1a6 (FPO: [1,7,4])

1f        34 0291fa3c 72755028 0291fa80 00000000 00000000 FunDisc!CQueryWorker::Execute+0x77 (FPO: [1,7,4])

20        18 0291fa54 74892c26 00000000 0291fa80 0057f198 FunDisc!CFunctionInstanceCollectionQuery::Execute+0x66 (FPO: [2,0,4])

21        1c 0291fa70 74892d21 0057f198 00000001 00000000 NetworkItemFactory!CNetworkItemFactory::_StartFDQuery+0x84 (FPO: [4,0,4])

22        30 0291faa0 74892d8b 0057f198 0291fac0 7489478d NetworkItemFactory!CNetworkItemFactory::s_StartFDInMTA+0xa8 (FPO: [1,3,4])

23         c 0291faac 7489478d 0057f198 00000000 00000000 NetworkItemFactory!FDBackgroundThreadHandler+0x1b (FPO: [1,0,0])

24        14 0291fac0 76d24911 01e4abd0 0291fb0c 7718e4b6 NetworkItemFactory!ThreadHandler+0xf (FPO: [1,0,0])

25         c 0291facc 7718e4b6 01e4abd0 75a3404c 00000000 kernel32!BaseThreadInitThunk+0xe (FPO: [1,0,0])

26        40 0291fb0c 7718e489 7489477e 01e4abd0 ffffffff ntdll!__RtlUserThreadStart+0x23 (FPO: [SEH])

27        18 0291fb24 00000000 7489477e 01e4abd0 00000000 ntdll!_RtlUserThreadStart+0x1b (FPO: [2,2,0])

 

From the stack above, you can clearly see that seven frames below the top is what ‘was’ happening just ‘before’ the dll got loaded. How do I get to the point just ‘after’ the module gets loaded? Well one way is to use ‘gu’ twelve times. Note: The purpose of this is to show you how to use the various exception related commands.

 

0:014> gu

eax=00000000 ebx=00000000 ecx=0291df74 edx=771a9a94 esi=7ffad000 edi=20000000

eip=771a8764 esp=0291df78 ebp=0291dfb8 iopl=0         nv up ei pl zr na pe nc

cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246

ntdll!ZwMapViewOfSection+0xc:

771a8764 c22800          ret     28h

<SNIP>

 

This is the point just ‘after’ MPR.DLL got loaded.

 

0:014> kvn ffff

 #   Memory  ChildEBP RetAddr  Args to Child             

00           0291e9dc 75a469fe 0291ea04 0291ecec 0291e9fc ole32!CClassCache::CDllPathEntry::Create_rl+0x37 (FPO: [3,3,4])

01       24c 0291ec28 75a46913 00000001 0291ecec 0291ec58 ole32!CClassCache::CClassEntry::CreateDllClassEntry_rl+0xd4 (FPO: [3,139,4])

02        48 0291ec70 75a467b4 00000001 00505350 0291ec9c ole32!CClassCache::GetClassObjectActivator+0x224 (FPO: [3,10,4])

03        38 0291eca8 75a474c0 0291ecec 00000000 0291f2f4 ole32!CClassCache::GetClassObject+0x30 (FPO: [1,3,4])

04        7c 0291ed24 75a4705b 75b4e428 00000000 0291f2f4 ole32!CServerContextActivator::CreateInstance+0x110 (FPO: [4,25,4])

05        40 0291ed64 75a4772d 0291f2f4 00000000 0291f85c ole32!ActivationPropertiesIn::DelegateCreateInstance+0x108 (FPO: [3,7,4])

06        54 0291edb8 75a4764f 75b4e4ac 00000000 0291f2f4 ole32!CApartmentActivator::CreateInstance+0x112 (FPO: [4,13,4])

07        20 0291edd8 75a47609 75b4e48c 00000001 00000000 ole32!CProcessActivator::CCICallback+0x6d (FPO: [6,1,4])

08        20 0291edf8 75a475ba 75b4e48c 0291f150 00000000 ole32!CProcessActivator::AttemptActivation+0x2c (FPO: [7,0,0])

09        3c 0291ee34 75a476af 75b4e48c 0291f150 00000000 ole32!CProcessActivator::ActivateByContext+0x4f (FPO: [6,3,4])

0a        28 0291ee5c 75a4705b 75b4e48c 00000000 0291f2f4 ole32!CProcessActivator::CreateInstance+0x49 (FPO: [4,1,4])

0b        40 0291ee9c 75a47121 0291f2f4 00000000 0291f85c ole32!ActivationPropertiesIn::DelegateCreateInstance+0x108 (FPO: [3,7,4])

0c       260 0291f0fc 75a4705b 75b4e4b4 00000000 0291f2f4 ole32!CClientContextActivator::CreateInstance+0xb0 (FPO: [4,6,4])

0d        40 0291f13c 75a472c5 0291f2f4 00000000 0291f85c ole32!ActivationPropertiesIn::DelegateCreateInstance+0x108 (FPO: [3,7,4])

0e       7d4 0291f910 75a6e2a2 0291f9f4 00000000 00000017 ole32!ICoCreateInstanceEx+0x403 (FPO: [8,50,4])

0f        60 0291f970 75a6e203 0291f9f4 00000000 00000017 ole32!CComActivator::DoCreateInstance+0xd9 (FPO: [7,11,4])

10        24 0291f994 75a6e1bc 0291f9f4 00000000 00000017 ole32!CoCreateInstanceEx+0x38 (FPO: [6,0,0])

11        30 0291f9c4 72751489 0291f9f4 00000000 00000017 ole32!CoCreateInstance+0x37 (FPO: [5,3,4])

12        44 0291fa08 727550b9 00000000 022cd14c 022cd140 FunDisc!CQueryWorker::CreateProvider+0x1a6 (FPO: [1,7,4])

13        34 0291fa3c 72755028 0291fa80 00000000 00000000 FunDisc!CQueryWorker::Execute+0x77 (FPO: [1,7,4])

14        18 0291fa54 74892c26 00000000 0291fa80 0057f198 FunDisc!CFunctionInstanceCollectionQuery::Execute+0x66 (FPO: [2,0,4])

15        1c 0291fa70 74892d21 0057f198 00000001 00000000 NetworkItemFactory!CNetworkItemFactory::_StartFDQuery+0x84 (FPO: [4,0,4])

16        30 0291faa0 74892d8b 0057f198 0291fac0 7489478d NetworkItemFactory!CNetworkItemFactory::s_StartFDInMTA+0xa8 (FPO: [1,3,4])

17         c 0291faac 7489478d 0057f198 00000000 00000000 NetworkItemFactory!FDBackgroundThreadHandler+0x1b (FPO: [1,0,0])

18        14 0291fac0 76d24911 01e4abd0 0291fb0c 7718e4b6 NetworkItemFactory!ThreadHandler+0xf (FPO: [1,0,0])

19         c 0291facc 7718e4b6 01e4abd0 75a3404c 00000000 kernel32!BaseThreadInitThunk+0xe (FPO: [1,0,0])

1a        40 0291fb0c 7718e489 7489477e 01e4abd0 ffffffff ntdll!__RtlUserThreadStart+0x23 (FPO: [SEH])

1b        18 0291fb24 00000000 7489477e 01e4abd0 00000000 ntdll!_RtlUserThreadStart+0x1b (FPO: [2,2,0])

Disable First Chance Exceptions

Another case where sx* commands are helpful is when you need to disable first change exceptions. Click here for more on the topic.

If you do not want to see a first chance exception in the debugger, you should disable first chance exception handling for the specific exception code. Otherwise, when the first chance exception occurs, you may need to instruct the debugger to pass on the exception to the program to be handled as usual. How do we do this?

 This is an example of disabling first chance Access Violation Exception.

sxd av

Let me show you a quick example using the MMC.exe process. On my Windows XP machine, I attached a debugger to the mmc.exe process and added “Computer Management” from File -> ‘Add/Remove Snap in’. The mmc.exe broke into the debugger on a first chance exception every time I clicked “Services and Applications”. I did not want this to happen because this was not the focus of my investigation.

This is what the first chance exception looks like in the debugger.

(d84.cc): Break instruction exception - code 80000003 (first chance)

eax=7ffd7000 ebx=00000001 ecx=00000002 edx=00000003 esi=00000004 edi=00000005

eip=7c901230 esp=00aeffcc ebp=00aefff4 iopl=0         nv up ei pl zr na pe nc

cs=001b  ss=0023  ds=0023  es=0023  fs=0038  gs=0000             efl=00000246

ntdll!DbgBreakPoint:

7c901230 cc              int     3

 

BTW, if you type ‘sx’, you get the current exception settings.

0:002> sx

 

<Snip>

 

  av - Access violation - break - not handled

 

<Snip>

 

So I disabled first chance exceptions by using this command.

sxd av

After running the command, first chance exceptions don’t cause the debugger to break. We only see the notifications.

 

(d84.d40): Access violation - code c0000005 (first chance)

 

After disabling first chance exceptions, this is our sx settings.

0:002> sx

 

<Snip>

 

  av - Access violation - second-chance break - not handled

 

<Snip>

Break on a user mode module from kernel mode debugging

 

A common challenge we face in ‘day to day’ debugging is how to break on a ‘user mode’ DLL - ‘module load’, while doing a kernel mode debug. Here's an example of setting a break point on the mpr!WNetEnumResource API from kernel mode.

 

1.       You must run !gflag +ksl to enable Kernel Stack Loading in the debugger. Now the kernel will notify the debugger when a user mode module loads occur (normally the kernel debugger is only notified of kernel module load, not user).  One caveat is the debugger is only notified on the first load of a particular module, rather than every load of the module.  However, this will let you set any breakpoints you're interested in the user mode module with ‘bu’.

 

kd> !gflag +ksl

New NtGlobalFlag contents: 0x00040000

    ksl - Enable loading of kernel debugger symbols

 

 2.      Set the process context to your user mode process using ‘.process -r -p <EPROCESS>’. I used mmc.exe in my case .

 

PROCESS 899d0c78  SessionId: 1  Cid: 0850    Peb: 7ffdf000  ParentCid: 0138

    DirBase: 7f7bf160  ObjectTable: 94fedcc8  HandleCount: 345.

    Image: mmc.exe

 

kd> .process -r -p 899d0c78

Implicit process is now 899d0c78

.cache forcedecodeuser done

Loading User Symbols

................................................................

.................

 

3.      Set an exception on module load ‘sxe ld usermode.dll’

 

kd> sxe ld mpr.dll

 

kd> sx

<Snip>

  ld - Load module - break

       (only break for mpr.dll)

<Snip>

 

This is what the debugger displays when mpr.dll gets loaded into the mmc process.

 

nt!DbgLoadImageSymbols+0x47:

816497f3 cc              int     3

 

kd> k ffff

  Memory  ChildEBP RetAddr 

          8e089b20 81780dcb nt!DbgLoadImageSymbols+0x47

       54 8e089b74 8186d735 nt!MiLoadUserSymbols+0x1ed

       a4 8e089c18 8185f655 nt!MiMapViewOfImageSection+0x885

       70 8e089c88 8185f745 nt!MiMapViewOfSection+0x22a

       30 8e089cb8 8185f952 nt!MmMapViewOfSection+0x2a

       7c 8e089d34 81692a1a nt!NtMapViewOfSection+0x203

        0 8e089d34 77a59a94 nt!KiFastCallEntry+0x12a

          0771e050 77a58764 ntdll!KiFastSystemCallRet

        4 0771e054 77a2df04 ntdll!ZwMapViewOfSection+0xc

       44 0771e098 77a2c855 ntdll!LdrpMapViewOfDllSection+0x67

      108 0771e1a0 77a2fab9 ntdll!LdrpMapDll+0x417

      274 0771e414 77a2610e ntdll!LdrpLoadImportModule+0x206

       4c 0771e460 77a26233 ntdll!LdrpHandleOneNewFormatImportDescriptor+0x84

       1c 0771e47c 77a26248 ntdll!LdrpHandleNewFormatImportDescriptors+0x1d

       7c 0771e4f8 77a2c5ba ntdll!LdrpWalkImportDescriptor+0x1f2

      288 0771e780 77a27a52 ntdll!LdrpLoadDll+0x2f1

      284 0771ea04 777131ba ntdll!LdrLoadDll+0x22a

       64 0771ea68 7689b34f kernel32!LoadLibraryExW+0x252

       24 0771ea8c 7689b239 ole32!CClassCache::CDllPathEntry::LoadDll+0xae

       30 0771eabc 768969fe ole32!CClassCache::CDllPathEntry::Create_rl+0x37

      24c 0771ed08 76896913 ole32!CClassCache::CClassEntry::CreateDllClassEntry_rl+0xd4

       48 0771ed50 768967b4 ole32!CClassCache::GetClassObjectActivator+0x224

       38 0771ed88 768974c0 ole32!CClassCache::GetClassObject+0x30

       7c 0771ee04 7689705b ole32!CServerContextActivator::CreateInstance+0x110

       40 0771ee44 7689772d ole32!ActivationPropertiesIn::DelegateCreateInstance+0x108

       54 0771ee98 7689764f ole32!CApartmentActivator::CreateInstance+0x112

       20 0771eeb8 76897609 ole32!CProcessActivator::CCICallback+0x6d

       20 0771eed8 768975ba ole32!CProcessActivator::AttemptActivation+0x2c

       3c 0771ef14 768976af ole32!CProcessActivator::ActivateByContext+0x4f

       28 0771ef3c 7689705b ole32!CProcessActivator::CreateInstance+0x49

       40 0771ef7c 76897121 ole32!ActivationPropertiesIn::DelegateCreateInstance+0x108

      260 0771f1dc 7689705b ole32!CClientContextActivator::CreateInstance+0xb0

       40 0771f21c 768972c5 ole32!ActivationPropertiesIn::DelegateCreateInstance+0x108

      7dc 0771f9f8 768be2a2 ole32!ICoCreateInstanceEx+0x403

       60 0771fa58 768be203 ole32!CComActivator::DoCreateInstance+0xd9

       24 0771fa7c 768be1bc ole32!CoCreateInstanceEx+0x38

       30 0771faac 733d1489 ole32!CoCreateInstance+0x37

       44 0771faf0 733d50b9 fundisc!CQueryWorker::CreateProvider+0x1a6

       34 0771fb24 733d5028 fundisc!CQueryWorker::Execute+0x77

       18 0771fb3c 751d2c26 fundisc!CFunctionInstanceCollectionQuery::Execute+0x66

       1c 0771fb58 751d2d21 networkitemfactory!CNetworkItemFactory::_StartFDQuery+0x84

       30 0771fb88 751d2d8b networkitemfactory!CNetworkItemFactory::s_StartFDInMTA+0xa8

        c 0771fb94 751d478d networkitemfactory!FDBackgroundThreadHandler+0x1b

       14 0771fba8 77734911 networkitemfactory!ThreadHandler+0xf

        c 0771fbb4 77a3e4b6 kernel32!BaseThreadInitThunk+0xe

       40 0771fbf4 77a3e489 ntdll!__RtlUserThreadStart+0x23

       18 0771fc0c 00000000 ntdll!_RtlUserThreadStart+0x1b

 

So now we can set an unresolved break point on mpr!WNetEnumResourceW

 

kd> bu mpr!WNetEnumResourceW

 

And this is how we hit the break point for mpr!WNetEnumResourceW

 

Breakpoint 0 hit

mpr!WNetEnumResourceW:

001b:75c83522 6a14            push    14h

 

kd> !thread

THREAD 8a0bfaf0  Cid 0850.0540  Teb: 7ff49000 Win32Thread: 00000000 RUNNING on processor 0

Not impersonating

DeviceMap                 92b291e8

Owning Process            0       Image:         <Unknown>

Attached Process          899d0c78       Image:         mmc.exe

Wait Start TickCount      678430         Ticks: 0

Context Switch Count      8            

UserTime                  00:00:00.015

KernelTime                00:00:00.031

Win32 Start Address ntdll!TppWorkerThread (0x77a3dbb0)

Stack Init 8e10e000 Current 8e10dc98 Base 8e10e000 Limit 8e10b000 Call 0

Priority 10 BasePriority 8 PriorityDecrement 2 IoPriority 2 PagePriority 5

ChildEBP RetAddr  Args to Child             

070bfd34 75193c14 06db4658 070bfd5c 06ec9c28 mpr!WNetEnumResourceW   

070bfd74 75193ee3 00000000 00000000 00000000 fdWNet!CWNetProvider::EnumerateFunc+0x1c3  

070bfd84 75193f23 7ff49000 06e4f258 75193ee9 fdWNet!CWNetProviderWorkItem::Enumerate+0x24

070bfd9c 77a18a5c 00000000 7007c2c5 06259e38 fdWNet!CWNetProvider::ThreadProc+0x3a   

070bfe00 77a3de3f 01cfc920 06e4f258 7007c3f5 ntdll!RtlpTpWorkCallback+0xbf   

070bff30 77734911 06259e30 070bff7c 77a3e4b6 ntdll!TppWorkerThread+0x545   

070bff3c 77a3e4b6 06259e30 7007c3b9 00000000 kernel32!BaseThreadInitThunk+0xe

070bff7c 77a3e489 77a3dbb0 06259e30 ffffffff ntdll!__RtlUserThreadStart+0x23

070bff94 00000000 77a3dbb0 06259e30 00000000 ntdll!_RtlUserThreadStart+0x1b

 

Hope this article helps you navigate around using the sx commands to collect data or debug. Take a look at the Windbg help files for more info on the sx* commands.

 

 

Share this post :
Leave a Comment
  • Please add 1 and 4 and type the answer here:
  • Post