1、THE ADVANCED COMPUTING SYSTEMS ASSOCIATIONThe following paper was originally published in the5thUSENIX Conference on Object-Oriented Technologies and Systems(COOTS 99)San Diego, California, USA, May 37, 1999Intercepting and Instrumenting COM ApplicationsGalen C. HuntMicrosoft ResearchMichael L. Scot
2、tUniversity of Rochester 1999 by The USENIX AssociationAll Rights ReservedRights to individual papers remain with the author or the authors employer. Permission is granted for noncommercialreproduction of the work for educational or research purposes. This copyright notice must be included in the re
3、produced paper.USENIX acknowledges all trademarks herein.For more information about the USENIX Association:Phone: 1 510 528 8649 FAX: 1 510 548 5738Email: officeusenix.org WWW: http:/www.usenix.orgIntercepting and Instrumenting COM ApplicationsGalen C. Hunt Michael L. ScottMicrosoft Research Departm
4、ent of Computer ScienceOne Microsoft Way University of RochesterRedmond, WA 98052 Rochester, NY scottcs.rochester.eduAbstractBinary standard object models, such as MicrosoftsComponent Object Model (COM) enable the develop-ment of not just reusable components, but also an in-credible variety of usef
5、ul component services throughrun-time interception of binary standard interfaces.Interception of binary components can be used forconformance testing, debugging, profiling, transactionmanagement, serialization and locking, cross-standardmiddleware interoperability, automatic distributedpartitioning,
6、 security enforcement, clustering, just-in-time activation, and transparent component aggrega-tion.We describe the implementation of an interceptionand instrumentation system tested on over 300 COMbinary components, 700 unique COM interfaces, 2 mil-lion lines of code, and on 3 major commercial-grade
7、applications including Microsoft PhotoDraw 2000.The described system serves as the foundation for theCoign Automatic Distributed Partitioning System(ADPS), the first ADPS to automatically partition anddistribute binary applications.While the techniques described in this paper weredeveloped specifica
8、lly for COM, they have relevance toother object models with binary standards, such as in-dividual CORBA implementations.1. IntroductionWidespread adoption of Microsofts ComponentObject Model (COM) 16, 25 standard has producedan explosion in the availability of binary components,reusable pieces of so
9、ftware in binary form. It can beargued that this popularity is driven largely by COMsbinary standard for component interoperability.While binary compatibility is a great boon to themarket for commercial components, it also enables awide range of unique component services through in-terception. Becau
10、se the interfaces between COM com-ponents are well defined by the binary standard, acomponent service can exploit the binary standard tointercept inter-component communication and interposeitself between components.Interception of binary components can be used forconformance testing, debugging, dist
11、ributed communi-cation, profiling, transaction management, serializationand locking, cross-standard middleware inter-operability, automatic distributed partitioning, securityenforcement, clustering and replication, just-in-timeactivation, and transparent component aggregation.In this paper, we descr
12、ibe an interception systemproven on over 300 COM binary components, 700unique COM interfaces, and 2 million lines of code 5.We have extensively tested our COM interception sys-tem on three major commercial-grade applications: theMSDN Corporate Benefits Sample 12, MicrosoftPhotoDraw 2000 15, and the
13、Octarine word-processorfrom the Microsoft Research COM Applications Group.The interception system serves as the foundation for theCoign Automatic Distributed Partitioning System(ADPS) 7 8, the first ADPS to automatically parti-tion and distribute binary applications.In the next section, we describe
14、the fundamentalfeatures of COM as they relate to the interception andinstrumentation of COM applications. Sections 3 and 4explain and evaluate our mechanisms for interceptingobject instantiation requests and inter-object communi-cation respectively. We describe related work in Sec-tion 5. In Section
15、 6, we present our conclusions andpropose future work.2. COM FundamentalsCOM is a standard for creating and connecting com-ponents. A COM component is the binary templatefrom which a COM object is instantiated. Due toCOMs binary standard, programmers can easily buildapplications from components, eve
16、n components forwhich they have no source code. COMs major fea-tures include multiple interfaces per object, mappingsfor common programming languages, standard-mandated binary compatibility, and location-transparentinvocation.2.1. Polymorphic InterfacesAll first-class communication in COM takes plac
17、ethrough interfaces. An interface is a strongly typedreference to a collection of semantically related func-tions. An interface is identified by a 128-bit globallyunique identifier (GUID). An explicit agreement be-tween two components to communicate through anamed interface contains an implicit cont
18、ract of thebinary representation of the interface.Microsoft Interface Definition Language (MIDL)Figure 1 contains the definitions of two interfaces:IUnknown and Istream in the Microsoft InterfaceDefinition Language (MIDL). Syntactically, MIDL isvery similar to C+. To clarify the semantic features of
19、interfaces, MIDL attributes (enclosed in square brackets) can be attached to any interface, member function,or parameter. Attributes specify features such as thedata-flow direction of function arguments, the size ofdynamic arrays, and the scope of pointers. For exam-ple, the in, size_is(cb) attribut
20、e on the pbargument of the Write function in Figure 1 declaresthat pb is an input array with cb elements.uuid(00000000-0000-0000-C000-000000000046) interface IUnknown HRESULT QueryInterface( in REFIID riid, out,iid_is(riid) void *ppObj); ULONG AddRef(); ULONG Release(); ; uuid(b3c11b80-9e7e-11d1-b6a
21、5-006097b010e3) interface IStream : IUnknown HRESULT Seek( in LONG nPos); HRESULT Read( out,size_is(cb) BYTE *pb, in LONG cb); HRESULT Write( in,size_is(cb) BYTE *pb, in LONG cb); ; Figure 1. MIDL for Two Interfaces.The MIDL definition of an interface describes its memberfunctions and their paramete
22、rs in sufficient detail to supportlocation-transparent invocation.IUnknownThe IUnknown interface, listed in Figure 1, is spe-cial. All COM objects must support IUnknown. EachCOM interface must include the three member func-tions from IUnknown, namely: QueryInterface,AddRef, and Release. AddRef and R
23、elease arereference-counting functions for lifetime management.When an objects reference count goes to zero, the ob-ject is responsible for freeing itself from memory.COM objects can support multiple interfaces. Cli-ents dynamically bind to a new interface by callingQueryInterface. QueryInterface ta
24、kes asinput the GUID of the interface to which the clientwould like to bind and returns a pointer to the new in-terface. Through run-time invocation of Query-Interface, clients can determine the exact function-ality supported by any object.2.2. Common Language MappingsThe MIDL compiler maps interfac
25、e definitions intoformats usable by common programming languages.Figure 2 contains the C+ abstract classes generated bythe MIDL compiler, for the interfaces in Figure 1.MIDL has straightforward mappings into other com-piled languages such as C and Java. In addition, theMIDL compiler can store metada
26、ta in binary files calledtype libraries. Many development tools can importtype libraries. Type libraries are well suited for script-ing languages such as the Visual Basic Scripting Edi-tion in Internet Explorer 11.class IUnknown public: virtual HRESULT QueryInterface( REFIID riid, void *ppObj) = 0;
27、virtual ULONG AddRef() = 0; virtual ULONG Release() = 0; ; class IStream : IUnknown public: virtual HRESULT Seek( LONG nPos) = 0; virtual HRESULT Read( BYTE *pb, LONG cb) = 0; virtual HRESULT Write( BYTE *pb, LONG cb) = 0; ; Figure 2. C+ Language Mapping.The MIDL compiler maps a COM interface into a
28、n abstractC+ class.2.3. Binary CompatibilityIn addition to language mappings, COM specifies aplatform-standard binary mapping for interfaces. Thebinary format for a COM interface is similar to thecommon format of a C+ virtual function table (VTBL,pronounced “V-Table”). All references to interfacesar
29、e stored as interface pointers (an indirect pointer to avirtual function table). Figure 3 shows the binary map-ping of the IStream interface.Each object is responsible for allocating and releas-ing the memory occupied by its interfaces. Quite often,objects place per-instance interface data immediate
30、lyfollowing the interface virtual-function-table pointer.With the exception of the virtual function table and thepointer to the virtual function table, the object memoryarea is opaque to the client.The standardized binary mapping enforces COMslanguage neutrality. Any language that can call a func-ti
31、on through a pointer can use COM objects. Any lan-guage that can export a function pointer can createCOM objects.COM components are distributed either in applica-tion executables (.EXE files) or in dynamic link librar-ies (DLLs).pfWrite Client IStream * Instance Data pVtbl pfQueryInterface pfAddRef
32、pfRelease pfSeek pfRead Virtual Function Table Code Write QueryInterface AddRef Release Seek Read Component Interfaces Figure 3. Binary Interface Mapping.COM defines a standard binary mapping for interfaces. Theformat is similar to the common representation of a C+ pureabstract virtual function tabl
33、e.2.4. Location TransparencyBinary compatibility is important because it facili-tates true location transparency. A client can commu-nicate with a COM object in the same process (in-process), in a different process (cross-process), or on anentirely different machine (cross-machine). The loca-tion of
34、 the COM object is completely transparent toboth client and component because in each case invo-cation takes place through an interfaces virtual func-tion table.Interface Proxies and StubsLocation transparency is achieved through proxiesand stubs generated by the MIDL compiler. Proxiesmarshal functi
35、on arguments into a single message thatcan be transported between address spaces or betweenmachines. Stubs unmarshal messages into functioncalls. Interface proxies and stubs copy data structureswith deep-copy semantics. In theory, proxies and stubscome in pairsthe first for marshaling and the second
36、for unmarshaling. In practice, COM generally com-bines code for the proxy and stub for a specific inter-face into a single reusable binary. COM proxies andstubs are similar in purpose to CORBA 19, 23 stubsand skeletons. However, their implementations varybecause COM proxies and stubs are only used w
37、heninter-object communication crosses process boundaries.In-Process CommunicationFor best performance, components reside in the cli-ents address space. An application invokes an in-process object directly through the interface virtualfunction table. In-process communication has the samecost as a C+
38、virtual function call because it uses nei-ther interface proxies nor stubs. The primary drawbackof in-process objects is that they share the same protec-tion domain as the application. The application cannotprotect itself from erroneous or malicious resource ac-cess by the object.Cross-Process Commu
39、nicationTo provide the application with security, objects canbe located in another operating-system process. Theapplication communicates with cross-process objectsthrough interface proxies and stubs. The applicationinvokes the object through an indirect call on an inter-face virtual function table.
40、In this case, however, thevirtual function table belongs to the interface proxy.The proxy marshals function arguments into a bufferand transfers execution to the objects address spacewhere the interface stub unmarshals the arguments andcalls the object through the interface virtual functiontable in
41、the target address space. Marshaling and un-marshaling are completely transparent to both applica-tion and component.Cross-Machine CommunicationInvocation of distributed objects is very similar toinvocation of cross-process objects. Cross-machinecommunication uses the same interface proxies andstubs
42、 as cross-process communication. The primarydifference is that once the function arguments havebeen marshaled, COM sends the serialized message tothe destination machine using the DCOM protocol 3,a superset of the Open Groups Distributed ComputingEnvironment Remote Procedure Call (DCE RPC) pro-tocol
43、 4.3. Interception of Object InstantiationsCOM objects are dynamic objects. Instantiatedduring an applications execution, objects communicatewith the application and each other through dynami-cally bound interfaces. An object frees itself frommemory after all references to it have been released byth
44、e application and other objects.Applications instantiate COM objects by calling APIfunctions exported from a user-mode COM DLL. Ap-plications bind to the COM DLL either statically ordynamically.Static binding to a DLL is very similar to the use ofshared libraries in most UNIX systems. Static binding
45、is performed in two stages. At link time, the linker em-beds in the application binary the name of the DLL, alist of all imported functions, and an indirect jump tablewith one entry per imported function. At load time, theloader maps all imported DLLs into the applicationsaddress space and patches t
46、he indirect jump table en-tries to point to the correct entry points in the DLL im-age.Dynamic binding occurs entirely at run time. ADLL is loaded into the applications address space bycalling the LoadLibrary Win32 function. Afterloading, the application looks for procedures within theDLL using the
47、GetProcAddress function. In con-trast to static binding, in which all calls use an indirectjump table, GetProcAddress returns a direct pointerto the entry point of the named function.BindMonikerCoCreateInstanceCoCreateInstanceExCoGetClassObjectCoGetInstanceFromFileCoRegisterClassObjectCreateAntiMoni
48、kerCreateBindCtxCreateClassMonikerCreateDataAdviseHolderCreateFileMonikerCreateGenericCompositeCreateItemMonikerCreateOleAdviseHolderCreatePointerMonikerGetRunningObjectTableMkParseDisplayNameMonikerCommonPrefixWithMonikerRelativePathToOleCreateOleCreateDefaultHandlerOleCreateExOleCreateFontIndirect
49、OleCreateFromData*OleCreateFromFile*OleCreateLink*OleCreateStaticFromDataOleGetClipboardOleLoadOleLoadFromStreamOleLoadPictureOleLoadPictureFileOleRegEnumFormatEtcOleRegEnumVerbsStgCreateDocfileStgCreateDocfileOn*StgGetIFillLockBytesOn*StgOpenAsyncDocfileOn*StgOpenStorageStgOpenStorageOn*Figure 4. Object Instantiation Functions.COM supports approximately 50 functions capable of creat-ing instantiation a new object. However, most instantiationsrequest use either CoCreateInstance or CoCr