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