Starting from Windows XP, TLS callback is not called with Reason == DLL_PROCESS_ATTACH for the executable that is staticaly linked only to ntdll.dll and / or kernel32.dll and / or kernelbase.dll. When LdrpRunInitializeRoutines is called from LdrpInitializeProcess (LdrDataTableEntry->Flags & LDRP_ENTRY_PROCESSED) != 0 for these DLLs (kernel32.dll and / or kernelbase.dll are already loaded with LdrpLoadDll by ntdll.dll itself), so LdrpCallTlsInitializers and LdrpCallInitRoutine are not called for these DLLs and LdrpCallTlsInitializers is not called for the main executable module.
Command lines used to pack executable for test:
upx.exe -q -o CConsoleTestAppStaticMSCRTMiniWithTLSDataAndCallback32Packed.exe --no-color --ultra-brute --keep-resource=MUI --overlay=strip --strip-relocs=0 CConsoleTestAppStaticMSCRTMiniWithTLSDataAndCallback32.exe
and
upx.exe -q -o CConsoleTestAppStaticMSCRTMiniWithTLSDataAndCallback64Packed.exe --no-color --ultra-brute --keep-resource=MUI --overlay=strip --strip-relocs=0 CConsoleTestAppStaticMSCRTMiniWithTLSDataAndCallback64.exe
Correction: kernel32.dll and / or kernelbase.dll are already loaded with LdrpLoadDll by ntdll.dll itself -> kernel32.dll and / or kernelbase.dll are already loaded with LdrpLoadDll by ntdll.dll before traversing imports of the main executable.
Unfortunately your file does not seems to work with wine+linux (that's the only environment I can do windows related testing). So, can you tell me, what should I exactly do to fix this?
Well, maybe just analyze executable for static imports and for executable that is statically linked only to ntdll.dll and / or kernel32.dll and / or kernelbase.dll (Vista or higher) do not call TLS callback with Reason == DLL_PROCESS_ATTACH (don't patch PETLSC2 handlers in i386-win32.pe.S and amd64-win64.pep.S to suppress wrong behavior of "other" loaders). Or and consult with Stefan Widmann.
And what about Windows related testing using Linux + VirtualBox (with Windows)?
Also You can lower priority and leave this bug opened forever (for informational purpose) because it is rare specific case.
Last edit: Mosc 2015-07-02
Thanks for the explanation, now I see what you're telling me. I think patching of the PETLSC2 handler is still needed - so that the tls callbacks would still work when Reason != DLL_PROCESS_ATTACH. But I can get rid of the Reason=DLL_PROCESS_ATTACH call, no problem.
I'll create a patch for this when Markus decides that we really want to release UPX 3.92.
Thanks for your report