Coinitialize Analysis 1

Source: Internet
Author: User

Everyone knows that to use COM components in a program, you must first call coinitialize. This function is mainly used to initialize the com runtime environment. But does the function scope take the thread as the unit or the process as the unit? Maybe you have figured out the answer through the test program. That's right, it's a thread. Today, we will go into a bit more detail and confirm our ideas by analyzing the specific implementation of coinitialize.

Let's take a look at coinitialize compilation.

769b2a24 mov EDI, EDI

769b2a26 push EBP

769b2a27 mov EBP, ESP

769b2a29 push 2; dwcoinit

769b2a2b push [EBP + 8]; pvreserved

769b2a2e call _ coinitializeex @ 8; coinitializeex (x, x)

769b2a33 pop EBP

769b2a34 retn 4

We can see that the implementation is still relatively simple. It just calls coinitializeex and sets the second parameter to 2, that is, coinit_apartmentthreaded. Let's take a look at the implementation of coinitializeex.

769aef5b mov EDI, EDI

769aef5d push EBP

769aef5e mov EBP, ESP

769aef60 push ECx

769aef61 push EBX

769aef62 mov EBX, [EBP + 0C]

769aef65 mov eax, EBX

769aef67 and eax, 0eh; check whether the parameter is correct. Currently, the second parameter only uses one byte.

769aef6a CMP eax, EBX

769aef6c jnz loc_76a0b8c7

769aef72 push EDI

769aef73 xor edi, EDI

769aef75 CMP [EBP + 8], EDI; Determine whether the first parameter is null

769aef78 jnz loc_76a0b8d1

769aef7e

769aef7eloc_769aef7e:

769aef7e call? Isrunninginrpcss @ yghxz; isrunninginrpcss (void)

769aef83 test eax, eax; judge whether the current process is RPCSS

769aef85 jnz loc_76a0b8ed; If yes (that is, non-0 is returned), a "catastrophic fault" error is returned.

769aef8b mov eax, large FS: 18 h

769aef91 mov eax, [eax + 0f80h]

769aef97 CMP eax, EDI

769aef99 mov [EBP + 8], eax

769aef9c JZ loc_769adf26; determines whether the struct tagsoletlsdata struct in the current thread is allocated. If not, allocate the struct.

769aefa2

769aefa2loc_769aefa2:

769aefa2 push ESI

769aefa3 push EDI; _ int32

769aefa4 push EBX; unsigned _ int32

769aefa5 xor esi, ESI

769aefa7 Inc ESI

769aefa8 push ESI; int

769aefa9 push ESI; int

769 aefaa call? Notifyinitializespies @ ygjhhkj @ Z; notifyinitializespies (INT, Int, ulong, long)

769 aefaf call? Isthreadinnta @ yghxz; isthreadinnta (void)

769aefb4 test eax, eax

769aefb6 jnz loc_769dafad; If yes, "cannot be changed after thread mode is set" is returned ." Error

769 aefbc mov eax, [EBP + 8]

769 aefbf mov ECx, [eax + 0ch]

769aefc2 test CH, 10 h; Determine whether to set the 4th bits (starting from 0th bits)

769aefc5 jnz loc_769d9d20; server exceptions.

769 aefcb mov edX, EBX

769 aefcd and EDX, 2

769aefd0 mov [ebp-4], EDX

769aefd3 JZ short loc_769aefde; non-coinit_apartmentthreaded Mode

769aefd5 test CH, 1; identify whether 0th bits are set

769aefd8 jnz loc_769dafad; "cannot be changed after thread mode is set" is returned ." Error

769 aefde

769aefdeloc_769aefde:

769 aefde CMP edX, EDI

769aefe0 JZ loc_769dafa5; non-coinit_apartmentthreaded Mode

769aefe6

769aefe6loc_769aefe6:

769aefe6 test BL, 8

769aefe9 jnz loc_76a0b901; in the second parameter, the coinit_speed_over_memory identifier is set, that is, the single-thread kit.

769 aefef

769aefefloc_769aefef:

