• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2018 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "components/zucchini/disassembler_elf.h"
6 
7 #include <stddef.h>
8 #include <stdint.h>
9 
10 #include <algorithm>
11 #include <random>
12 #include <string>
13 #include <vector>
14 
15 #include "components/zucchini/test_utils.h"
16 #include "components/zucchini/type_elf.h"
17 #include "testing/gtest/include/gtest/gtest.h"
18 
19 namespace zucchini {
20 
TEST(DisassemblerElfTest,IsTargetOffsetInElfSectionList)21 TEST(DisassemblerElfTest, IsTargetOffsetInElfSectionList) {
22   // Minimal required fields for IsTargetOffsetInElfSectionList().
23   struct FakeElfShdr {
24     offset_t sh_offset;
25     offset_t sh_size;
26   };
27 
28   // Calls IsTargetOffsetInElfSectionList() for fixed |sorted_list|, and sweeps
29   // offsets in [lo, hi). Renders results into a string consisting of '.' (not
30   // in list) and '*' (in list).
31   auto test = [&](const std::vector<FakeElfShdr>& sorted_list, offset_t lo,
32                   offset_t hi) -> std::string {
33     // Ensure |sorted_list| is indeed sorted, without overlaps.
34     for (size_t i = 1; i < sorted_list.size(); ++i) {
35       if (sorted_list[i].sh_offset <
36           sorted_list[i - 1].sh_offset + sorted_list[i - 1].sh_size) {
37         return "(Bad input)";
38       }
39     }
40     // The interface to IsTargetOffsetInElfSectionList() takes a list of
41     // pointers (since data can be casted from images), so make the conversion.
42     std::vector<const FakeElfShdr*> ptr_list;
43     for (const FakeElfShdr& header : sorted_list)
44       ptr_list.push_back(&header);
45     std::string result;
46     for (offset_t offset = lo; offset < hi; ++offset) {
47       result += IsTargetOffsetInElfSectionList(ptr_list, offset) ? '*' : '.';
48     }
49     return result;
50   };
51 
52   EXPECT_EQ("..........", test(std::vector<FakeElfShdr>(), 0, 10));
53   EXPECT_EQ("*.........", test({{0, 1}}, 0, 10));
54   EXPECT_EQ("...*......", test({{3, 1}}, 0, 10));
55   EXPECT_EQ("...****...", test({{3, 4}}, 0, 10));
56   EXPECT_EQ("...****...", test({{10003, 4}}, 10000, 10010));
57   EXPECT_EQ("...********...", test({{3, 4}, {7, 4}}, 0, 14));
58   EXPECT_EQ("...****.****...", test({{3, 4}, {8, 4}}, 0, 15));
59   EXPECT_EQ("...****..****...", test({{3, 4}, {9, 4}}, 0, 16));
60   EXPECT_EQ("..****...*****..", test({{2, 4}, {9, 5}}, 0, 16));
61   EXPECT_EQ("...***......***..", test({{3, 3}, {12, 3}}, 0, 17));
62 
63   // Many small ranges.
64   EXPECT_EQ("..**.**.*.*...*.*.**...**.*.**.*..",  // (Comment strut).
65             test({{2, 2},
66                   {5, 2},
67                   {8, 1},
68                   {10, 1},
69                   {14, 1},
70                   {16, 1},
71                   {18, 2},
72                   {23, 2},
73                   {26, 1},
74                   {28, 2},
75                   {31, 1}},
76                  0, 34));
77   EXPECT_EQ("..*****.****.***.**.*..",
78             test({{137, 5}, {143, 4}, {148, 3}, {152, 2}, {155, 1}}, 135, 158));
79   // Consecutive.
80   EXPECT_EQ("..***************..",
81             test({{137, 5}, {142, 4}, {146, 3}, {149, 2}, {151, 1}}, 135, 154));
82   // Hover around 32 (power of 2).
83   EXPECT_EQ("..*******************************..",
84             test({{2002, 31}}, 2000, 2035));
85   EXPECT_EQ("..********************************..",
86             test({{5002, 32}}, 5000, 5036));
87   EXPECT_EQ("..*********************************..",
88             test({{8002, 33}}, 8000, 8037));
89   // Consecutive + small gap.
90   EXPECT_EQ(
91       "..*****************.***********..",
92       test({{9876543, 8}, {9876551, 9}, {9876561, 11}}, 9876541, 9876574));
93   // Sample internal of big range.
94   EXPECT_EQ("**************************************************",
95             test({{100, 1000000}}, 5000, 5050));
96   // Sample boundaries of big range.
97   EXPECT_EQ(".........................*************************",
98             test({{100, 1000000}}, 75, 125));
99   EXPECT_EQ("*************************.........................",
100             test({{100, 1000000}}, 1000075, 1000125));
101   // 1E9 is still good.
102   EXPECT_EQ(".....*.....", test({{1000000000, 1}}, 999999995, 1000000006));
103 }
104 
TEST(DisassemblerElfTest,QuickDetect)105 TEST(DisassemblerElfTest, QuickDetect) {
106   std::vector<uint8_t> image_data;
107   ConstBufferView image;
108 
109   // Empty.
110   EXPECT_FALSE(DisassemblerElfX86::QuickDetect(image));
111   EXPECT_FALSE(DisassemblerElfX64::QuickDetect(image));
112 
113   // Unrelated.
114   image_data = ParseHexString("DE AD");
115   image = {image_data.data(), image_data.size()};
116   EXPECT_FALSE(DisassemblerElfX86::QuickDetect(image));
117   EXPECT_FALSE(DisassemblerElfX64::QuickDetect(image));
118 
119   // Only Magic.
120   image_data = ParseHexString("7F 45 4C 46");
121   image = {image_data.data(), image_data.size()};
122   EXPECT_FALSE(DisassemblerElfX86::QuickDetect(image));
123   EXPECT_FALSE(DisassemblerElfX64::QuickDetect(image));
124 
125   // Only identification.
126   image_data =
127       ParseHexString("7F 45 4C 46 01 01 01 00 00 00 00 00 00 00 00 00");
128   image = {image_data.data(), image_data.size()};
129   EXPECT_FALSE(DisassemblerElfX86::QuickDetect(image));
130   EXPECT_FALSE(DisassemblerElfX64::QuickDetect(image));
131 
132   // Large enough, filled with zeros.
133   image_data.assign(sizeof(elf::Elf32_Ehdr), 0);
134   image = {image_data.data(), image_data.size()};
135   EXPECT_FALSE(DisassemblerElfX86::QuickDetect(image));
136   EXPECT_FALSE(DisassemblerElfX64::QuickDetect(image));
137 
138   // Random.
139   std::random_device rd;
140   std::mt19937 gen{rd()};
141   std::generate(image_data.begin(), image_data.end(), gen);
142   image = {image_data.data(), image_data.size()};
143   EXPECT_FALSE(DisassemblerElfX86::QuickDetect(image));
144   EXPECT_FALSE(DisassemblerElfX64::QuickDetect(image));
145 
146   // Typical x86 elf header.
147   {
148     elf::Elf32_Ehdr header = {};
149     auto e_ident =
150         ParseHexString("7F 45 4C 46 01 01 01 00 00 00 00 00 00 00 00 00");
151     std::copy(e_ident.begin(), e_ident.end(), header.e_ident);
152     header.e_type = elf::ET_EXEC;
153     header.e_machine = elf::EM_386;
154     header.e_version = 1;
155     header.e_shentsize = sizeof(elf::Elf32_Shdr);
156     image = {reinterpret_cast<const uint8_t*>(&header), sizeof(header)};
157     EXPECT_TRUE(DisassemblerElfX86::QuickDetect(image));
158     EXPECT_FALSE(DisassemblerElfX64::QuickDetect(image));
159   }
160 
161   // Typical x64 elf header.
162   {
163     elf::Elf64_Ehdr header = {};
164     auto e_ident =
165         ParseHexString("7F 45 4C 46 02 01 01 00 00 00 00 00 00 00 00 00");
166     std::copy(e_ident.begin(), e_ident.end(), header.e_ident);
167     header.e_type = elf::ET_EXEC;
168     header.e_machine = elf::EM_X86_64;
169     header.e_version = 1;
170     header.e_shentsize = sizeof(elf::Elf64_Shdr);
171     image = {reinterpret_cast<const uint8_t*>(&header), sizeof(header)};
172     EXPECT_FALSE(DisassemblerElfX86::QuickDetect(image));
173     EXPECT_TRUE(DisassemblerElfX64::QuickDetect(image));
174   }
175 }
176 
177 }  // namespace zucchini
178