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 5 // This is the transformation for Windows X86 executables. 6 // The same patcher can be used for Windows X64 executables. 7 8 #ifndef COURGETTE_WIN32_X86_PATCHER_H_ 9 #define COURGETTE_WIN32_X86_PATCHER_H_ 10 11 #include "courgette/ensemble.h" 12 13 namespace courgette { 14 15 // Courgette32X86Patcher is a TransformationPatcher for Windows 32-bit 16 // and 64-bit executables. We can use the same patcher for both. 17 // 18 class PatcherX86_32 : public TransformationPatcher { 19 public: 20 explicit PatcherX86_32(const Region& region) 21 : ensemble_region_(region), 22 base_offset_(0), 23 base_length_(0) { 24 } 25 26 Status Init(SourceStream* parameter_stream) { 27 if (!parameter_stream->ReadVarint32(&base_offset_)) 28 return C_BAD_TRANSFORM; 29 if (!parameter_stream->ReadVarint32(&base_length_)) 30 return C_BAD_TRANSFORM; 31 32 if (base_offset_ > ensemble_region_.length()) 33 return C_BAD_TRANSFORM; 34 if (base_length_ > ensemble_region_.length() - base_offset_) 35 return C_BAD_TRANSFORM; 36 37 return C_OK; 38 } 39 40 Status PredictTransformParameters(SinkStreamSet* predicted_parameters) { 41 // No code needed to write an 'empty' predicted parameter set. 42 return C_OK; 43 } 44 45 Status Transform(SourceStreamSet* corrected_parameters, 46 SinkStreamSet* transformed_element) { 47 Status status; 48 if (!corrected_parameters->Empty()) 49 return C_GENERAL_ERROR; // Don't expect any corrected parameters. 50 51 AssemblyProgram* program = NULL; 52 status = ParseDetectedExecutable(ensemble_region_.start() + base_offset_, 53 base_length_, 54 &program); 55 if (status != C_OK) 56 return status; 57 58 // Trim labels below a certain threshold 59 Status trim_status = TrimLabels(program); 60 if (trim_status != C_OK) { 61 DeleteAssemblyProgram(program); 62 return trim_status; 63 } 64 65 EncodedProgram* encoded = NULL; 66 status = Encode(program, &encoded); 67 DeleteAssemblyProgram(program); 68 if (status != C_OK) 69 return status; 70 71 status = WriteEncodedProgram(encoded, transformed_element); 72 DeleteEncodedProgram(encoded); 73 74 return status; 75 } 76 77 Status Reform(SourceStreamSet* transformed_element, 78 SinkStream* reformed_element) { 79 Status status; 80 EncodedProgram* encoded_program = NULL; 81 status = ReadEncodedProgram(transformed_element, &encoded_program); 82 if (status != C_OK) 83 return status; 84 85 status = Assemble(encoded_program, reformed_element); 86 DeleteEncodedProgram(encoded_program); 87 if (status != C_OK) 88 return status; 89 90 return C_OK; 91 } 92 93 private: 94 Region ensemble_region_; 95 96 uint32 base_offset_; 97 uint32 base_length_; 98 99 DISALLOW_COPY_AND_ASSIGN(PatcherX86_32); 100 }; 101 102 } // namespace 103 #endif // COURGETTE_WIN32_X86_PATCHER_H_ 104