encode_decode_unittest.cc 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. // Copyright (c) 2011 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 <stddef.h>
  5. #include <memory>
  6. #include "courgette/base_test_unittest.h"
  7. #include "courgette/courgette.h"
  8. #include "courgette/courgette_flow.h"
  9. #include "courgette/streams.h"
  10. namespace courgette {
  11. class EncodeDecodeTest : public BaseTest {
  12. public:
  13. void TestAssembleToStreamDisassemble(const std::string& file,
  14. size_t expected_encoded_length) const;
  15. };
  16. void EncodeDecodeTest::TestAssembleToStreamDisassemble(
  17. const std::string& file,
  18. size_t expected_encoded_length) const {
  19. const uint8_t* original_data = reinterpret_cast<const uint8_t*>(file.data());
  20. size_t original_length = file.length();
  21. CourgetteFlow flow;
  22. // Convert executable to encoded assembly.
  23. RegionBuffer original_buffer(Region(original_data, original_length));
  24. flow.ReadDisassemblerFromBuffer(flow.ONLY, original_buffer);
  25. EXPECT_EQ(C_OK, flow.status());
  26. EXPECT_TRUE(nullptr != flow.data(flow.ONLY)->disassembler.get());
  27. flow.CreateAssemblyProgramFromDisassembler(flow.ONLY, false);
  28. EXPECT_EQ(C_OK, flow.status());
  29. EXPECT_TRUE(nullptr != flow.data(flow.ONLY)->program.get());
  30. flow.CreateEncodedProgramFromDisassemblerAndAssemblyProgram(flow.ONLY);
  31. EXPECT_EQ(C_OK, flow.status());
  32. EXPECT_TRUE(nullptr != flow.data(flow.ONLY)->encoded.get());
  33. flow.DestroyAssemblyProgram(flow.ONLY);
  34. EXPECT_EQ(C_OK, flow.status());
  35. EXPECT_TRUE(nullptr == flow.data(flow.ONLY)->program.get());
  36. flow.DestroyDisassembler(flow.ONLY);
  37. EXPECT_EQ(C_OK, flow.status());
  38. EXPECT_TRUE(nullptr == flow.data(flow.ONLY)->disassembler.get());
  39. flow.WriteSinkStreamSetFromEncodedProgram(flow.ONLY);
  40. EXPECT_EQ(C_OK, flow.status());
  41. flow.DestroyEncodedProgram(flow.ONLY);
  42. EXPECT_EQ(C_OK, flow.status());
  43. EXPECT_TRUE(nullptr == flow.data(flow.ONLY)->encoded.get());
  44. SinkStream sink;
  45. flow.WriteSinkStreamFromSinkStreamSet(flow.ONLY, &sink);
  46. EXPECT_EQ(C_OK, flow.status());
  47. const void* encoded_data = sink.Buffer();
  48. size_t encoded_length = sink.Length();
  49. EXPECT_EQ(expected_encoded_length, encoded_length);
  50. // Convert encoded assembly back to executable.
  51. RegionBuffer encoded_buffer(Region(encoded_data, encoded_length));
  52. flow.ReadSourceStreamSetFromBuffer(flow.ONLY, encoded_buffer);
  53. EXPECT_EQ(C_OK, flow.status());
  54. flow.ReadEncodedProgramFromSourceStreamSet(flow.ONLY);
  55. EXPECT_EQ(C_OK, flow.status());
  56. EXPECT_TRUE(nullptr != flow.data(flow.ONLY)->encoded.get());
  57. SinkStream executable;
  58. flow.WriteExecutableFromEncodedProgram(flow.ONLY, &executable);
  59. EXPECT_EQ(C_OK, flow.status());
  60. flow.DestroyEncodedProgram(flow.ONLY);
  61. EXPECT_EQ(C_OK, flow.status());
  62. EXPECT_TRUE(nullptr == flow.data(flow.ONLY)->encoded.get());
  63. EXPECT_TRUE(flow.ok());
  64. EXPECT_FALSE(flow.failed());
  65. const void* executable_data = executable.Buffer();
  66. size_t executable_length = executable.Length();
  67. EXPECT_EQ(original_length, executable_length);
  68. EXPECT_EQ(0, memcmp(original_data, executable_data, original_length));
  69. }
  70. TEST_F(EncodeDecodeTest, PE) {
  71. std::string file = FileContents("setup1.exe");
  72. TestAssembleToStreamDisassemble(file, 972845);
  73. }
  74. TEST_F(EncodeDecodeTest, PE64) {
  75. std::string file = FileContents("chrome64_1.exe");
  76. TestAssembleToStreamDisassemble(file, 810090);
  77. }
  78. TEST_F(EncodeDecodeTest, Elf_Small) {
  79. std::string file = FileContents("elf-32-1");
  80. TestAssembleToStreamDisassemble(file, 136201);
  81. }
  82. TEST_F(EncodeDecodeTest, Elf_HighBSS) {
  83. std::string file = FileContents("elf-32-high-bss");
  84. TestAssembleToStreamDisassemble(file, 7308);
  85. }
  86. } // namespace courgette