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
3 // found in the LICENSE file.
5 #include "courgette/disassembler.h"
11 #include "base/basictypes.h"
12 #include "base/logging.h"
14 #include "courgette/assembly_program.h"
15 #include "courgette/courgette.h"
16 #include "courgette/disassembler_elf_32_arm.h"
17 #include "courgette/disassembler_elf_32_x86.h"
18 #include "courgette/disassembler_win32_x64.h"
19 #include "courgette/disassembler_win32_x86.h"
20 #include "courgette/encoded_program.h"
24 ////////////////////////////////////////////////////////////////////////////////
26 Disassembler
* DetectDisassembler(const void* buffer
, size_t length
) {
27 Disassembler
* disassembler
= NULL
;
29 disassembler
= new DisassemblerWin32X86(buffer
, length
);
30 if (disassembler
->ParseHeader())
35 disassembler
= new DisassemblerWin32X64(buffer
, length
);
36 if (disassembler
->ParseHeader())
41 disassembler
= new DisassemblerElf32X86(buffer
, length
);
42 if (disassembler
->ParseHeader())
47 disassembler
= new DisassemblerElf32ARM(buffer
, length
);
48 if (disassembler
->ParseHeader())
56 Status
DetectExecutableType(const void* buffer
, size_t length
,
58 size_t* detected_length
) {
60 Disassembler
* disassembler
= DetectDisassembler(buffer
, length
);
63 *type
= disassembler
->kind();
64 *detected_length
= disassembler
->length();
69 // We failed to detect anything
72 return C_INPUT_NOT_RECOGNIZED
;
75 Status
ParseDetectedExecutable(const void* buffer
, size_t length
,
76 AssemblyProgram
** output
) {
79 Disassembler
* disassembler
= DetectDisassembler(buffer
, length
);
82 return C_INPUT_NOT_RECOGNIZED
;
85 AssemblyProgram
* program
= new AssemblyProgram(disassembler
->kind());
87 if (!disassembler
->Disassemble(program
)) {
90 return C_DISASSEMBLY_FAILED
;
98 void DeleteAssemblyProgram(AssemblyProgram
* program
) {
102 Disassembler::Disassembler(const void* start
, size_t length
)
103 : failure_reason_("uninitialized") {
105 start_
= reinterpret_cast<const uint8
*>(start
);
107 end_
= start_
+ length_
;
110 Disassembler::~Disassembler() {};
112 const uint8
* Disassembler::OffsetToPointer(size_t offset
) const {
113 assert(start_
+ offset
<= end_
);
114 return start_
+ offset
;
117 bool Disassembler::Good() {
118 failure_reason_
= NULL
;
122 bool Disassembler::Bad(const char* reason
) {
123 failure_reason_
= reason
;
127 void Disassembler::ReduceLength(size_t reduced_length
) {
128 CHECK_LE(reduced_length
, length_
);
129 length_
= reduced_length
;
130 end_
= start_
+ length_
;
133 } // namespace courgette