comon - a new project in the wtrace toolkit
Almost five months ago, I wrote an article on implementing COM+ code, in which I promised a new troubleshooting tool in the wtrace toolkit. Today, I am pleased to present it to you! It’s an open-source Windbg extension named comon. You may use it to investigate COM class interactions and better understand application logic. During a debugging session, comon will record virtual table addresses (for the newly created COM objects) and allow you to query them or even set breakpoints (!cobp) on COM interface methods.
The !cometa command parses COM metadata found in the registry or standalone TLB/DLL files. Thanks to the metadata, comon will decode CLSIDs and IIDs to their human-friendly names. You may also query the metadata with the showc or showi subcommands.
Here is a short snippet of a debugging session with comon:
0:000> .load c:\Users\me\Debugging Tools for Windows\extensions-x86\comon.dll
[comon] Opening an existing metadata database from 'C:\Users\me\AppData\Local\Temp\cometa.db3'.
0:000> !comon attach
[comon] COM monitor enabled for process 0.
0:000> !cometa showi {59644217-3E52-4202-BA49-F473590CC61A}
Found: {59644217-3E52-4202-BA49-F473590CC61A} (IGameObject)
Methods:
- [0] QueryInterface
- [1] AddRef
- [2] Release
- [3] get_Name
- [4] get_Minerals
- [5] get_BuildTime
Registered VTables for IID:
- Module: protoss (32-bit), CLSID: {EFF8970E-C50F-45E0-9284-291CE5A6F771} (Protoss Probe), VTable offset: 0x37854
- Module: protoss (32-bit), CLSID: {F5353C58-CFD9-4204-8D92-D274C7578B53} (Protoss Nexus), VTable offset: 0x37808
0:000> sxe ld:protoss.dll
0:000> g
...
ModLoad: 70290000 702d4000 c:\Users\me\repos\protoss-com-example\Debug\protoss.dll
ntdll!NtMapViewOfSection+0xc:
774a4e7c c22800 ret 28h
0:000> !cobp {F5353C58-CFD9-4204-8D92-D274C7578B53} {59644217-3E52-4202-BA49-F473590CC61A} get_Name
0:000> bl
8 e Disable Clear 702a1505 0001 (0001) 0:**** protoss!ILT+1280(?get_NameNexusUAGJPAPA_WZ) "..."
0:000> g
...
[comon] 0:000 [IUnknown::QueryInterface] CLSID: {EFF8970E-C50F-45E0-9284-291CE5A6F771} (Protoss Probe), IID: {00000001-0000-0000-C000-000000000046} (IClassFactory)
[comon] 0:000 [IUnknown::QueryInterface] CLSID: {EFF8970E-C50F-45E0-9284-291CE5A6F771} (Protoss Probe), IID: {00000001-0000-0000-C000-000000000046} (IClassFactory)
[comon] 0:000 [combase!CoGetClassObject] CLSID: {EFF8970E-C50F-45E0-9284-291CE5A6F771} (Protoss Probe), IID: {00000001-0000-0000-C000-000000000046} (IClassFactory)
[comon] 0:000 [IUnknown::QueryInterface] CLSID: {EFF8970E-C50F-45E0-9284-291CE5A6F771} (Protoss Probe), IID: {246A22D5-CF02-44B2-BF09-AAB95A34E0CF} (IProbe)
[comon] 0:000 [IUnknown::QueryInterface] CLSID: {EFF8970E-C50F-45E0-9284-291CE5A6F771} (Protoss Probe), IID: {59644217-3E52-4202-BA49-F473590CC61A} (IGameObject)
[comon] 0:000 [IUnknown::QueryInterface] CLSID: {F5353C58-CFD9-4204-8D92-D274C7578B53} (Protoss Nexus), IID: {59644217-3E52-4202-BA49-F473590CC61A} (IGameObject)
== Method get_Name [3] called on a COM object (CLSID: {59644217-3E52-4202-BA49-F473590CC61A} (IGameObject), IID {F5353C58-CFD9-4204-8D92-D274C7578B53} (Protoss Nexus)) ==
0:000> k
# ChildEBP RetAddr
00 0095f540 004e482a protoss!ILT+1280(?get_NameNexusUAGJPAPA_WZ)
If you’re working with COM (or debugging Windows applications), I believe that comon will benefit your work. So comon, give it a try 😊 The latest binaries are on the release page and the documentation is here.