When an application is started by a Setup process (Wise or MS Install), for
example to set registry entries, it can crash (or show other behavior it
does not show when run "manually").
When does it happen (here): If GetUserName() or other APIs that use
SECUR32.DLL are called while PROCESS_ATTACH of DllMain().
Why does it happen? This API call appears BEFORE the PROCESS_ATTACH of
SECUR32.DLL! Thus the following happens:
- all DLLs are loaded (debugger shows the "module load"s)
- the own DLL gets called with PROCESS_ATTACH and calls the API that
(indirectly) calls an SECUR32 API
Secur32!InitState+0x5e
Secur32!IsOkayToExec+0x89
Secur32!SecpGetUserName+0x15
Secur32!GetUserNameExW+0x29
Secur32!GetUserNameExA+0x58
ADVAPI32!GetUserNameA+0x15
...
- the SECUR32 call seems to succeed (at least it does not crash - I did not
check whether the returned value, in this case the user's name, is correct)
- then SECUR32 is called with PROCESS_ATTACH
Secur32!ProcAttach+0x16
Secur32!_DllMain+0x36
ntdll!LdrpCallInitRoutine+0x14
ntdll!LdrpRunInitializeRoutines+0x36d
ntdll!LdrpInitializeProcess+0x10df
ntdll!_LdrpInitialize+0xf5
ntdll!LdrInitializeThunk+0x10
and clears its internal SecDllClient pointer:
Secur32!ProcAttach:
757d1402 mov edi,edi
757d1404 push ebp
757d1405 mov ebp,esp
757d1407 or dword ptr [Secur32!DllState (757e1060)],80000000h
757d1411 and dword ptr [Secur32!SecDllClient (757e105c)],0
...
- Afterwards, calls that use the SECUR32.DLL do crash (due to the resuling
NULL pointer).
I do write here just to publicize this, as this is a bug very hard to find
and even harder to understand (the loader does initialize the DLLs
differently in SETUP). Hopefully it does help others - it would have saved
us hours.
The problem is known
(http://msdn2.microsoft.com/en-us/library/ms682583.aspx), but the fact that
the call/initialization order changes when spawned by a SETUP process is a
new one.
Suggested workaround so far: see the MSDN docs above. Don't do anything
"complex" (whatever that is) in DllMain().
Christian