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 <hash_map>
21 : #include <string>
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 :
88 m : private:
89 : // Reads from a memory range using the actual modules as backing memory.
90 : // First determines how many bytes are available from the head of a range,
91 : // then optionally retrieves them.
92 : // @pre @p range must be a valid range.
93 : // @param range the requested range.
94 : // @param data_cnt on success, contains the number of bytes returned from the
95 : // head of @p range.
96 : // @param data_ptr a buffer of size at least that of @p range or nullptr. On
97 : // success, a valid buffer contains the returned data.
98 : // @returns true iff some data is available from the head of @p range.
99 : // TODO(manzagop): actually implement. Current implementation successfully
100 : // reads 0 bytes if the address range falls within a module.
101 m : bool ReadFromModule(const AddressRange& range,
102 m : size_t* bytes_read,
103 m : void* buffer);
104 :
105 : // Backing memory for registers.
106 m : base::hash_map<CV_HREG_e, ULONGLONG> registers_;
107 :
108 m : scoped_refptr<DiaSymbolProvider> symbol_provider_;
109 m : ProcessState* process_state_; // Not owned.
110 m : };
111 :
112 m : } // namespace refinery
113 :
114 : #endif // SYZYGY_REFINERY_ANALYZERS_STACK_ANALYZER_IMPL_H_
|