Crash Dump Analysis Patterns (Part 282)
Sunday, November 27th, 2022COM Object analysis pattern is similar to C++ Object because of the same binary compatibility (the first object member is a pointer (vptr) to a table of function pointers (vtbl):
0:003> !teb
TEB at 000000c0033d8000
ExceptionList: 0000000000000000
StackBase: 000000c003480000
StackLimit: 000000c00347a000
SubSystemTib: 0000000000000000
FiberData: 0000000000001e00
ArbitraryUserPointer: 0000000000000000
Self: 000000c0033d8000
EnvironmentPointer: 0000000000000000
ClientId: 00000000000012e8 . 00000000000023c8
RpcHandle: 0000000000000000
Tls Storage: 000002a0b8be97f0
PEB Address: 000000c0033d1000
LastErrorValue: 14007
LastStatusValue: c0150008
Count Owned Locks: 0
HardErrorMode: 0
0:003> dpp 000000c00347a000 000000c003480000
[...]
000000c0`0347d698 000000c0`0347d630 00000001`574f454d
000000c0`0347d6a0 000002a0`b3dc36e0 00007ffc`f5f98430 combase!CObjectContext::`vftable’
000000c0`0347d6a8 000002a0`00000000
000000c0`0347d6b0 000000c0`0347d9e8 00000000`00000000
000000c0`0347d6b8 000000c0`0347d7a0 00000000`00260001
000000c0`0347d6c0 000002a0`b8c07050 4b62055c`8a40a45d
000000c0`0347d6c8 000000c0`0347d9b0 000000c0`0347e2c0
000000c0`0347d6d0 000000c0`0347d9b0 000000c0`0347e2c0
000000c0`0347d6d8 00000000`00000010
000000c0`0347d6e0 0000eda0`2ba8550b
000000c0`0347d6e8 000002a0`b8c0cbe0 00007ffc`f5f9bae8 combase!CClientChannel::`vftable’
000000c0`0347d6f0 00000000`00000002
[…]
We have the following chain of memory addresses: 000000c0`0347d6a0 (the address of the object pointer) -> 000002a0`b3dc36e0 (the address of the object allocated from heap) -> 00007ffc`f5f98430 (vptr, the address of the first vtbl entry).
0:003> dps 00007ffc`f5f98430
00007ffc`f5f98430 00007ffc`f5dacd30 combase!CObjectContext::QueryInterface
00007ffc`f5f98438 00007ffc`f5e25120 combase!CObjectContext::AddRef
00007ffc`f5f98440 00007ffc`f5d8e990 combase!CObjectContext::Release
00007ffc`f5f98448 00007ffc`f5e769e0 combase!CObjectContext::SetProperty
00007ffc`f5f98450 00007ffc`f5ef7000 combase!CObjectContext::RemoveProperty
00007ffc`f5f98458 00007ffc`f5dffb00 combase!CObjectContext::GetProperty
00007ffc`f5f98460 00007ffc`f5ef57e0 combase!CObjectContext::EnumContextProps
00007ffc`f5f98468 00007ffc`f5e20e90 combase!CObjectContext::Freeze
00007ffc`f5f98470 00007ffc`f5ef57a0 combase!CObjectContext::DoCallback
00007ffc`f5f98478 00007ffc`f5ef7140 combase!CObjectContext::SetContextMarshaler
00007ffc`f5f98480 00007ffc`f5df7d50 combase!CObjectContext::GetContextMarshaler
00007ffc`f5f98488 00007ffc`f5ef7120 combase!CObjectContext::SetContextFlags
00007ffc`f5f98490 00007ffc`f5ef5340 combase!CObjectContext::ClearContextFlags
00007ffc`f5f98498 00007ffc`f5ef5960 combase!CObjectContext::GetContextFlags
00007ffc`f5f984a0 00007ffc`f5d8e750 combase!CObjectContext::FreezeWithApartmentSet
00007ffc`f5f984a8 00007ffc`f5d9b4c0 combase!CObjectContext::InternalContextCallback
The difference from a traditional C++ object (with virtual functions) layout is that the first 3 functions in vtbl (vftable) are QueryInterface, AddRef, and Release. In a C++ object, there can be an arbitrary number of function pointers with any corresponding symbolic names.
- Dmitry Vostokov @ DumpAnalysis.org + TraceAnalysis.org -