disassembler_elf_unittest.cc 6.5 KB

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