Delay load Version.dll to avoid dll hijacking [bug #1125]

git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@6642 212acab6-be3b-0410-9dea-997c60f758d6
This commit is contained in:
anders_k 2015-11-25 13:13:42 +00:00
parent 0b5b7fad0e
commit 6be5d8d07d
5 changed files with 20 additions and 11 deletions

View file

@ -108,8 +108,9 @@ EXTERN_C void NSISWinMainNOCRT()
// Note: We also import directly from KERNEL32, ADVAPI32 and SHELL32 so they // Note: We also import directly from KERNEL32, ADVAPI32 and SHELL32 so they
// are exempt from this requirement and SHELL32 imports from SHLWAPI on // are exempt from this requirement and SHELL32 imports from SHLWAPI on
// WoW64 systems and it is also on the KnownDLLs list so // WoW64 systems and it is also on the KnownDLLs list so
// SHLWAPI also gets a pass and that just leaves SHFOLDER. // SHLWAPI also gets a pass and that just leaves
g_SHGetFolderPath = myGetProcAddress(MGA_SHGetFolderPath); myGetProcAddress(MGA_GetFileVersionInfo); // VERSION
g_SHGetFolderPath = myGetProcAddress(MGA_SHGetFolderPath); // and SHFOLDER
{ {
// workaround for bug #1008632 // workaround for bug #1008632

View file

@ -43,7 +43,6 @@ libs = Split("""
comdlg32 comdlg32
comctl32 comctl32
ole32 ole32
version
uuid uuid
""") """)

View file

@ -946,13 +946,11 @@ static int NSISCALL ExecuteEntry(entry *entry_)
#ifdef NSIS_SUPPORT_GETDLLVERSION #ifdef NSIS_SUPPORT_GETDLLVERSION
case EW_GETDLLVERSION: case EW_GETDLLVERSION:
{ {
TCHAR *highout=var0; TCHAR *highout=var0, *lowout=var1;
TCHAR *lowout=var1; DWORD s1, d;
DWORD s1;
VS_FIXEDFILEINFO *pvsf1; VS_FIXEDFILEINFO *pvsf1;
DWORD d;
TCHAR *buf1=GetStringFromParm(-0x12); TCHAR *buf1=GetStringFromParm(-0x12);
s1=GetFileVersionInfoSize(buf1,&d); s1=((DWORD(WINAPI*)(LPCTSTR,DWORD*))myGetProcAddress(MGA_GetFileVersionInfoSize))(buf1,&d);
*lowout=*highout=0; *lowout=*highout=0;
exec_error++; exec_error++;
if (s1) if (s1)
@ -961,8 +959,10 @@ static int NSISCALL ExecuteEntry(entry *entry_)
b1=GlobalAlloc(GPTR,s1); b1=GlobalAlloc(GPTR,s1);
if (b1) if (b1)
{ {
FARPROC gfvi = myGetProcAddress(MGA_GetFileVersionInfo), vqv = myGetProcAddress(MGA_VerQueryValue);
UINT uLen; UINT uLen;
if (GetFileVersionInfo(buf1,0,s1,b1) && VerQueryValue(b1,_T("\\"),(void*)&pvsf1,&uLen)) if ( ((BOOL(WINAPI*)(LPCTSTR,DWORD,DWORD,LPVOID))gfvi)(buf1,0,s1,b1)
&& ((BOOL(WINAPI*)(LPCVOID,LPCTSTR,LPVOID*,UINT*))vqv)(b1,_T("\\"),(void*)&pvsf1,&uLen) )
{ {
myitoa(highout,pvsf1->dwFileVersionMS); myitoa(highout,pvsf1->dwFileVersionMS);
myitoa(lowout,pvsf1->dwFileVersionLS); myitoa(lowout,pvsf1->dwFileVersionLS);

View file

@ -1070,7 +1070,10 @@ struct MGA_FUNC MGA_FUNCS[] = {
#endif #endif
{"ADVAPI32", "InitiateShutdownW"}, {"ADVAPI32", "InitiateShutdownW"},
{"SHLWAPI", "SHAutoComplete"}, {"SHLWAPI", "SHAutoComplete"},
{"SHFOLDER", "SHGetFolderPathW"} {"SHFOLDER", "SHGetFolderPathW"},
{"VERSION", "GetFileVersionInfoSizeW"},
{"VERSION", "GetFileVersionInfoW"},
{"VERSION", "VerQueryValueW"}
}; };
#else #else
{"KERNEL32", "GetDiskFreeSpaceExA"}, {"KERNEL32", "GetDiskFreeSpaceExA"},
@ -1078,7 +1081,10 @@ struct MGA_FUNC MGA_FUNCS[] = {
{"ADVAPI32", "RegDeleteKeyExA"}, {"ADVAPI32", "RegDeleteKeyExA"},
{"ADVAPI32", "InitiateShutdownA"}, {"ADVAPI32", "InitiateShutdownA"},
{"SHLWAPI", "SHAutoComplete"}, {"SHLWAPI", "SHAutoComplete"},
{"SHFOLDER", "SHGetFolderPathA"} {"SHFOLDER", "SHGetFolderPathA"},
{"VERSION", "GetFileVersionInfoSizeA"},
{"VERSION", "GetFileVersionInfoA"},
{"VERSION", "VerQueryValueA"}
}; };
#endif #endif

View file

@ -127,6 +127,9 @@ enum myGetProcAddressFunctions {
MGA_InitiateShutdown, MGA_InitiateShutdown,
MGA_SHAutoComplete, // x64 can link to shlwapi directly but as long as MGA_SHGetFolderPath is used we can stick with myGetProcAddress MGA_SHAutoComplete, // x64 can link to shlwapi directly but as long as MGA_SHGetFolderPath is used we can stick with myGetProcAddress
MGA_SHGetFolderPath, // TODO: This can probably call something else directly on x64 MGA_SHGetFolderPath, // TODO: This can probably call something else directly on x64
MGA_GetFileVersionInfoSize, // Version.dll exists in all Windows versions, it is delay loaded to avoid dll hijacking [bug #1125]
MGA_GetFileVersionInfo,
MGA_VerQueryValue
}; };
void * NSISCALL myGetProcAddress(const enum myGetProcAddressFunctions func); void * NSISCALL myGetProcAddress(const enum myGetProcAddressFunctions func);