summaryrefslogtreecommitdiff
path: root/src/vm/pefingerprint.h
blob: 19de312ac00deb0ecdae09e7fcab00f544bcac22 (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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
// --------------------------------------------------------------------------------
// PEFingerprint.h
// 

// --------------------------------------------------------------------------------

#ifndef PEFINGERPRINT_H_
#define PEFINGERPRINT_H_


#ifdef FEATURE_FUSION

#include "corcompile.h"

class PEImage;

//==================================================================================
// This is the implementation of IILFingerprint object maintained by PEImage objects.
// IILFingerprint is described in detail in IILFingerprint.h
//==================================================================================
class PEFingerprint : public IILFingerprint
{
  public:
  //----------------------------------------------------------------
  // IILFingerprint methods
  //----------------------------------------------------------------
    STDMETHOD_(ULONG, AddRef)();
    STDMETHOD_(ULONG, Release)();
    STDMETHOD_(BOOL, CommitAndCompare)(ILFingerprintTag componentType, LPCVOID data);
    STDMETHOD_(BOOL, CommitAndCompareMulti)(UINT numComponents, const ILFingerprintComponent *pComponents);
    STDMETHOD_(void, LockAndLoadIL)();

  //----------------------------------------------------------------
  // Non-interface public methods.
  //----------------------------------------------------------------
  public:
    static PEFingerprint* PEFingerprint::CreatePEFingerprint(PEImage *owner);
    virtual ~PEFingerprint();

  private:
    PEFingerprint(PEImage *owner);

  //----------------------------------------------------------------
  // Private methods.
  //----------------------------------------------------------------
  private:

    BOOL IsComponentCommitted(ILFingerprintTag tag)
    {
        LIMITED_METHOD_CONTRACT;
        _ASSERTE(tag < ILFTagCount);
        return 0 != (m_commitMask & (1 << tag));
    }

    void SetComponentCommitted(ILFingerprintTag tag)
    {
        LIMITED_METHOD_CONTRACT;
        _ASSERTE(tag < ILFTagCount);
        m_commitMask |= (1 << tag);
    }

    LPVOID TagDataStart(ILFingerprintTag tag)
    {
        LIMITED_METHOD_CONTRACT;
        _ASSERTE(tag < ILFTagCount);
        return (LPVOID)(((LPBYTE)this) + s_offsets[tag]);
    }

    DWORD TagDataSize(ILFingerprintTag tag)
    {
        LIMITED_METHOD_CONTRACT;
        _ASSERTE(tag < ILFTagCount);
        return s_sizes[tag];
    }


  //----------------------------------------------------------------
  // Private instance data
  //----------------------------------------------------------------
  private:
    Crst                            *m_pcrst;                              // Synchronizes updates to fingerprint
    PEImage                         *m_peimage;                            // Backpointer to PEImage (for ref-counting purposes, the PEImage and PEFingerprint have the same identity)
    DWORD                            m_commitMask;                         // Bitmask to indicate which components have been committed ( fCommitted =  (m_commitMask & (1 << tag)) )
    FILETIME                         m_timeStamp;                          // Component: File system lastwrite Timestamp
    DWORD                            m_size;                               // Component: File size
    GUID                             m_mvid;                               // Component: Mvid

    BOOL                             m_alreadyLoaded;                      // Turns repeated attempts to LockAndLoadIL() into NOP's
    HRESULT                          m_priorLockAndLoadFailure;            // If LockAndLoadIL() failed the first time, return the same failure on subsequent attempts.

  //----------------------------------------------------------------
  // Private static data
  //----------------------------------------------------------------
  private:
    const static size_t              s_offsets[ILFTagCount];               // static: Maps tags to offsets within PEFingerprint
    const static DWORD               s_sizes[ILFTagCount];                 // static: Maps tag to expected data size
};

#endif // FEATURE_FUSION


//==================================================================================
// This holder must be wrapped around any code that opens an IL image.
// It will verify that the actual fingerprint doesn't conflict with the stored
// assumptions in the PEFingerprint. (If it does, the holder constructor throws
// a torn state exception.)
//
// It is a holder because it needs to keep a file handle open to prevent
// anyone from overwriting the IL after the check has been done. Once
// you've opened the "real" handle to the IL (i.e. LoadLibrary/CreateFile),
// you can safely destruct the holder.
//==================================================================================
class PEFingerprintVerificationHolder
{
  public:
    PEFingerprintVerificationHolder(PEImage *owner);

  private:
    FileHandleHolder m_fileHandle;
};


#endif //PEFINGERPRINT