Dedicated to those who never stop asking why.
By TNTTOOLS, The ART of Reverse Engieering.
Figure I. Prototype for InitCommonControls
void InitCommonControls(VOID);
Figure II. Implementation for InitCommonControls
InitCommonControls proc near
mov eax, eax
retn
InitCommonControls endp
This function is simple, in fact, don't do anything. Why, This 'Placeholder' function is put in the IAT, Just telling the exe loader that comctl32.dll need to be loaded. Like God say let there be light, And there is. How about his brother InitCommonControlsEx(InitEx for abbreviation below.)
Figure 3. Prototype for InitCommonControlsEx
BOOL InitCommonControlsEx(
LPINITCOMMONCONTROLSEX lpInitCtrls );
In the first, InitEx executes the parameter check, and Do something with ActiveContext. Then All important job is done in a loop. below is the psedu code.
Figure 4.
------------------------------------------------------------------------
typedef struct _INITCOMCTRLEX
{
BOOL (*InitRoutine)();
LPWSTR ComCtrlName;
DWORD dwICC;
}INITCOMCTRLEX;
INITCOMCTRLEX Icc[20];
extern HANDLE g_hinst; // handle for CommCtl32.dll
BOOL WINAPI InitCommonControlsEx(
LPINITCOMMONCONTROLSEX lpInitCtrls)
{
PACTCTX pAC;
int tmp1;
BOOL retval = TRUE;
// Parameter Check
// 参数检查
if ( !lpInitCtrls || lpInitCtrls->dwSize != 8 )
return FALSE;
// a buuuug
if ( lpInitCtrls->dwICC & 0x7fffc000 )
return FALSE;
if ( !g_hinst ) // g_hinst: Handle of Comctl32.dll
g_hinst = GetModuleHandleW(NULL);
SHFusionInitializeFromModuleID(g_hinst,0x7C);
SHActivateContext(&pAC);
for(tmp1=0;tmp1<sizeof(Icc)/sizeof(INITCOMCTRLEX);tmp1++)
{
if ( lpInitCtrls->dwICC & Icc[tmp1].dwICC )
{if ( !(retval=Icc[tmp1].InitRoutine()) ) break;}
}
SHDeactivateContext(&pAC);
return retval;
}
------------------------------------------------------------------------
In the Loop, all InitRoutines are executed orderly. No big secret, A control class has a Init Routine that calls RegisterClassEx() to register the corrsponding class, like RebarWindow32, tooltips_class32, ...
Figure 5. The real Icc[] array
--------------------------------------------------------------------------
_icc dd offset _InitToolbarClass
dd offset aToolbarwindow3
dword_5D1E21E8 dd 4
dd offset unk_5D198963
dd offset aRebarwindow32 ; "ReBarWindow32"
dd 400h
dd offset sub_5D198CB3
dd offset aTooltips_class ; "tooltips_class32"
dd 0Eh
dd offset sub_5D195A51
dd offset aMsctls_statusb ; "msctls_statusbar32"
dd 4
dd offset sub_5D1D12CB
--------------------------------------------------------------------------
that's all the story. Enjoy it.