patcher_x86_32.h 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. // Copyright (c) 2012 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. #ifndef COURGETTE_PATCHER_X86_32_H_
  5. #define COURGETTE_PATCHER_X86_32_H_
  6. #include <stdint.h>
  7. #include "base/logging.h"
  8. #include "courgette/courgette_flow.h"
  9. #include "courgette/ensemble.h"
  10. #include "courgette/region.h"
  11. #include "courgette/streams.h"
  12. namespace courgette {
  13. // PatcherX86_32 is the universal patcher for all executables. The executable
  14. // type is determined by the program detector.
  15. class PatcherX86_32 : public TransformationPatcher {
  16. public:
  17. explicit PatcherX86_32(const Region& region)
  18. : ensemble_region_(region),
  19. base_offset_(0),
  20. base_length_(0) {
  21. }
  22. PatcherX86_32(const PatcherX86_32&) = delete;
  23. PatcherX86_32& operator=(const PatcherX86_32&) = delete;
  24. Status Init(SourceStream* parameter_stream) {
  25. if (!parameter_stream->ReadVarint32(&base_offset_))
  26. return C_BAD_TRANSFORM;
  27. if (!parameter_stream->ReadVarint32(&base_length_))
  28. return C_BAD_TRANSFORM;
  29. if (base_offset_ > ensemble_region_.length())
  30. return C_BAD_TRANSFORM;
  31. if (base_length_ > ensemble_region_.length() - base_offset_)
  32. return C_BAD_TRANSFORM;
  33. return C_OK;
  34. }
  35. Status PredictTransformParameters(SinkStreamSet* predicted_parameters) {
  36. // No code needed to write an 'empty' predicted parameter set.
  37. return C_OK;
  38. }
  39. Status Transform(SourceStreamSet* corrected_parameters,
  40. SinkStreamSet* transformed_element) {
  41. if (!corrected_parameters->Empty())
  42. return C_GENERAL_ERROR; // Don't expect any corrected parameters.
  43. CourgetteFlow flow;
  44. RegionBuffer only_buffer(
  45. Region(ensemble_region_.start() + base_offset_, base_length_));
  46. flow.ReadDisassemblerFromBuffer(flow.ONLY, only_buffer);
  47. flow.CreateAssemblyProgramFromDisassembler(flow.ONLY, false);
  48. flow.CreateEncodedProgramFromDisassemblerAndAssemblyProgram(flow.ONLY);
  49. flow.DestroyAssemblyProgram(flow.ONLY);
  50. flow.DestroyDisassembler(flow.ONLY);
  51. flow.WriteSinkStreamSetFromEncodedProgram(flow.ONLY, transformed_element);
  52. if (flow.failed())
  53. LOG(ERROR) << flow.message();
  54. return flow.status();
  55. }
  56. Status Reform(SourceStreamSet* transformed_element,
  57. SinkStream* reformed_element) {
  58. CourgetteFlow flow;
  59. flow.ReadEncodedProgramFromSourceStreamSet(flow.ONLY, transformed_element);
  60. flow.WriteExecutableFromEncodedProgram(flow.ONLY, reformed_element);
  61. if (flow.failed())
  62. LOG(ERROR) << flow.message();
  63. return flow.status();
  64. }
  65. private:
  66. Region ensemble_region_;
  67. uint32_t base_offset_;
  68. uint32_t base_length_;
  69. };
  70. } // namespace courgette
  71. #endif // COURGETTE_PATCHER_X86_32_H_