diff options
Diffstat (limited to 'courgette/ensemble.cc')
-rw-r--r-- | courgette/ensemble.cc | 99 |
1 files changed, 56 insertions, 43 deletions
diff --git a/courgette/ensemble.cc b/courgette/ensemble.cc index a2bea8f..69e07a7 100644 --- a/courgette/ensemble.cc +++ b/courgette/ensemble.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -14,15 +14,8 @@ namespace courgette { -Element::Element(ExecutableType kind, - Ensemble* ensemble, - const Region& region, - PEInfo* info) - : kind_(kind), ensemble_(ensemble), region_(region), info_(info) { -} - -Element::~Element() { - delete info_; +Element::Element(Kind kind, Ensemble* ensemble, const Region& region) + : kind_(kind), ensemble_(ensemble), region_(region) { } std::string Element::Name() const { @@ -32,51 +25,71 @@ std::string Element::Name() const { + base::Uint64ToString(region().length()) + ")"; } +// A subclass of Element that has a PEInfo. +class ElementWinPE : public Element { + public: + ElementWinPE(Kind kind, Ensemble* ensemble, const Region& region, + PEInfo* info) + : Element(kind, ensemble, region), + pe_info_(info) { + } + + virtual PEInfo* GetPEInfo() const { return pe_info_; } + + protected: + ~ElementWinPE() { delete pe_info_; } + + private: + PEInfo* pe_info_; // Owned by |this|. +}; + // Scans the Ensemble's region, sniffing out Elements. We assume that the // elements do not overlap. Status Ensemble::FindEmbeddedElements() { - size_t length = region_.length(); const uint8* start = region_.start(); size_t position = 0; while (position < length) { - ExecutableType type = DetectExecutableType(start + position, - length - position); - - // - // TODO(dgarrett) This switch can go away totally after two things. - // - // Make ImageInfo generic for all executable types. - // Find a generic way to handle length detection for executables. - // - // When this switch is gone, that's one less piece of code that is - // executable type aware. - // - switch (type) { - case UNKNOWN: { - // No Element found at current position. - ++position; - break; - } - case WIN32_X86: { - // The Info is only created to detect the length of the executable - courgette::PEInfo* info(new courgette::PEInfo()); - info->Init(start + position, length - position); - if (!info->ParseHeader()) { - delete info; - position++; - break; - } + // Quick test; Windows executables begin with 'MZ'. + if (start[position] == 'M' && + position + 1 < length && start[position + 1] == 'Z') { + courgette::PEInfo *info = new courgette::PEInfo(); + info->Init(start + position, length - position); + if (info->ParseHeader()) { Region region(start + position, info->length()); - Element* element = new Element(type, this, region, info); - owned_elements_.push_back(element); - elements_.push_back(element); - position += region.length(); - break; + if (info->has_text_section()) { + if (info->is_32bit()) { + Element* element = new ElementWinPE(Element::WIN32_X86_WITH_CODE, + this, region, info); + owned_elements_.push_back(element); + elements_.push_back(element); + position += region.length(); + continue; + } + // TODO(sra): Extend to 64-bit executables. + } + + // If we had a clever transformation for resource-only executables we + // should identify the suitable elements here: + if (!info->has_text_section() && false) { + Element* element = new ElementWinPE(Element::WIN32_NOCODE, + this, region, info); + owned_elements_.push_back(element); + elements_.push_back(element); + position += region.length(); + continue; + } } + delete info; } + + // This is where to add new formats, e.g. Linux executables, Dalvik + // executables etc. + + // No Element found at current position. + ++position; } return C_OK; } |