summaryrefslogtreecommitdiffstats
path: root/courgette/ensemble.cc
diff options
context:
space:
mode:
authordgarrett@chromium.org <dgarrett@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-10-04 13:43:25 +0000
committerdgarrett@chromium.org <dgarrett@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-10-04 13:43:25 +0000
commit14df9e63ee9497eaed402e00cd4f95bfd2630476 (patch)
tree8d5668dd3313119fc5b6ebf22a089c8559264969 /courgette/ensemble.cc
parent13daae6db93408e08e373f9ca911d371120cfab6 (diff)
downloadchromium_src-14df9e63ee9497eaed402e00cd4f95bfd2630476.zip
chromium_src-14df9e63ee9497eaed402e00cd4f95bfd2630476.tar.gz
chromium_src-14df9e63ee9497eaed402e00cd4f95bfd2630476.tar.bz2
Start refactoring to reduce executable type knowledge.
This creates executable detection functions, a globally shared enum for describing an executable type, and reduces the number of classes and locations with executable specific knowledge. These changes, along with moving architecture specific classes into their own files should make it easier to produce special purpose clients that only contain the code required to apply their own form of patch. DisassemblerWin32EXE, ImagePE, CourgetteWin32X86PatchGenerator, and CourgetteWin32X86Patcher, and ensemble handling are all heavily affected here. This should have no effect on the behavior of the system yet, and is instead all prep-work. BUG=None TEST=Unittests Review URL: http://codereview.chromium.org/7920004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@103879 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'courgette/ensemble.cc')
-rw-r--r--courgette/ensemble.cc99
1 files changed, 43 insertions, 56 deletions
diff --git a/courgette/ensemble.cc b/courgette/ensemble.cc
index 69e07a7..a2bea8f 100644
--- a/courgette/ensemble.cc
+++ b/courgette/ensemble.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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,8 +14,15 @@
namespace courgette {
-Element::Element(Kind kind, Ensemble* ensemble, const Region& region)
- : kind_(kind), ensemble_(ensemble), region_(region) {
+Element::Element(ExecutableType kind,
+ Ensemble* ensemble,
+ const Region& region,
+ PEInfo* info)
+ : kind_(kind), ensemble_(ensemble), region_(region), info_(info) {
+}
+
+Element::~Element() {
+ delete info_;
}
std::string Element::Name() const {
@@ -25,71 +32,51 @@ 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) {
- // 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());
-
- 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.
+ 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;
}
+ Region region(start + position, info->length());
- // 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;
- }
+ Element* element = new Element(type, this, region, info);
+ owned_elements_.push_back(element);
+ elements_.push_back(element);
+ position += region.length();
+ break;
}
- 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;
}