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