1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
|
// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
#include "precomp.h"
static const HRESULT E_SUSPECTED_TAMPERING = MAKE_HRESULT(SEVERITY_ERROR, 500/*FACILITY_WIX*/, 2001);
static void AvoidLocalDllRedirection(LPCWSTR wzPath);
int WINAPI wWinMain(
__in HINSTANCE hInstance,
__in_opt HINSTANCE /* hPrevInstance */,
__in_z_opt LPWSTR lpCmdLine,
__in int nCmdShow
)
{
HRESULT hr = S_OK;
DWORD dwExitCode = 0;
LPWSTR sczPath = NULL;
HANDLE hEngineFile = INVALID_HANDLE_VALUE;
LPCWSTR rgsczSafelyLoadSystemDlls[] =
{
L"cabinet.dll", // required by Burn.
L"msi.dll", // required by Burn.
L"version.dll", // required by Burn.
L"wininet.dll", // required by Burn.
L"comres.dll", // required by CLSIDFromProgID() when loading clbcatq.dll.
L"clbcatq.dll", // required by CLSIDFromProgID() when loading msxml?.dll.
L"msasn1.dll", // required by DecryptFile() when loading crypt32.dll.
L"crypt32.dll", // required by DecryptFile() when loading feclient.dll.
L"feclient.dll", // unsafely loaded by DecryptFile().
};
// Best effort attempt to get our file handle as soon as possible.
hr = PathForCurrentProcess(&sczPath, NULL);
if (SUCCEEDED(hr))
{
hEngineFile = ::CreateFileW(sczPath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
}
AppInitialize(rgsczSafelyLoadSystemDlls, countof(rgsczSafelyLoadSystemDlls));
AvoidLocalDllRedirection(sczPath);
// call run
hr = EngineRun(hInstance, hEngineFile, lpCmdLine, nCmdShow, &dwExitCode);
ExitOnFailure(hr, "Failed to run application.");
LExit:
ReleaseFileHandle(hEngineFile);
ReleaseStr(sczPath);
return FAILED(hr) ? (int)hr : (int)dwExitCode;
}
static void AvoidLocalDllRedirection(LPCWSTR wzPath)
{
LPWSTR sczLocalPath = NULL;
HMODULE hmodComCtl = NULL;
// Bail if there's a <bundle>.exe.local directory, as it's a feature of
// DLL redirection that has no real use for a bundle and is a hole for
// DLL hijacking attacks.
if (FAILED(StrAllocFormatted(&sczLocalPath, L"%ls.local", wzPath))
|| DirExists(sczLocalPath, NULL)
|| FileExistsEx(sczLocalPath, NULL)
|| FAILED(LoadSystemLibrary(L"Comctl32.dll", &hmodComCtl)))
{
::ExitProcess((UINT)E_SUSPECTED_TAMPERING);
}
ReleaseStr(sczLocalPath);
}
|