aboutsummaryrefslogtreecommitdiff
path: root/src/burn/stub/stub.cpp
blob: d8cee9f12b3b67bdbdfdc70e39969d8ef9962753 (plain)
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);
}