769 aefef add eax, 18 h

769aeff2 Inc dword ptr [eax]; tagsoletlsdata. dwreserved1 [0] ++;

769aeff4 CMP [eax], ESI

769aeff6 jnz loc_769adbf9; Judge tagsoletlsdata. dwreserved1 [0] = 1?

769 aeffc test edX, EDX

769 aeffe mov EBX, offset? Gmtainitlock @ 3vcolestaticmutexsem @ A; colestaticmutexsem gmtainitlock

769af003 JZ loc_769daff2; the second parameter is not set with the coinit_apartmentthreaded identifier, that is, the multi-thread suite

769af009

769af009loc_769af009:

769af009 mov ESI, offset? G_mxssinglethreadole @ 3vcolestaticmutexsem @ A; colestaticmutexsemg_mxssinglethreadole

769af00e mov ECx, ESI

769af010 call? Request @ colestaticmutexsem @ qaexxz; colestaticmutexsem: Request (void)

769af015 push [EBP + 0C]

769af018 Lea eax, [EBP + 8]

769af01b push eax

769af01c call? Wcoinitializeex @ ygjaavcoletls @ k @ Z; wcoinitializeex (coletls &, ulong) calls wcoinitializeex

769af021 mov ECx, ESI

769af023 mov EDI, eax

769af025 call? Release @ colestaticmutexsem @ qaexxz; colestaticmutexsem: release (void)

769af02a test EDI, EDI

769af02c JL loc_76a0b90c

769af032

769af032loc_769af032:

769af032 CMP [ebp-4], 0

769af036 JZ loc_769db004; the second parameter is not set with the coinit_apartmentthreaded identifier, that is, the multi-thread suite

769af03c

769af03c loc_769af03c:; Code xref: coinitializeex (x, x) + 2c0b4.7

769af03c xor esi, ESI

769af03e Inc ESI

769af03f

769af03f loc_769af03f:

769af03f push EDI; _ int32

769af040 push [EBP + 0C]; unsigned _ int32

769af043 push 0; int

769af045 push ESI; int

769af046 call? Notifyinitializespies @ ygjhhkj @ Z; notifyinitializespies (INT, Int, ulong, long)

769af04b pop ESI

769af04c

769af04c loc_769af04c:

769af04c pop EDI

769af04d

769af04dloc_769af04d:

769af04d pop EBX

769af04e leave

769af04f retn 8

Note the following points:

1. When the first parameter is not blank, the function determines whether the current process is Excel;

2. This function will also determine whether the current process is RPCSS. For details about the purpose of this process, refer to the following methods to check whether the process is RPCSS: first, determine whether the current process has been loaded into the Windows directory \ system32 \ RPCSS. DLL. If it is not loaded, the current process is not RPCSS. If it is loaded, obtain the export function named whichservice In the DLL. If the function is not found, the current process is considered as RPCSS; if it is found, and the return value of this function is greater than or equal to 0, and the pointer to this function parameter points to 2, the current process is not RPCSS; otherwise, the current process is RPCSS.

3. The Teb structure of each thread is offset to 0x0f80 to store the pointer of struct tagsoletlsdata. The declaration of this structure is as follows:

Typedef structtagsoletlsdata

{

Void * pvreserved0 [2];

DWORD dwreserved0 [3];

Void * pvreserved1 [1];

DWORD dwreserved1 [3];

Void * pvreserved2 [4];

DWORD dwreserved2 [1];

Void * pcurrentctx;

} Soletlsdata;

This structure stores information about the com environment of the current thread. The definition of each domain in this struct does not seem to be made public by Microsoft. After the thread starts, the pointer is blank before the thread calls coinitialize or coinitializeex. After the above function is called for the first time, allocate the memory of the structure to the thread from the heap and save the pointer to Teb + 0x0f80.

4. We noticed that all modifications to the struct tagsoletlsdata content are not mutually exclusive, because all modifications to this structure are performed within the current thread, therefore, multi-thread synchronization does not occur. Modifications to some global information are protected.

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.