App crashes when invoking hooked LodLibraryExW...
Posted: Wed Sep 07, 2016 6:05 pm
We have a COM Addin for 64-bit version of Outlook 2013.
In our plugin we hook the family of LoadLibraryX() functions from kernel32.dll
Our replacement functions examine any attempted dll loads to identify and prevent loading of specific dlls.
All of the above seems to work nomally until...
Outlook attempts to run spellcheck via msspell7.dll
In this dll it imports LoadLibraryExW() and attempts to invoke it.
The invoke attempt causes Outlook to crash.
MS debug of provided time-travel-trace data indicates that the function table slot where they expect LoadLibraryExW to be does not appear to represent executable code - hence the crash.
I have verified that if we disable our hooking of the family of LoadLibrary function, we no longer see the crash - so it would appear that establishing the hook does something such that the import and subsequent invoke attempt of the function via code in the spell check dll no longer works.
Some more detail (ASCD as mentioned below is a dll used by our plugin and this is where the hooking is implemented):
When MSSPELL7 loads, it imports (what it thinks is) the kernel32!LoadLibraryExW; ASCD intercepts this call and instead of providing a pointer to the location of kernel32!LoadLibraryExW, it provides the memory location of 0x00000001’71990000 which is supposed to be its implementation of that function (its replacement function). Unfortunately, it appears that ASCD is wrong about where its replacement function resides – because there’s NOTHING at that memory location:
Outllook is calling into a dynamic
> function table - basically msspell7.dll has imported kernel32.dll's
> LoadLibraryExW function. It does this as it needs to load a lexicon
> (.lex file) using LoadLibraryExW(). disassembly code as
> follows:
>
> ... call qword ptr [msspell7!_imp_LoadLibraryExW...
>
> On dumping the memory addresses representing the dynamic function
> table MS sees valid entries for other functions, including functions
> from kernel32.dll but the slot where MS expects to see LoadLibraryExW
> is empty.
Here’s the surrounding dynamic function table - the slot containing 00000001`71990000 is where LoadLibraryExW replacement is expected:
0:000> dps 000007fe`d313b288-0x10
000007fe`d313b278 00000000`777ec7f0 kernel32!EnumSystemLocalesAStub
000007fe`d313b280 00000000`777b8550 kernel32!IsValidLocaleStub
000007fe`d313b288 00000001`71990000
000007fe`d313b290 00000000`779e38f0 ntdll!RtlDeleteCriticalSection
000007fe`d313b298 00000000`777b6e40 kernel32!InitializeCriticalSectionExStub
In our plugin we hook the family of LoadLibraryX() functions from kernel32.dll
Our replacement functions examine any attempted dll loads to identify and prevent loading of specific dlls.
All of the above seems to work nomally until...
Outlook attempts to run spellcheck via msspell7.dll
In this dll it imports LoadLibraryExW() and attempts to invoke it.
The invoke attempt causes Outlook to crash.
MS debug of provided time-travel-trace data indicates that the function table slot where they expect LoadLibraryExW to be does not appear to represent executable code - hence the crash.
I have verified that if we disable our hooking of the family of LoadLibrary function, we no longer see the crash - so it would appear that establishing the hook does something such that the import and subsequent invoke attempt of the function via code in the spell check dll no longer works.
Some more detail (ASCD as mentioned below is a dll used by our plugin and this is where the hooking is implemented):
When MSSPELL7 loads, it imports (what it thinks is) the kernel32!LoadLibraryExW; ASCD intercepts this call and instead of providing a pointer to the location of kernel32!LoadLibraryExW, it provides the memory location of 0x00000001’71990000 which is supposed to be its implementation of that function (its replacement function). Unfortunately, it appears that ASCD is wrong about where its replacement function resides – because there’s NOTHING at that memory location:
Outllook is calling into a dynamic
> function table - basically msspell7.dll has imported kernel32.dll's
> LoadLibraryExW function. It does this as it needs to load a lexicon
> (.lex file) using LoadLibraryExW(). disassembly code as
> follows:
>
> ... call qword ptr [msspell7!_imp_LoadLibraryExW...
>
> On dumping the memory addresses representing the dynamic function
> table MS sees valid entries for other functions, including functions
> from kernel32.dll but the slot where MS expects to see LoadLibraryExW
> is empty.
Here’s the surrounding dynamic function table - the slot containing 00000001`71990000 is where LoadLibraryExW replacement is expected:
0:000> dps 000007fe`d313b288-0x10
000007fe`d313b278 00000000`777ec7f0 kernel32!EnumSystemLocalesAStub
000007fe`d313b280 00000000`777b8550 kernel32!IsValidLocaleStub
000007fe`d313b288 00000001`71990000
000007fe`d313b290 00000000`779e38f0 ntdll!RtlDeleteCriticalSection
000007fe`d313b298 00000000`777b6e40 kernel32!InitializeCriticalSectionExStub