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 : // Defines the PEHackerApp class, which implements the command-line
16 : // "pehacker" tool.
17 :
18 : #ifndef SYZYGY_PEHACKER_PEHACKER_APP_H_
19 : #define SYZYGY_PEHACKER_PEHACKER_APP_H_
20 :
21 : #include "base/command_line.h"
22 : #include "base/values.h"
23 : #include "base/files/file_path.h"
24 : #include "base/memory/scoped_vector.h"
25 : #include "base/strings/string_piece.h"
26 : #include "base/time/time.h"
27 : #include "syzygy/application/application.h"
28 : #include "syzygy/block_graph/block_graph.h"
29 : #include "syzygy/pe/image_source_map.h"
30 : #include "syzygy/pe/pe_file.h"
31 : #include "syzygy/pe/pe_transform_policy.h"
32 :
33 : namespace pehacker {
34 :
35 : // Implements the "pehacker" command-line application.
36 : //
37 : // Refer to kUsageFormatStr (referenced from PEHackerApp::Usage()) for
38 : // usage information.
39 : class PEHackerApp : public application::AppImplBase {
40 : public:
41 E : PEHackerApp()
42 : : application::AppImplBase("PEHacker"), overwrite_(false) {
43 E : }
44 :
45 : // @name Implementation of the AppImplBase interface.
46 : // @{
47 : bool ParseCommandLine(const base::CommandLine* command_line);
48 : int Run();
49 : // @}
50 :
51 : protected:
52 : typedef block_graph::BlockGraph BlockGraph;
53 :
54 : // Modules being maintained by the pipeline are uniquely identified by
55 : // their input and output names. This allows the same module to be processed
56 : // multiple times by the pipeline, being written to different destinations.
57 : struct ImageId {
58 : base::FilePath input_module;
59 : base::FilePath output_module;
60 : bool operator<(const ImageId& rhs) const;
61 : };
62 :
63 : // This maintains information about a module that is being processed by
64 : // the pipeline.
65 : struct ImageInfo {
66 E : ImageInfo() : header_block(NULL) { }
67 : base::FilePath input_module;
68 : base::FilePath output_module;
69 : base::FilePath input_pdb;
70 : base::FilePath output_pdb;
71 : pe::PEFile pe_file;
72 : BlockGraph block_graph;
73 : BlockGraph::Block* header_block;
74 : pe::RelativeAddressRange input_omap_range;
75 : };
76 :
77 : typedef std::map<ImageId, ImageInfo*> ImageInfoMap;
78 :
79 : // @name Utility members.
80 : // @{
81 : bool Usage(const base::CommandLine* command_line,
82 : const base::StringPiece& message) const;
83 : // @}
84 :
85 : // Sets built-in variables. This is run by ParseCommandLine, prior to parsing
86 : // variables passed on the command-line.
87 : // @returns true on success, false otherwise.
88 : bool SetBuiltInVariables();
89 :
90 : // Loads, parses and validates the configuration file. This is called as
91 : // part of Run(), but is exposed for unittesting.
92 : bool LoadAndValidateConfigurationFile();
93 :
94 : // Parses the configuration file, populating config_. This is called from
95 : // LoadAndValidateConfiguration.
96 : // @returns true on success, false otherwise.
97 : bool ParseConfigFile();
98 :
99 : // Updates the variables dictionary with values parsed from the configuration
100 : // file. This is called from LoadAndValidateConfiguration.
101 : // @returns true on success, false otherwise.
102 : bool UpdateVariablesFromConfig();
103 :
104 : // @name For processing the configuration file.
105 : // @{
106 : // @param dry_run If this is true then no actual work is done, but the
107 : // configuration file is validated.
108 : // @param targets A list of targets to process.
109 : // @param target A target to process.
110 : // @param operations A list of operations to process.
111 : // @param operation An operation to process.
112 : // @param image_info Information about the image being transformed.
113 : // @returns true on success, false otherwise.
114 : bool ProcessConfigurationFile(bool dry_run);
115 : bool ProcessTargets(bool dry_run, base::ListValue* targets);
116 : bool ProcessTarget(bool dry_run, base::DictionaryValue* target);
117 : bool ProcessOperations(bool dry_run,
118 : base::ListValue* operations,
119 : ImageInfo* image_info);
120 : bool ProcessOperation(bool dry_run,
121 : base::DictionaryValue* operation,
122 : ImageInfo* image_info);
123 : // @}
124 :
125 : // Looks up the already decomposed image, or loads and decomposes it for the
126 : // first time.
127 : // @param input_module The path to the input module.
128 : // @param output_module The path to the output module.
129 : // @param input_pdb The path to the input PDB.
130 : // @param output_pdb The path to the output PDB.
131 : // @returns a pointer to the ImageInfo for the requested image. Returns NULL
132 : // on failure.
133 : ImageInfo* GetImageInfo(const base::FilePath& input_module,
134 : const base::FilePath& output_module,
135 : const base::FilePath& input_pdb,
136 : const base::FilePath& output_pdb);
137 :
138 : // Writes any transformed images back to disk.
139 : // @returns true on success, false otherwise.
140 : bool WriteImages();
141 :
142 : // @name Command-line parameters.
143 : base::FilePath config_file_;
144 : bool overwrite_;
145 : // @}
146 :
147 : // Dictionary of variables. We use a JSON dictionary so that it can easily
148 : // represent doubles, integers, strings, etc.
149 : base::DictionaryValue variables_;
150 :
151 : // The configuration file is parsed as a JSON file and stored here.
152 : scoped_ptr<base::DictionaryValue> config_;
153 :
154 : // These house the modules that are being transformed by the pipeline.
155 : ScopedVector<ImageInfo> image_infos_;
156 : ImageInfoMap image_info_map_;
157 :
158 : // The policy object used by the various transforms.
159 : pe::PETransformPolicy policy_;
160 : };
161 :
162 : } // namespace pehacker
163 :
164 : #endif // SYZYGY_PEHACKER_PEHACKER_APP_H_
|