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 | |
24 namespace courgette { | 7 namespace courgette { |
25 | 8 |
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 | |
102 Disassembler::Disassembler(const void* start, size_t length) | 9 Disassembler::Disassembler(const void* start, size_t length) |
103 : failure_reason_("uninitialized") { | 10 : failure_reason_("uninitialized") { |
104 start_ = reinterpret_cast<const uint8_t*>(start); | 11 start_ = reinterpret_cast<const uint8_t*>(start); |
105 length_ = length; | 12 length_ = length; |
106 end_ = start_ + length_; | 13 end_ = start_ + length_; |
107 }; | 14 }; |
108 | 15 |
109 Disassembler::~Disassembler() {}; | 16 Disassembler::~Disassembler() {}; |
110 | 17 |
111 const uint8_t* Disassembler::OffsetToPointer(size_t offset) const { | 18 const uint8_t* Disassembler::OffsetToPointer(size_t offset) const { |
(...skipping 11 matching lines...) Expand all Loading... |
123 return false; | 30 return false; |
124 } | 31 } |
125 | 32 |
126 void Disassembler::ReduceLength(size_t reduced_length) { | 33 void Disassembler::ReduceLength(size_t reduced_length) { |
127 CHECK_LE(reduced_length, length_); | 34 CHECK_LE(reduced_length, length_); |
128 length_ = reduced_length; | 35 length_ = reduced_length; |
129 end_ = start_ + length_; | 36 end_ = start_ + length_; |
130 } | 37 } |
131 | 38 |
132 } // namespace courgette | 39 } // namespace courgette |
OLD | NEW |