LogParser launches COM in a Single Threaded Apartment

by Klaus Graefensteiner 15. December 2007 10:15

I was developing a custom input format for the LogParser 2.2. This COM plug-in reads binary files that can be several Gigabytes big. Scanning a file this size can take several minutes. My C# Windows Forms application that hosted the LogParser COM server and my custom input format COM server needed to stay responsive to user input during the processing of the file. I considered two approaches:

  • Add a Message pump to my custom input format or
  • Launch my LogParser query from a BackgroundWorkerThread component  in my C# application.

I wanted to make an educated decision based on how LogParser.exe is initializing its COM runtime. This article describes how I debugged LogParser.exe to determine the parameters it used in the CoInitializeEx() function call.

Particle

CoInitializeEx()

Knowing that the function CoInitializeEx() determines the threading model used by your threads is the key information to start the reverse engineering investigation. According to MSDN: "CoInitializeEx() initializes the COM library for use by the calling thread, sets the thread's concurrency model, and creates a new apartment for the thread if one is required." Detailed information can be found when you search for CoInitializeEx on MSDN.

It Depends

If you have the source code and the debugging symbols it is very easy to set a breakpoint at a line of your source code in Visual Studio. But in this case we I don't have the source code to the DLL that includes the code for CoInitializeEx(). The DLL is OLO32.DLL. WinDBG, which is part of the Debugging Tools For Windows is able to inject breakpoint instructions (int 3) into the code of OLE32.DLL based on a code offset supplied by a Set Breakpoint command.

To calculate the memory offset where the debugger should inject the breakpoint instruction requires 2 pieces of information. First we need to know at which address LogParser.exe loads OLE32.DLL. This can be done by attaching LogParser.exe to WinDBG, forcing a debug break and listing the modules. The other piece of information is the offset of the CoInitializeEx() function within the OLE32.DLL. This offset can be gathered using the Dependency Walker utility "Depends.exe". This is part of the Visual Studio tool box. Opening OLE32.DLL with depends.exe will show us the memory offset of the function within the DLL.

Walking OLE32 Dependencies

The Dependency Walker tells us that the function entry point of CoInitializeEx() in OLE32.DLL is at 0x0001EF6B.

Early Attachment

The function CoInitializeEx usually gets called very early in the game. Attaching the debugger to the process manually would be to late. The function has most likely already be called and the break point will never get hit again. Fortunately there is a way to automatically attach a debugger to a process during startup. The following registry entry will configure Windows to attach WinDBG to LogParser.exe at startup.

    1 [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\logparser.exe]

    2 "Debugger"="c:\\debuggers\\windbg.exe"

Query the Event Logs with LogParser

Before we can put it all together and finally know the answer of our initial question we need to come up with a simple query for LogParser to execute. The following command reads the Windows Application Event Log and exports some events into a text file:

    1 LogParser "SELECT TimeGenerated, SourceName, EventCategoryName, Message INTO report.txt FROM Application WHERE EventID = 1800" -o:CSV

Start your Engines

Once the "Image File Execution Options" for LogParser.exe have been set and the LogParser query has been kicked off, we finally should get a closer look at OLE32.DLL in the WinDBG debugger. WinDBG launched automatically and the LogParser.exe process is stopped in the debugger.

 LogParser Loaded Modules 

Right after WinDBG launches it lists the loaded modules automatically. OLE32.DLL is loaded at 0x774E0000. Doing a little math and adding the function entry point and the module load address of OLE32.DLL gives us the absolute address of the CoInitializeEx() function in the Virtual Memory of LogParser.exe:

0x774E0000 + 0x0001EF6B = 0x774FEF6B.

To set a break point at a specific address we are going to use the following WinDBG command:

    1 bp 774FEF6B

Loading Symbols and Setting a Breakpoint 

Before you continue, make sure that the symbol file path has been set correctly. It needs to point to the Microsoft Symbol Server. As a refresher here is a commonly used path:

    1 srv*c:\symbols*http://msdl.microsoft.com/download/symbols

Ready! Set! g

The next command is a simple g, which lets the debuggee run until it hits the breakpoint at CoInitializeEx().

Stop at CoInitialize

At this point we finally hit the breakpoint at CoInitializeEx(). Now we can look in the Call Stack Window and see what value the second parameter is that LogParser passed into this function.

Call Stack Window

The second parameter is an enumeration of type COINIT and its value is two. The enumeration is defined as:

    1 typedef enum tagCOINIT {

    2     COINIT_MULTITHREADED    = 0x0,

    3     COINIT_APARTMENTTHREADED = 0x2,

    4     COINIT_DISABLE_OLE1DDE  = 0x4,

    5     COINIT_SPEED_OVER_MEMORY = 0x8,

    6 } COINIT;

The value of the COINIT parameter is 2 according to the debugger. This means that LogParser.exe has been initialized as Apartment Threaded application.

Summary

This article describes a simple way to automatically attach a debugger to a process and set a breakpoint based on the memory address of a function entry point. In this case I found that the LogParser launched my custom LogParser input format in a single threaded apartment. Based on this knowledge I decided to use a simple message pump in my input plug-in COM server to keep my Windows Forms application responsive to user input.

 

Tags: ,

LogParser | Debugging

Comments

12/15/2007 6:11:45 PM #

trackback

Trackback from DotNetKicks.com

LogParser launches COM in a Single Threaded Apartment

DotNetKicks.com |

Comments are closed

About Klaus Graefensteiner

I like the programming of machines.

Add to Google Reader or Homepage

LinkedIn FacebookTwitter View Klaus Graefensteiner's profile on Technorati
Klaus Graefensteiner

Klaus Graefensteiner
works as Developer In Test and is founder of the PowerShell Unit Testing Framework PSUnit. More...

Open Source Projects

PSUnit is a Unit Testing framwork for PowerShell. It is designed for simplicity and hosted by Codeplex.
BlogShell is The tool for lazy developers who like to automate the composition of blog content during the writing of a blog post. It is hosted by CodePlex.

Administration

About

Powered by:
BlogEngine.Net
Version: 1.6.1.0

License:
Creative Commons License

Copyright:
© Copyright 2014, Klaus Graefensteiner.

Disclaimer:
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

Theme design:
This blog theme was designed and is copyrighted 2014 by Klaus Graefensteiner

Rendertime:
Page rendered at 8/21/2014 8:57:01 PM (PST Pacific Standard Time UTC DST -7)