Home | History | Annotate | Download | only in courgette
      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