abs32_utils_unittest.cc 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543
  1. // Copyright 2017 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/abs32_utils.h"
  5. #include <stdint.h>
  6. #include <algorithm>
  7. #include <string>
  8. #include <utility>
  9. #include "base/numerics/safe_conversions.h"
  10. #include "components/zucchini/address_translator.h"
  11. #include "components/zucchini/image_utils.h"
  12. #include "components/zucchini/test_utils.h"
  13. #include "testing/gtest/include/gtest/gtest.h"
  14. namespace zucchini {
  15. namespace {
  16. // A trivial AddressTranslator that applies constant shift.
  17. class TestAddressTranslator : public AddressTranslator {
  18. public:
  19. TestAddressTranslator(size_t image_size, rva_t rva_begin) {
  20. DCHECK_GE(rva_begin, 0U);
  21. CHECK_EQ(AddressTranslator::kSuccess,
  22. Initialize({{0, base::checked_cast<offset_t>(image_size),
  23. rva_begin, base::checked_cast<rva_t>(image_size)}}));
  24. }
  25. };
  26. // Helper to translate address |value| to RVA. May return |kInvalidRva|.
  27. rva_t AddrValueToRva(uint64_t value, AbsoluteAddress* addr) {
  28. *addr->mutable_value() = value;
  29. return addr->ToRva();
  30. }
  31. } // namespace
  32. TEST(Abs32UtilsTest, AbsoluteAddress32) {
  33. std::vector<uint8_t> data32 = ParseHexString(
  34. "00 00 32 00 21 43 65 4A 00 00 00 00 FF FF FF FF FF FF 31 00");
  35. ConstBufferView image32(data32.data(), data32.size());
  36. MutableBufferView mutable_image32(data32.data(), data32.size());
  37. AbsoluteAddress addr32(kBit32, 0x00320000U);
  38. EXPECT_TRUE(addr32.Read(0x0U, image32));
  39. EXPECT_EQ(0x00000000U, addr32.ToRva());
  40. EXPECT_TRUE(addr32.Read(0x4U, image32));
  41. EXPECT_EQ(0x4A334321U, addr32.ToRva());
  42. EXPECT_TRUE(addr32.Read(0x8U, image32));
  43. EXPECT_EQ(kInvalidRva, addr32.ToRva()); // Underflow.
  44. EXPECT_TRUE(addr32.Read(0xCU, image32));
  45. EXPECT_EQ(kInvalidRva, addr32.ToRva()); // Translated RVA would be too large.
  46. EXPECT_TRUE(addr32.Read(0x10U, image32));
  47. EXPECT_EQ(kInvalidRva, addr32.ToRva()); // Underflow (boundary case).
  48. EXPECT_FALSE(addr32.Read(0x11U, image32));
  49. EXPECT_FALSE(addr32.Read(0x14U, image32));
  50. EXPECT_FALSE(addr32.Read(0x100000U, image32));
  51. EXPECT_FALSE(addr32.Read(0x80000000U, image32));
  52. EXPECT_FALSE(addr32.Read(0xFFFFFFFFU, image32));
  53. EXPECT_TRUE(addr32.FromRva(0x11223344U));
  54. EXPECT_TRUE(addr32.Write(0x2U, &mutable_image32));
  55. EXPECT_TRUE(addr32.Write(0x10U, &mutable_image32));
  56. std::vector<uint8_t> expected_data32 = ParseHexString(
  57. "00 00 44 33 54 11 65 4A 00 00 00 00 FF FF FF FF 44 33 54 11");
  58. EXPECT_EQ(expected_data32, data32);
  59. EXPECT_FALSE(addr32.Write(0x11U, &mutable_image32));
  60. EXPECT_FALSE(addr32.Write(0xFFFFFFFFU, &mutable_image32));
  61. EXPECT_EQ(expected_data32, data32);
  62. }
  63. TEST(Abs32UtilsTest, AbsoluteAddress32Overflow) {
  64. AbsoluteAddress addr32(kBit32, 0xC0000000U);
  65. EXPECT_TRUE(addr32.FromRva(0x00000000U));
  66. EXPECT_TRUE(addr32.FromRva(0x11223344U));
  67. EXPECT_TRUE(addr32.FromRva(0x3FFFFFFFU));
  68. EXPECT_FALSE(addr32.FromRva(0x40000000U));
  69. EXPECT_FALSE(addr32.FromRva(0x40000001U));
  70. EXPECT_FALSE(addr32.FromRva(0x80000000U));
  71. EXPECT_FALSE(addr32.FromRva(0xFFFFFFFFU));
  72. EXPECT_EQ(0x00000000U, AddrValueToRva(0xC0000000U, &addr32));
  73. EXPECT_EQ(kInvalidRva, AddrValueToRva(0xBFFFFFFFU, &addr32));
  74. EXPECT_EQ(kInvalidRva, AddrValueToRva(0x00000000U, &addr32));
  75. EXPECT_EQ(0x3FFFFFFFU, AddrValueToRva(0xFFFFFFFFU, &addr32));
  76. }
  77. TEST(Abs32UtilsTest, AbsoluteAddress64) {
  78. std::vector<uint8_t> data64 = ParseHexString(
  79. "00 00 00 00 64 00 00 00 21 43 65 4A 64 00 00 00 "
  80. "00 00 00 00 00 00 00 00 FF FF FF FF FF FF FF FF "
  81. "00 00 00 00 64 00 00 80 FF FF FF FF 63 00 00 00");
  82. ConstBufferView image64(data64.data(), data64.size());
  83. MutableBufferView mutable_image64(data64.data(), data64.size());
  84. AbsoluteAddress addr64(kBit64, 0x0000006400000000ULL);
  85. EXPECT_TRUE(addr64.Read(0x0U, image64));
  86. EXPECT_EQ(0x00000000U, addr64.ToRva());
  87. EXPECT_TRUE(addr64.Read(0x8U, image64));
  88. EXPECT_EQ(0x4A654321U, addr64.ToRva());
  89. EXPECT_TRUE(addr64.Read(0x10U, image64)); // Succeeds, in spite of value.
  90. EXPECT_EQ(kInvalidRva, addr64.ToRva()); // Underflow.
  91. EXPECT_TRUE(addr64.Read(0x18U, image64));
  92. EXPECT_EQ(kInvalidRva, addr64.ToRva()); // Translated RVA too large.
  93. EXPECT_TRUE(addr64.Read(0x20U, image64));
  94. EXPECT_EQ(kInvalidRva, addr64.ToRva()); // Translated RVA toolarge.
  95. EXPECT_TRUE(addr64.Read(0x28U, image64));
  96. EXPECT_EQ(kInvalidRva, addr64.ToRva()); // Underflow.
  97. EXPECT_FALSE(addr64.Read(0x29U, image64)); // Extends outside.
  98. EXPECT_FALSE(addr64.Read(0x30U, image64)); // Entirely outside (note: hex).
  99. EXPECT_FALSE(addr64.Read(0x100000U, image64));
  100. EXPECT_FALSE(addr64.Read(0x80000000U, image64));
  101. EXPECT_FALSE(addr64.Read(0xFFFFFFFFU, image64));
  102. EXPECT_TRUE(addr64.FromRva(0x11223344U));
  103. EXPECT_TRUE(addr64.Write(0x13U, &mutable_image64));
  104. EXPECT_TRUE(addr64.Write(0x20U, &mutable_image64));
  105. std::vector<uint8_t> expected_data64 = ParseHexString(
  106. "00 00 00 00 64 00 00 00 21 43 65 4A 64 00 00 00 "
  107. "00 00 00 44 33 22 11 64 00 00 00 FF FF FF FF FF "
  108. "44 33 22 11 64 00 00 00 FF FF FF FF 63 00 00 00");
  109. EXPECT_EQ(expected_data64, data64);
  110. EXPECT_FALSE(addr64.Write(0x29U, &mutable_image64));
  111. EXPECT_FALSE(addr64.Write(0x30U, &mutable_image64));
  112. EXPECT_FALSE(addr64.Write(0xFFFFFFFFU, &mutable_image64));
  113. EXPECT_EQ(expected_data64, data64);
  114. EXPECT_FALSE(addr64.FromRva(0xFFFFFFFFU));
  115. }
  116. TEST(Abs32UtilsTest, AbsoluteAddress64Overflow) {
  117. {
  118. // Counterpart to AbsoluteAddress632verflow test.
  119. AbsoluteAddress addr64(kBit64, 0xFFFFFFFFC0000000ULL);
  120. EXPECT_TRUE(addr64.FromRva(0x00000000U));
  121. EXPECT_TRUE(addr64.FromRva(0x11223344U));
  122. EXPECT_TRUE(addr64.FromRva(0x3FFFFFFFU));
  123. EXPECT_FALSE(addr64.FromRva(0x40000000U));
  124. EXPECT_FALSE(addr64.FromRva(0x40000001U));
  125. EXPECT_FALSE(addr64.FromRva(0x80000000U));
  126. EXPECT_FALSE(addr64.FromRva(0xFFFFFFFFU));
  127. EXPECT_EQ(0x00000000U, AddrValueToRva(0xFFFFFFFFC0000000U, &addr64));
  128. EXPECT_EQ(kInvalidRva, AddrValueToRva(0xFFFFFFFFBFFFFFFFU, &addr64));
  129. EXPECT_EQ(kInvalidRva, AddrValueToRva(0x0000000000000000U, &addr64));
  130. EXPECT_EQ(kInvalidRva, AddrValueToRva(0xFFFFFFFF00000000U, &addr64));
  131. EXPECT_EQ(0x3FFFFFFFU, AddrValueToRva(0xFFFFFFFFFFFFFFFFU, &addr64));
  132. }
  133. {
  134. // Pseudo-counterpart to AbsoluteAddress632verflow test: Some now pass.
  135. AbsoluteAddress addr64(kBit64, 0xC0000000U);
  136. EXPECT_TRUE(addr64.FromRva(0x00000000U));
  137. EXPECT_TRUE(addr64.FromRva(0x11223344U));
  138. EXPECT_TRUE(addr64.FromRva(0x3FFFFFFFU));
  139. EXPECT_TRUE(addr64.FromRva(0x40000000U));
  140. EXPECT_TRUE(addr64.FromRva(0x40000001U));
  141. EXPECT_FALSE(addr64.FromRva(0x80000000U));
  142. EXPECT_FALSE(addr64.FromRva(0xFFFFFFFFU));
  143. // ToRva() still fail though.
  144. EXPECT_EQ(0x00000000U, AddrValueToRva(0xC0000000U, &addr64));
  145. EXPECT_EQ(kInvalidRva, AddrValueToRva(0xBFFFFFFFU, &addr64));
  146. EXPECT_EQ(kInvalidRva, AddrValueToRva(0x00000000U, &addr64));
  147. EXPECT_EQ(0x3FFFFFFFU, AddrValueToRva(0xFFFFFFFFU, &addr64));
  148. }
  149. {
  150. AbsoluteAddress addr64(kBit64, 0xC000000000000000ULL);
  151. EXPECT_TRUE(addr64.FromRva(0x00000000ULL));
  152. EXPECT_TRUE(addr64.FromRva(0x11223344ULL));
  153. EXPECT_TRUE(addr64.FromRva(0x3FFFFFFFULL));
  154. EXPECT_TRUE(addr64.FromRva(0x40000000ULL));
  155. EXPECT_TRUE(addr64.FromRva(0x40000001ULL));
  156. EXPECT_FALSE(addr64.FromRva(0x80000000ULL));
  157. EXPECT_FALSE(addr64.FromRva(0xFFFFFFFFULL));
  158. EXPECT_EQ(0x00000000U, AddrValueToRva(0xC000000000000000ULL, &addr64));
  159. EXPECT_EQ(kInvalidRva, AddrValueToRva(0xBFFFFFFFFFFFFFFFULL, &addr64));
  160. EXPECT_EQ(kInvalidRva, AddrValueToRva(0x0000000000000000ULL, &addr64));
  161. EXPECT_EQ(0x3FFFFFFFU, AddrValueToRva(0xC00000003FFFFFFFULL, &addr64));
  162. EXPECT_EQ(kInvalidRva, AddrValueToRva(0xFFFFFFFFFFFFFFFFULL, &addr64));
  163. }
  164. }
  165. TEST(Abs32UtilsTest, Win32Read32) {
  166. constexpr uint32_t kImageBase = 0xA0000000U;
  167. constexpr uint32_t kRvaBegin = 0x00C00000U;
  168. struct {
  169. std::vector<uint8_t> data32;
  170. std::deque<offset_t> abs32_locations; // Assumption: Sorted.
  171. offset_t lo; // Assumption: In range, does not straddle |abs32_location|.
  172. offset_t hi; // Assumption: Also >= |lo|.
  173. std::vector<Reference> expected_refs;
  174. } test_cases[] = {
  175. // Targets at beginning and end.
  176. {ParseHexString("FF FF FF FF 0F 00 C0 A0 00 00 C0 A0 FF FF FF FF"),
  177. {0x4U, 0x8U},
  178. 0x0U,
  179. 0x10U,
  180. {{0x4U, 0xFU}, {0x8U, 0x0U}}},
  181. // Targets at beginning and end are out of bound: Rejected.
  182. {ParseHexString("FF FF FF FF 10 00 C0 A0 FF FF BF A0 FF FF FF FF"),
  183. {0x4U, 0x8U},
  184. 0x0U,
  185. 0x10U,
  186. std::vector<Reference>()},
  187. // Same with more extreme target values: Rejected.
  188. {ParseHexString("FF FF FF FF FF FF FF FF 00 00 00 00 FF FF FF FF"),
  189. {0x4U, 0x8U},
  190. 0x0U,
  191. 0x10U,
  192. std::vector<Reference>()},
  193. // Locations at beginning and end, plus invalid locations.
  194. {ParseHexString("08 00 C0 A0 FF FF FF FF FF FF FF FF 04 00 C0 A0"),
  195. {0x0U, 0xCU, 0x10U, 0x1000U, 0x80000000U, 0xFFFFFFFFU},
  196. 0x0U,
  197. 0x10U,
  198. {{0x0U, 0x8U}, {0xCU, 0x4U}}},
  199. // Odd size, location, target.
  200. {ParseHexString("FF FF FF 09 00 C0 A0 FF FF FF FF FF FF FF FF FF "
  201. "FF FF FF"),
  202. {0x3U},
  203. 0x0U,
  204. 0x13U,
  205. {{0x3U, 0x9U}}},
  206. // No location given.
  207. {ParseHexString("FF FF FF FF 0C 00 C0 A0 00 00 C0 A0 FF FF FF FF"),
  208. std::deque<offset_t>(), 0x0U, 0x10U, std::vector<Reference>()},
  209. // Simple alternation.
  210. {ParseHexString("04 00 C0 A0 FF FF FF FF 0C 00 C0 A0 FF FF FF FF "
  211. "14 00 C0 A0 FF FF FF FF 1C 00 C0 A0 FF FF FF FF"),
  212. {0x0U, 0x8U, 0x10U, 0x18U},
  213. 0x0U,
  214. 0x20U,
  215. {{0x0U, 0x4U}, {0x8U, 0xCU}, {0x10U, 0x14U}, {0x18U, 0x1CU}}},
  216. // Same, with locations limited by |lo| and |hi|. By assumption these must
  217. // not cut accross Reference body.
  218. {ParseHexString("04 00 C0 A0 FF FF FF FF 0C 00 C0 A0 FF FF FF FF "
  219. "14 00 C0 A0 FF FF FF FF 1C 00 C0 A0 FF FF FF FF"),
  220. {0x0U, 0x8U, 0x10U, 0x18U},
  221. 0x04U,
  222. 0x17U,
  223. {{0x8U, 0xCU}, {0x10U, 0x14U}}},
  224. // Same, with very limiting |lo| and |hi|.
  225. {ParseHexString("04 00 C0 A0 FF FF FF FF 0C 00 C0 A0 FF FF FF FF "
  226. "14 00 C0 A0 FF FF FF FF 1C 00 C0 A0 FF FF FF FF"),
  227. {0x0U, 0x8U, 0x10U, 0x18U},
  228. 0x0CU,
  229. 0x10U,
  230. std::vector<Reference>()},
  231. // Same, |lo| == |hi|.
  232. {ParseHexString("04 00 C0 A0 FF FF FF FF 0C 00 C0 A0 FF FF FF FF "
  233. "14 00 C0 A0 FF FF FF FF 1C 00 C0 A0 FF FF FF FF"),
  234. {0x0U, 0x8U, 0x10U, 0x18U},
  235. 0x14U,
  236. 0x14U,
  237. std::vector<Reference>()},
  238. // Same, |lo| and |hi| at end.
  239. {ParseHexString("04 00 C0 A0 FF FF FF FF 0C 00 C0 A0 FF FF FF FF "
  240. "14 00 C0 A0 FF FF FF FF 1C 00 C0 A0 FF FF FF FF"),
  241. {0x0U, 0x8U, 0x10U, 0x18U},
  242. 0x20U,
  243. 0x20U,
  244. std::vector<Reference>()},
  245. // Mix. Note that targets can overlap.
  246. {ParseHexString("FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF "
  247. "06 00 C0 A0 2C 00 C0 A0 FF FF C0 A0 2B 00 C0 A0 "
  248. "FF 06 00 C0 A0 00 00 C0 A0 FF FF FF FF FF FF FF"),
  249. {0x10U, 0x14U, 0x18U, 0x1CU, 0x21U, 0x25U, 0xAAAAU},
  250. 0x07U,
  251. 0x25U,
  252. {{0x10U, 0x6U}, {0x14U, 0x2CU}, {0x1CU, 0x2BU}, {0x21, 0x6U}}},
  253. };
  254. for (const auto& test_case : test_cases) {
  255. ConstBufferView image32(test_case.data32.data(), test_case.data32.size());
  256. Abs32RvaExtractorWin32 extractor(image32, {kBit32, kImageBase},
  257. test_case.abs32_locations, test_case.lo,
  258. test_case.hi);
  259. TestAddressTranslator translator(test_case.data32.size(), kRvaBegin);
  260. Abs32ReaderWin32 reader(std::move(extractor), translator);
  261. // Loop over |expected_ref| to check element-by-element.
  262. absl::optional<Reference> ref;
  263. for (const auto& expected_ref : test_case.expected_refs) {
  264. ref = reader.GetNext();
  265. EXPECT_TRUE(ref.has_value());
  266. EXPECT_EQ(expected_ref, ref.value());
  267. }
  268. // Check that nothing is left.
  269. ref = reader.GetNext();
  270. EXPECT_FALSE(ref.has_value());
  271. }
  272. }
  273. TEST(Abs32UtilsTest, Win32Read64) {
  274. constexpr uint64_t kImageBase = 0x31415926A0000000U;
  275. constexpr uint32_t kRvaBegin = 0x00C00000U;
  276. // For simplicity, just test mixed case.
  277. std::vector<uint8_t> data64 = ParseHexString(
  278. "FF FF FF FF FF FF FF FF 00 00 C0 A0 26 59 41 31 "
  279. "06 00 C0 A0 26 59 41 31 02 00 C0 A0 26 59 41 31 "
  280. "FF FF FF BF 26 59 41 31 FF FF FF FF FF FF FF FF "
  281. "02 00 C0 A0 26 59 41 31 07 00 C0 A0 26 59 41 31");
  282. std::deque<offset_t> abs32_locations = {0x8U, 0x10U, 0x18U, 0x20U,
  283. 0x28U, 0x30U, 0x38U, 0x40U};
  284. offset_t lo = 0x10U;
  285. offset_t hi = 0x38U;
  286. std::vector<Reference> expected_refs = {
  287. {0x10U, 0x06U}, {0x18U, 0x02U}, {0x30U, 0x02U}};
  288. ConstBufferView image64(data64.data(), data64.size());
  289. Abs32RvaExtractorWin32 extractor(image64, {kBit64, kImageBase},
  290. abs32_locations, lo, hi);
  291. TestAddressTranslator translator(data64.size(), kRvaBegin);
  292. Abs32ReaderWin32 reader(std::move(extractor), translator);
  293. std::vector<Reference> refs;
  294. absl::optional<Reference> ref;
  295. for (ref = reader.GetNext(); ref.has_value(); ref = reader.GetNext())
  296. refs.push_back(ref.value());
  297. EXPECT_EQ(expected_refs, refs);
  298. }
  299. TEST(Abs32UtilsTest, Win32ReadFail) {
  300. // Make |bitness| a state to reduce repetition.
  301. Bitness bitness = kBit32;
  302. constexpr uint32_t kImageBase = 0xA0000000U; // Shared for 32-bit and 64-bit.
  303. std::vector<uint8_t> data(32U, 0xFFU);
  304. ConstBufferView image(data.data(), data.size());
  305. auto try_make = [&](std::deque<offset_t>&& abs32_locations, offset_t lo,
  306. offset_t hi) {
  307. Abs32RvaExtractorWin32 extractor(image, {bitness, kImageBase},
  308. abs32_locations, lo, hi);
  309. extractor.GetNext(); // Dummy call so |extractor| gets used.
  310. };
  311. // 32-bit tests.
  312. bitness = kBit32;
  313. try_make({8U, 24U}, 0U, 32U);
  314. EXPECT_DEATH(try_make({4U, 24U}, 32U, 0U), ""); // |lo| > |hi|.
  315. try_make({8U, 24U}, 0U, 12U);
  316. try_make({8U, 24U}, 0U, 28U);
  317. try_make({8U, 24U}, 8U, 32U);
  318. try_make({8U, 24U}, 24U, 32U);
  319. EXPECT_DEATH(try_make({8U, 24U}, 0U, 11U), ""); // |hi| straddles.
  320. EXPECT_DEATH(try_make({8U, 24U}, 26U, 32U), ""); // |lo| straddles.
  321. try_make({8U, 24U}, 12U, 24U);
  322. // 64-bit tests.
  323. bitness = kBit64;
  324. try_make({6U, 22U}, 0U, 32U);
  325. // |lo| > |hi|.
  326. EXPECT_DEATH(try_make(std::deque<offset_t>(), 32U, 31U), "");
  327. try_make({6U, 22U}, 0U, 14U);
  328. try_make({6U, 22U}, 0U, 30U);
  329. try_make({6U, 22U}, 6U, 32U);
  330. try_make({6U, 22U}, 22U, 32U);
  331. EXPECT_DEATH(try_make({6U, 22U}, 0U, 29U), ""); // |hi| straddles.
  332. EXPECT_DEATH(try_make({6U, 22U}, 7U, 32U), ""); // |lo| straddles.
  333. try_make({6U, 22U}, 14U, 20U);
  334. try_make({16U}, 16U, 24U);
  335. EXPECT_DEATH(try_make({16U}, 18U, 18U), ""); // |lo|, |hi| straddle.
  336. }
  337. TEST(Abs32UtilsTest, Win32Write32) {
  338. constexpr uint32_t kImageBase = 0xA0000000U;
  339. constexpr uint32_t kRvaBegin = 0x00C00000U;
  340. std::vector<uint8_t> data32(0x30, 0xFFU);
  341. MutableBufferView image32(data32.data(), data32.size());
  342. AbsoluteAddress addr(kBit32, kImageBase);
  343. TestAddressTranslator translator(data32.size(), kRvaBegin);
  344. Abs32WriterWin32 writer(image32, std::move(addr), translator);
  345. // Successful writes.
  346. writer.PutNext({0x02U, 0x10U});
  347. writer.PutNext({0x0BU, 0x21U});
  348. writer.PutNext({0x16U, 0x10U});
  349. writer.PutNext({0x2CU, 0x00U});
  350. // Invalid data: For simplicity, Abs32WriterWin32 simply ignores bad writes.
  351. // Invalid location.
  352. writer.PutNext({0x2DU, 0x20U});
  353. writer.PutNext({0x80000000U, 0x20U});
  354. writer.PutNext({0xFFFFFFFFU, 0x20U});
  355. // Invalid target.
  356. writer.PutNext({0x1CU, 0x00001111U});
  357. writer.PutNext({0x10U, 0xFFFFFF00U});
  358. std::vector<uint8_t> expected_data32 = ParseHexString(
  359. "FF FF 10 00 C0 A0 FF FF FF FF FF 21 00 C0 A0 FF "
  360. "FF FF FF FF FF FF 10 00 C0 A0 FF FF FF FF FF FF "
  361. "FF FF FF FF FF FF FF FF FF FF FF FF 00 00 C0 A0");
  362. EXPECT_EQ(expected_data32, data32);
  363. }
  364. TEST(Abs32UtilsTest, Win32Write64) {
  365. constexpr uint64_t kImageBase = 0x31415926A0000000U;
  366. constexpr uint32_t kRvaBegin = 0x00C00000U;
  367. std::vector<uint8_t> data64(0x30, 0xFFU);
  368. MutableBufferView image32(data64.data(), data64.size());
  369. AbsoluteAddress addr(kBit64, kImageBase);
  370. TestAddressTranslator translator(data64.size(), kRvaBegin);
  371. Abs32WriterWin32 writer(image32, std::move(addr), translator);
  372. // Successful writes.
  373. writer.PutNext({0x02U, 0x10U});
  374. writer.PutNext({0x0BU, 0x21U});
  375. writer.PutNext({0x16U, 0x10U});
  376. writer.PutNext({0x28U, 0x00U});
  377. // Invalid data: For simplicity, Abs32WriterWin32 simply ignores bad writes.
  378. // Invalid location.
  379. writer.PutNext({0x29U, 0x20U});
  380. writer.PutNext({0x80000000U, 0x20U});
  381. writer.PutNext({0xFFFFFFFFU, 0x20U});
  382. // Invalid target.
  383. writer.PutNext({0x1CU, 0x00001111U});
  384. writer.PutNext({0x10U, 0xFFFFFF00U});
  385. std::vector<uint8_t> expected_data64 = ParseHexString(
  386. "FF FF 10 00 C0 A0 26 59 41 31 FF 21 00 C0 A0 26 "
  387. "59 41 31 FF FF FF 10 00 C0 A0 26 59 41 31 FF FF "
  388. "FF FF FF FF FF FF FF FF 00 00 C0 A0 26 59 41 31");
  389. EXPECT_EQ(expected_data64, data64);
  390. }
  391. TEST(Abs32UtilsTest, RemoveUntranslatableAbs32) {
  392. Bitness kBitness = kBit32;
  393. uint64_t kImageBase = 0x2BCD0000;
  394. // Valid RVAs: [0x00001A00, 0x00001A28) and [0x00003A00, 0x00004000).
  395. // Valid AVAs: [0x2BCD1A00, 0x2BCD1A28) and [0x2BCD3A00, 0x2BCD4000).
  396. // Notice that the second section has has dangling RVA.
  397. AddressTranslator translator;
  398. ASSERT_EQ(AddressTranslator::kSuccess,
  399. translator.Initialize(
  400. {{0x04, +0x28, 0x1A00, +0x28}, {0x30, +0x30, 0x3A00, +0x600}}));
  401. std::vector<uint8_t> data = ParseHexString(
  402. "FF FF FF FF 0B 3A CD 2B 00 00 00 04 3A CD 2B 00 "
  403. "FC 3F CD 2B 14 1A CD 2B 44 00 00 00 CC 00 00 00 "
  404. "00 00 55 00 00 00 1E 1A CD 2B 00 99 FF FF FF FF "
  405. "10 3A CD 2B 22 00 00 00 00 00 00 11 00 00 00 00 "
  406. "66 00 00 00 28 1A CD 2B 00 00 CD 2B 27 1A CD 2B "
  407. "FF 39 CD 2B 00 00 00 00 18 1A CD 2B 00 00 00 00 "
  408. "FF FF FF FF FF FF FF FF");
  409. MutableBufferView image(data.data(), data.size());
  410. const offset_t kAbs1 = 0x04; // a:2BCD3A0B = r:3A0B = o:3B
  411. const offset_t kAbs2 = 0x0B; // a:2BCD3A04 = r:3A04 = o:34
  412. const offset_t kAbs3 = 0x10; // a:2BCD3FFF = r:3FFF (dangling)
  413. const offset_t kAbs4 = 0x14; // a:2BCD1A14 = r:1A14 = o:18
  414. const offset_t kAbs5 = 0x26; // a:2BCD1A1E = r:1A1E = o:22
  415. const offset_t kAbs6 = 0x30; // a:2BCD3A10 = r:3A10 = 0x40
  416. const offset_t kAbs7 = 0x44; // a:2BCD1A28 = r:1A28 (bad: sentinel)
  417. const offset_t kAbs8 = 0x48; // a:2BCD0000 = r:0000 (bad: not covered)
  418. const offset_t kAbs9 = 0x4C; // a:2BCD1A27 = r:1A27 = 0x2B
  419. const offset_t kAbsA = 0x50; // a:2BCD39FF (bad: not covered)
  420. const offset_t kAbsB = 0x54; // a:00000000 (bad: underflow)
  421. const offset_t kAbsC = 0x58; // a:2BCD1A18 = r:1A18 = 0x1C
  422. std::deque<offset_t> locations = {kAbs1, kAbs2, kAbs3, kAbs4, kAbs5, kAbs6,
  423. kAbs7, kAbs8, kAbs9, kAbsA, kAbsB, kAbsC};
  424. std::deque<offset_t> exp_locations = {kAbs1, kAbs2, kAbs3, kAbs4,
  425. kAbs5, kAbs6, kAbs9, kAbsC};
  426. size_t exp_num_removed = locations.size() - exp_locations.size();
  427. size_t num_removed = RemoveUntranslatableAbs32(image, {kBitness, kImageBase},
  428. translator, &locations);
  429. EXPECT_EQ(exp_num_removed, num_removed);
  430. EXPECT_EQ(exp_locations, locations);
  431. }
  432. TEST(Abs32UtilsTest, RemoveOverlappingAbs32Locations) {
  433. // Make |width| a state to reduce repetition.
  434. uint32_t width = WidthOf(kBit32);
  435. auto run_test = [&width](const std::deque<offset_t>& expected_locations,
  436. std::deque<offset_t>&& locations) {
  437. ASSERT_TRUE(std::is_sorted(locations.begin(), locations.end()));
  438. size_t expected_removals = locations.size() - expected_locations.size();
  439. size_t removals = RemoveOverlappingAbs32Locations(width, &locations);
  440. EXPECT_EQ(expected_removals, removals);
  441. EXPECT_EQ(expected_locations, locations);
  442. };
  443. // 32-bit tests.
  444. width = WidthOf(kBit32);
  445. run_test(std::deque<offset_t>(), std::deque<offset_t>());
  446. run_test({4U}, {4U});
  447. run_test({4U, 10U}, {4U, 10U});
  448. run_test({4U, 8U}, {4U, 8U});
  449. run_test({4U}, {4U, 7U});
  450. run_test({4U}, {4U, 4U});
  451. run_test({4U, 8U}, {4U, 7U, 8U});
  452. run_test({4U, 10U}, {4U, 7U, 10U});
  453. run_test({4U, 9U}, {4U, 9U, 10U});
  454. run_test({3U}, {3U, 5U, 6U});
  455. run_test({3U, 7U}, {3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U});
  456. run_test({3U, 7U, 11U}, {3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 12U});
  457. run_test({4U, 8U, 12U}, {4U, 6U, 8U, 10U, 12U});
  458. run_test({4U, 8U, 12U, 16U}, {4U, 8U, 12U, 16U});
  459. run_test({4U, 8U, 12U}, {4U, 8U, 9U, 12U});
  460. run_test({4U}, {4U, 4U, 4U, 4U, 4U, 4U});
  461. run_test({3U}, {3U, 4U, 4U, 4U, 5U, 5U});
  462. run_test({3U, 7U}, {3U, 4U, 4U, 4U, 7U, 7U, 8U});
  463. run_test({10U, 20U, 30U, 40U}, {10U, 20U, 22U, 22U, 30U, 40U});
  464. run_test({1000000U, 1000004U}, {1000000U, 1000004U});
  465. run_test({1000000U}, {1000000U, 1000002U});
  466. // 64-bit tests.
  467. width = WidthOf(kBit64);
  468. run_test(std::deque<offset_t>(), std::deque<offset_t>());
  469. run_test({4U}, {4U});
  470. run_test({4U, 20U}, {4U, 20U});
  471. run_test({4U, 12U}, {4U, 12U});
  472. run_test({4U}, {4U, 11U});
  473. run_test({4U}, {4U, 5U});
  474. run_test({4U}, {4U, 4U});
  475. run_test({4U, 12U, 20U}, {4U, 12U, 20U});
  476. run_test({1U, 9U, 17U}, {1U, 9U, 17U});
  477. run_test({1U, 17U}, {1U, 8U, 17U});
  478. run_test({1U, 10U}, {1U, 10U, 17U});
  479. run_test({3U, 11U}, {3U, 4U, 5U, 6U, 7U, 8U, 9U, 10U, 11U, 12U});
  480. run_test({4U, 12U}, {4U, 6U, 8U, 10U, 12U});
  481. run_test({4U, 12U}, {4U, 12U, 16U});
  482. run_test({4U, 12U, 20U, 28U}, {4U, 12U, 20U, 28U});
  483. run_test({4U}, {4U, 4U, 4U, 4U, 5U, 5U});
  484. run_test({3U, 11U}, {3U, 4U, 4U, 4U, 11U, 11U, 12U});
  485. run_test({10U, 20U, 30U, 40U}, {10U, 20U, 22U, 22U, 30U, 40U});
  486. run_test({1000000U, 1000008U}, {1000000U, 1000008U});
  487. run_test({1000000U}, {1000000U, 1000004U});
  488. }
  489. } // namespace zucchini