1 : // Copyright 2015 Google Inc. All Rights Reserved.
2 : //
3 : // Licensed under the Apache License, Version 2.0 (the "License");
4 : // you may not use this file except in compliance with the License.
5 : // You may obtain a copy of the License at
6 : //
7 : // http://www.apache.org/licenses/LICENSE-2.0
8 : //
9 : // Unless required by applicable law or agreed to in writing, software
10 : // distributed under the License is distributed on an "AS IS" BASIS,
11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 : // See the License for the specific language governing permissions and
13 : // limitations under the License.
14 :
15 : #ifndef SYZYGY_REFINERY_ANALYZERS_STACK_ANALYZER_IMPL_H_
16 : #define SYZYGY_REFINERY_ANALYZERS_STACK_ANALYZER_IMPL_H_
17 :
18 : #include <dia2.h>
19 :
20 : #include <string>
21 : #include <unordered_map>
22 :
23 : #include "base/containers/hash_tables.h"
24 : #include "base/files/file_path.h"
25 : #include "base/memory/ref_counted.h"
26 : #include "base/win/iunknown_impl.h"
27 : #include "syzygy/pe/pe_file.h"
28 : #include "syzygy/refinery/process_state/process_state_util.h"
29 : #include "syzygy/refinery/symbols/dia_symbol_provider.h"
30 :
31 m : namespace refinery {
32 :
33 : // Fwd.
34 m : class ProcessState;
35 :
36 m : class StackWalkHelper : public IDiaStackWalkHelper,
37 m : public base::win::IUnknownImpl {
38 m : public:
39 m : explicit StackWalkHelper(scoped_refptr<DiaSymbolProvider> symbol_provider);
40 m : ~StackWalkHelper() override;
41 :
42 : // Sets up the stack walk helper's state.
43 : // @param stack_record the record of the stack to walk.
44 : // @param process_state the state of the process; must outlive this class.
45 m : void SetState(StackRecordPtr stack_record, ProcessState* process_state);
46 :
47 : // @name IUnknown implementation
48 : // @{
49 m : ULONG STDMETHODCALLTYPE AddRef() override;
50 m : ULONG STDMETHODCALLTYPE Release() override;
51 m : HRESULT STDMETHODCALLTYPE QueryInterface(REFIID, PVOID*) override;
52 : // @}
53 :
54 : // @name IDiaStackWalkHelper implementation
55 : // @{
56 : // TODO(manzagop): investigate for possible improvements in terms of
57 : // error codes returned by the current implementation.
58 m : STDMETHOD(get_registerValue)(DWORD index, ULONGLONG* pRetVal);
59 m : STDMETHOD(put_registerValue)(DWORD index, ULONGLONG NewVal);
60 m : STDMETHOD(readMemory)(MemoryTypeEnum type,
61 m : ULONGLONG va,
62 m : DWORD cbData,
63 m : DWORD* pcbData,
64 m : BYTE* pbData);
65 m : STDMETHOD(searchForReturnAddress)(IDiaFrameData* frame,
66 m : ULONGLONG* returnAddress);
67 :
68 m : STDMETHOD(searchForReturnAddressStart)(IDiaFrameData* frame,
69 m : ULONGLONG startAddress,
70 m : ULONGLONG* returnAddress);
71 :
72 m : STDMETHOD(frameForVA)(ULONGLONG va, IDiaFrameData** ppFrame);
73 :
74 m : STDMETHOD(symbolForVA)(ULONGLONG va, IDiaSymbol** ppSymbol);
75 :
76 m : STDMETHOD(pdataForVA)(ULONGLONG va,
77 m : DWORD cbData,
78 m : DWORD* pcbData,
79 m : BYTE* pbData);
80 :
81 m : STDMETHOD(imageForVA)(ULONGLONG vaContext, ULONGLONG* pvaImageStart);
82 :
83 m : STDMETHOD(addressForVA)(ULONGLONG va,
84 m : _Out_ DWORD* pISect,
85 m : _Out_ DWORD* pOffset);
86 :
87 m : STDMETHOD(numberOfFunctionFragmentsForVA)(ULONGLONG vaFunc,
88 m : DWORD cbFunc,
89 m : _Out_ DWORD* pNumFragments);
90 :
91 m : STDMETHOD(functionFragmentsForVA)(ULONGLONG vaFunc,
92 m : DWORD cbFunc,
93 m : DWORD cFragments,
94 m : _Out_ ULONGLONG* pVaFragment,
95 m : _Out_ DWORD* pLenFragment);
96 : // @}
97 :
98 m : private:
99 : // Reads from a memory range using the actual modules as backing memory.
100 : // First determines how many bytes are available from the head of a range,
101 : // then optionally retrieves them.
102 : // @pre @p range must be a valid range.
103 : // @param range the requested range.
104 : // @param data_cnt on success, contains the number of bytes returned from the
105 : // head of @p range.
106 : // @param data_ptr a buffer of size at least that of @p range or nullptr. On
107 : // success, a valid buffer contains the returned data.
108 : // @returns true iff some data is available from the head of @p range.
109 : // TODO(manzagop): actually implement. Current implementation successfully
110 : // reads 0 bytes if the address range falls within a module.
111 m : bool ReadFromModule(const AddressRange& range,
112 m : size_t* bytes_read,
113 m : void* buffer);
114 :
115 : // Backing memory for registers.
116 m : std::unordered_map<CV_HREG_e, ULONGLONG> registers_;
117 :
118 m : scoped_refptr<DiaSymbolProvider> symbol_provider_;
119 m : ProcessState* process_state_; // Not owned.
120 m : };
121 :
122 m : } // namespace refinery
123 :
124 : #endif // SYZYGY_REFINERY_ANALYZERS_STACK_ANALYZER_IMPL_H_
|