1 : // Copyright 2013 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/instrument/instrumenters/asan_instrumenter.h"
16 :
17 : #include "base/file_util.h"
18 : #include "base/logging.h"
19 : #include "syzygy/common/application.h"
20 :
21 : namespace instrument {
22 : namespace instrumenters {
23 :
24 : const char AsanInstrumenter::kAgentDllAsan[] = "syzyasan_rtl.dll";
25 :
26 : AsanInstrumenter::AsanInstrumenter()
27 : : use_interceptors_(true),
28 : remove_redundant_checks_(true),
29 E : use_liveness_analysis_(true) {
30 E : agent_dll_ = kAgentDllAsan;
31 E : }
32 :
33 : bool AsanInstrumenter::ImageFormatIsSupported(
34 E : pe::ImageFormat image_format) {
35 E : if (image_format == pe::PE_IMAGE || image_format == pe::COFF_IMAGE)
36 E : return true;
37 i : return false;
38 E : }
39 :
40 E : bool AsanInstrumenter::InstrumentImpl() {
41 : // Parse the filter if one was provided.
42 E : scoped_ptr<pe::ImageFilter> filter;
43 E : if (!filter_path_.empty()) {
44 E : filter.reset(new pe::ImageFilter());
45 E : if (!filter->LoadFromJSON(filter_path_)) {
46 i : LOG(ERROR) << "Failed to parse filter file: " << filter_path_.value();
47 i : return false;
48 : }
49 :
50 : // Ensure it is for the input module.
51 E : if (!filter->IsForModule(input_image_path_)) {
52 E : LOG(ERROR) << "Filter does not match the input module.";
53 E : return false;
54 : }
55 : }
56 :
57 E : asan_transform_.reset(new instrument::transforms::AsanTransform());
58 E : asan_transform_->set_instrument_dll_name(agent_dll_);
59 E : asan_transform_->set_use_interceptors(use_interceptors_);
60 E : asan_transform_->set_use_liveness_analysis(use_liveness_analysis_);
61 E : asan_transform_->set_remove_redundant_checks(remove_redundant_checks_);
62 :
63 : // Set up the filter if one was provided.
64 E : if (filter.get()) {
65 E : filter_.reset(filter.release());
66 E : asan_transform_->set_filter(&filter_->filter);
67 : }
68 :
69 : // Set overwrite source range flag in the ASAN transform. The ASAN
70 : // transformation will overwrite the source range of created instructions to
71 : // the source range of corresponding instrumented instructions.
72 E : asan_transform_->set_debug_friendly(debug_friendly_);
73 :
74 E : if (!relinker_->AppendTransform(asan_transform_.get()))
75 i : return false;
76 :
77 E : return true;
78 E : }
79 :
80 : bool AsanInstrumenter::ParseAdditionalCommandLineArguments(
81 E : const CommandLine* command_line) {
82 : // Parse the additional command line arguments.
83 E : filter_path_ = command_line->GetSwitchValuePath("filter");
84 E : use_liveness_analysis_ = !command_line->HasSwitch("no-liveness-analysis");
85 E : remove_redundant_checks_ = !command_line->HasSwitch("no-redundancy-analysis");
86 E : use_interceptors_ = !command_line->HasSwitch("no-interceptors");
87 :
88 E : return true;
89 E : }
90 :
91 : } // namespace instrumenters
92 : } // namespace instrument
|