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 : #include "syzygy/refinery/process_state/process_state_util.h"
16 :
17 : #include <vector>
18 :
19 : #include "base/strings/utf_string_conversions.h"
20 : #include "gtest/gtest.h"
21 : #include "syzygy/refinery/core/address.h"
22 : #include "syzygy/refinery/process_state/layer_data.h"
23 : #include "syzygy/refinery/process_state/process_state.h"
24 : #include "syzygy/refinery/process_state/refinery.pb.h"
25 : #include "syzygy/refinery/types/type.h"
26 :
27 : namespace refinery {
28 :
29 : namespace {
30 :
31 : const Address kAddress = 0x0000CAFE; // Fits 32-bit.
32 : const Size kSize = 42U;
33 : const uint32 kChecksum = 11U;
34 : const uint32 kTimestamp = 22U;
35 : const wchar_t kPath[] = L"c:\\path\\ModuleName";
36 : const char kDataName[] = "data_name";
37 : const ModuleId kModuleId = 100;
38 : const TypeId kTypeId = 42;
39 :
40 : } // namespace
41 :
42 E : TEST(ModuleLayerAccessorTest, AddModuleRecord) {
43 E : ProcessState state;
44 E : ModuleLayerAccessor accessor(&state);
45 : accessor.AddModuleRecord(AddressRange(kAddress, kSize), kChecksum, kTimestamp,
46 E : kPath);
47 :
48 : // Validate a record was added.
49 E : ModuleLayerPtr module_layer;
50 E : ASSERT_TRUE(state.FindLayer(&module_layer));
51 E : std::vector<ModuleRecordPtr> matching_records;
52 E : module_layer->GetRecordsAt(kAddress, &matching_records);
53 E : ASSERT_EQ(1, matching_records.size());
54 :
55 : // Validate the record.
56 E : ModuleRecordPtr record = matching_records[0];
57 E : ASSERT_EQ(AddressRange(kAddress, kSize), record->range());
58 E : const Module& module = matching_records[0]->data();
59 E : ASSERT_NE(kNoModuleId, module.module_id());
60 :
61 : // Validate the layer data contains the module information.
62 E : pe::PEFile::Signature signature;
63 E : ASSERT_TRUE(module_layer->data().Find(module.module_id(), &signature));
64 E : ASSERT_EQ(kPath, signature.path);
65 E : ASSERT_EQ(0U, signature.base_address.value());
66 E : ASSERT_EQ(kSize, signature.module_size);
67 E : ASSERT_EQ(kChecksum, signature.module_checksum);
68 E : ASSERT_EQ(kTimestamp, signature.module_time_date_stamp);
69 :
70 E : ASSERT_EQ(module.module_id(), module_layer->data().Find(signature));
71 E : }
72 :
73 E : TEST(ModuleLayerAccessorTest, GetModuleSignatureVATest) {
74 E : ProcessState state;
75 E : ModuleLayerAccessor accessor(&state);
76 E : pe::PEFile::Signature signature;
77 :
78 : // Fails when VA doesn't correspond to a module.
79 E : ASSERT_FALSE(accessor.GetModuleSignature(kAddress, &signature));
80 :
81 : // Add a module.
82 : accessor.AddModuleRecord(AddressRange(kAddress, kSize), kChecksum, kTimestamp,
83 E : kPath);
84 :
85 : // Fails outside the module's range.
86 E : ASSERT_FALSE(accessor.GetModuleSignature(kAddress - 1, &signature));
87 E : ASSERT_FALSE(accessor.GetModuleSignature(kAddress + kSize, &signature));
88 :
89 : // Succeeds within the module's range.
90 E : ASSERT_TRUE(accessor.GetModuleSignature(kAddress, &signature));
91 E : ASSERT_TRUE(accessor.GetModuleSignature(kAddress + kSize - 1, &signature));
92 :
93 : // Validate signature on the last hit.
94 E : ASSERT_EQ(kAddress, signature.base_address.value());
95 E : ASSERT_EQ(kSize, signature.module_size);
96 E : ASSERT_EQ(kChecksum, signature.module_checksum);
97 E : ASSERT_EQ(kTimestamp, signature.module_time_date_stamp);
98 E : ASSERT_EQ(kPath, signature.path);
99 E : }
100 :
101 E : TEST(ModuleLayerAccessorTest, GetModuleSignatureIdTest) {
102 E : ProcessState state;
103 E : ModuleLayerAccessor accessor(&state);
104 :
105 : // Add a module and get its id.
106 : accessor.AddModuleRecord(AddressRange(kAddress, kSize), kChecksum, kTimestamp,
107 E : kPath);
108 E : ModuleId module_id = accessor.GetModuleId(kAddress);
109 :
110 : // Validate.
111 E : pe::PEFile::Signature signature;
112 E : ASSERT_TRUE(accessor.GetModuleSignature(module_id, &signature));
113 :
114 E : ASSERT_EQ(0U, signature.base_address.value());
115 E : ASSERT_EQ(kSize, signature.module_size);
116 E : ASSERT_EQ(kChecksum, signature.module_checksum);
117 E : ASSERT_EQ(kTimestamp, signature.module_time_date_stamp);
118 E : ASSERT_EQ(kPath, signature.path);
119 E : }
120 :
121 E : TEST(ModuleLayerAccessorTest, GetModuleIdTest) {
122 E : ProcessState state;
123 E : ModuleLayerAccessor accessor(&state);
124 :
125 : // Not hitting a module case.
126 E : ASSERT_EQ(kNoModuleId, accessor.GetModuleId(kAddress));
127 :
128 : // Hitting a module case.
129 : accessor.AddModuleRecord(AddressRange(kAddress, kSize), kChecksum, kTimestamp,
130 E : kPath);
131 E : ModuleId module_id = accessor.GetModuleId(kAddress);
132 E : ASSERT_NE(kNoModuleId, module_id);
133 :
134 : // Consistency check: the signature associated to module_id must be equal to
135 : // that associated with va, up to the base address being 0.
136 E : pe::PEFile::Signature sig_from_va;
137 E : ASSERT_TRUE(accessor.GetModuleSignature(kAddress, &sig_from_va));
138 E : sig_from_va.base_address = core::AbsoluteAddress(0U);
139 :
140 E : pe::PEFile::Signature sig_from_id;
141 E : ModuleLayerPtr layer;
142 E : state.FindOrCreateLayer(&layer);
143 E : ASSERT_TRUE(layer->data().Find(module_id, &sig_from_id));
144 :
145 E : ASSERT_EQ(sig_from_va, sig_from_id);
146 E : }
147 :
148 E : TEST(AddTypedBlockRecord, BasicTest) {
149 E : ProcessState state;
150 : AddTypedBlockRecord(AddressRange(kAddress, kSize),
151 : base::ASCIIToUTF16(kDataName), kModuleId, kTypeId,
152 E : &state);
153 :
154 : // Validate a record was added.
155 E : TypedBlockLayerPtr layer;
156 E : ASSERT_TRUE(state.FindLayer(&layer));
157 E : std::vector<TypedBlockRecordPtr> matching_records;
158 E : layer->GetRecordsAt(kAddress, &matching_records);
159 E : ASSERT_EQ(1, matching_records.size());
160 :
161 : // Validate range.
162 E : TypedBlockRecordPtr record = matching_records[0];
163 E : ASSERT_EQ(AddressRange(kAddress, kSize), record->range());
164 :
165 : // Validate TypedBlock proto.
166 E : TypedBlock* proto = record->mutable_data();
167 E : ASSERT_EQ(kDataName, proto->data_name());
168 E : ASSERT_EQ(kTypeId, proto->type_id());
169 E : ASSERT_EQ(kModuleId, proto->module_id());
170 E : }
171 :
172 : } // namespace refinery
|