1 : // Copyright 2011 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/pe/metadata.h"
16 :
17 : #include "base/file_util.h"
18 : #include "base/json/json_reader.h"
19 : #include "gtest/gtest.h"
20 : #include "syzygy/core/json_file_writer.h"
21 : #include "syzygy/core/serialization.h"
22 : #include "syzygy/core/unittest_util.h"
23 :
24 : namespace pe {
25 :
26 : typedef PEFile::AbsoluteAddress AbsoluteAddress;
27 :
28 : namespace {
29 :
30 E : void InitMetadata(Metadata* metadata) {
31 E : std::string command_line = "foo.exe --bar --baz=blarg";
32 :
33 E : base::Time creation_time;
34 : EXPECT_TRUE(base::Time::FromString("Thu, 7 Jul 2011 13:45:00 GMT",
35 E : &creation_time));
36 :
37 E : SyzygyVersion toolchain_version(1, 2, 3, 4, "5");
38 :
39 E : PEFile::Signature module_signature;
40 E : module_signature.path = L"C:\\foo\\foo.dll";
41 E : module_signature.base_address = AbsoluteAddress(0x4001000);
42 E : module_signature.module_size = 2 * 1024 * 1024;
43 E : module_signature.module_time_date_stamp = 0xdeadbeefu;
44 E : module_signature.module_checksum = 0xbaadf00du;
45 :
46 E : metadata->set_command_line(command_line);
47 E : metadata->set_creation_time(creation_time);
48 E : metadata->set_toolchain_version(toolchain_version);
49 E : metadata->set_module_signature(module_signature);
50 E : }
51 :
52 E : bool TestJSONSerialization(bool pretty_print) {
53 E : base::FilePath temp_file_path;
54 E : FILE* temp_file = file_util::CreateAndOpenTemporaryFile(&temp_file_path);
55 E : if (temp_file == NULL)
56 i : return false;
57 :
58 E : bool success = true;
59 :
60 : // Output to file.
61 E : Metadata metadata1;
62 E : InitMetadata(&metadata1);
63 E : core::JSONFileWriter json_file(temp_file, pretty_print);
64 E : EXPECT_TRUE(success = metadata1.SaveToJSON(&json_file));
65 E : fclose(temp_file);
66 :
67 : // Read the file.
68 E : std::string file_string;
69 E : if (success)
70 : EXPECT_TRUE(success =
71 E : file_util::ReadFileToString(temp_file_path, &file_string));
72 :
73 : // Parse the JSON, extracting the root dictionary.
74 E : scoped_ptr<Value> value;
75 E : DictionaryValue* metadata_dict = NULL;
76 E : if (success) {
77 E : value.reset(base::JSONReader::Read(file_string));
78 : EXPECT_TRUE(success =
79 E : (value.get() != NULL && value->GetType() == Value::TYPE_DICTIONARY));
80 E : if (success)
81 E : metadata_dict = static_cast<DictionaryValue*>(value.get());
82 : }
83 :
84 : // Parse the metadata from the Value.
85 E : Metadata metadata2;
86 E : if (success) {
87 E : DCHECK(metadata_dict != NULL);
88 E : EXPECT_TRUE(success = metadata2.LoadFromJSON(*metadata_dict));
89 : }
90 :
91 : // Compare the two structures.
92 E : if (success)
93 E : EXPECT_TRUE(success = (metadata1 == metadata2));
94 :
95 : // Always delete the temporary file.
96 E : if (!file_util::Delete(temp_file_path, false))
97 i : success = false;
98 :
99 E : return success;
100 E : }
101 :
102 : } // namespace
103 :
104 E : TEST(MetadataTest, Equality) {
105 E : Metadata metadata1;
106 E : Metadata metadata2;
107 E : InitMetadata(&metadata1);
108 E : InitMetadata(&metadata2);
109 E : EXPECT_EQ(metadata1, metadata2);
110 E : }
111 :
112 E : TEST(MetadataTest, Inequality) {
113 E : Metadata metadata1;
114 E : Metadata metadata2;
115 E : InitMetadata(&metadata1);
116 E : EXPECT_NE(metadata1, metadata2);
117 E : }
118 :
119 E : TEST(MetadataTest, SaveToBlock) {
120 E : Metadata metadata1;
121 E : InitMetadata(&metadata1);
122 :
123 E : BlockGraph block_graph;
124 : BlockGraph::Block* block =
125 E : block_graph.AddBlock(BlockGraph::DATA_BLOCK, 0, "Metadata");
126 E : EXPECT_TRUE(metadata1.SaveToBlock(block));
127 :
128 E : Metadata metadata2;
129 E : EXPECT_TRUE(metadata2.LoadFromBlock(block));
130 E : EXPECT_EQ(metadata1, metadata2);
131 E : }
132 :
133 E : TEST(MetadataTest, Serialization) {
134 E : Metadata metadata;
135 E : InitMetadata(&metadata);
136 E : EXPECT_TRUE(testing::TestSerialization(metadata));
137 E : }
138 :
139 E : TEST(MetadataTest, JSONSerializationNoPrettyPrint) {
140 E : EXPECT_TRUE(TestJSONSerialization(true));
141 E : }
142 :
143 E : TEST(MetadataTest, JSONSerializationPrettyPrint) {
144 E : EXPECT_TRUE(TestJSONSerialization(false));
145 E : }
146 :
147 : } // namespace pe
|