OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "courgette/disassembler.h" | 5 #include "courgette/disassembler.h" |
6 | 6 |
| 7 #include <stddef.h> |
| 8 #include <stdint.h> |
| 9 |
| 10 #include <algorithm> |
| 11 #include <string> |
| 12 #include <vector> |
| 13 |
| 14 #include "base/logging.h" |
| 15 #include "base/memory/scoped_ptr.h" |
| 16 #include "courgette/assembly_program.h" |
| 17 #include "courgette/courgette.h" |
| 18 #include "courgette/disassembler_elf_32_arm.h" |
| 19 #include "courgette/disassembler_elf_32_x86.h" |
| 20 #include "courgette/disassembler_win32_x64.h" |
| 21 #include "courgette/disassembler_win32_x86.h" |
| 22 #include "courgette/encoded_program.h" |
| 23 |
7 namespace courgette { | 24 namespace courgette { |
8 | 25 |
| 26 //////////////////////////////////////////////////////////////////////////////// |
| 27 |
| 28 Disassembler* DetectDisassembler(const void* buffer, size_t length) { |
| 29 Disassembler* disassembler = NULL; |
| 30 |
| 31 disassembler = new DisassemblerWin32X86(buffer, length); |
| 32 if (disassembler->ParseHeader()) |
| 33 return disassembler; |
| 34 else |
| 35 delete disassembler; |
| 36 |
| 37 disassembler = new DisassemblerWin32X64(buffer, length); |
| 38 if (disassembler->ParseHeader()) |
| 39 return disassembler; |
| 40 else |
| 41 delete disassembler; |
| 42 |
| 43 disassembler = new DisassemblerElf32X86(buffer, length); |
| 44 if (disassembler->ParseHeader()) |
| 45 return disassembler; |
| 46 else |
| 47 delete disassembler; |
| 48 |
| 49 disassembler = new DisassemblerElf32ARM(buffer, length); |
| 50 if (disassembler->ParseHeader()) |
| 51 return disassembler; |
| 52 else |
| 53 delete disassembler; |
| 54 |
| 55 return NULL; |
| 56 } |
| 57 |
| 58 Status DetectExecutableType(const void* buffer, size_t length, |
| 59 ExecutableType* type, |
| 60 size_t* detected_length) { |
| 61 |
| 62 Disassembler* disassembler = DetectDisassembler(buffer, length); |
| 63 |
| 64 if (disassembler) { |
| 65 *type = disassembler->kind(); |
| 66 *detected_length = disassembler->length(); |
| 67 delete disassembler; |
| 68 return C_OK; |
| 69 } |
| 70 |
| 71 // We failed to detect anything |
| 72 *type = EXE_UNKNOWN; |
| 73 *detected_length = 0; |
| 74 return C_INPUT_NOT_RECOGNIZED; |
| 75 } |
| 76 |
| 77 Status ParseDetectedExecutable(const void* buffer, size_t length, |
| 78 AssemblyProgram** output) { |
| 79 *output = nullptr; |
| 80 |
| 81 scoped_ptr<Disassembler> disassembler(DetectDisassembler(buffer, length)); |
| 82 if (!disassembler) |
| 83 return C_INPUT_NOT_RECOGNIZED; |
| 84 |
| 85 scoped_ptr<AssemblyProgram> program( |
| 86 new AssemblyProgram(disassembler->kind())); |
| 87 |
| 88 if (!disassembler->Disassemble(program.get())) |
| 89 return C_DISASSEMBLY_FAILED; |
| 90 |
| 91 if (!program->TrimLabels()) |
| 92 return C_TRIM_FAILED; |
| 93 |
| 94 *output = program.release(); |
| 95 return C_OK; |
| 96 } |
| 97 |
| 98 void DeleteAssemblyProgram(AssemblyProgram* program) { |
| 99 delete program; |
| 100 } |
| 101 |
9 Disassembler::Disassembler(const void* start, size_t length) | 102 Disassembler::Disassembler(const void* start, size_t length) |
10 : failure_reason_("uninitialized") { | 103 : failure_reason_("uninitialized") { |
11 start_ = reinterpret_cast<const uint8_t*>(start); | 104 start_ = reinterpret_cast<const uint8_t*>(start); |
12 length_ = length; | 105 length_ = length; |
13 end_ = start_ + length_; | 106 end_ = start_ + length_; |
14 }; | 107 }; |
15 | 108 |
16 Disassembler::~Disassembler() {}; | 109 Disassembler::~Disassembler() {}; |
17 | 110 |
18 const uint8_t* Disassembler::OffsetToPointer(size_t offset) const { | 111 const uint8_t* Disassembler::OffsetToPointer(size_t offset) const { |
(...skipping 11 matching lines...) Expand all Loading... |
30 return false; | 123 return false; |
31 } | 124 } |
32 | 125 |
33 void Disassembler::ReduceLength(size_t reduced_length) { | 126 void Disassembler::ReduceLength(size_t reduced_length) { |
34 CHECK_LE(reduced_length, length_); | 127 CHECK_LE(reduced_length, length_); |
35 length_ = reduced_length; | 128 length_ = reduced_length; |
36 end_ = start_ + length_; | 129 end_ = start_ + length_; |
37 } | 130 } |
38 | 131 |
39 } // namespace courgette | 132 } // namespace courgette |
OLD | NEW |