Index: courgette/program_detector.cc |
diff --git a/courgette/program_detector.cc b/courgette/program_detector.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..4dde3e425af2246e5830ffe4ddaacbfadedd80cf |
--- /dev/null |
+++ b/courgette/program_detector.cc |
@@ -0,0 +1,85 @@ |
+// Copyright 2016 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. |
+ |
+#include "courgette/program_detector.h" |
+ |
+#include <utility> |
+ |
+#include "courgette/assembly_program.h" |
+#include "courgette/disassembler.h" |
+#include "courgette/disassembler_elf_32_arm.h" |
+#include "courgette/disassembler_elf_32_x86.h" |
+#include "courgette/disassembler_win32_x64.h" |
+#include "courgette/disassembler_win32_x86.h" |
+ |
+namespace courgette { |
+ |
+namespace { |
+ |
+// Returns a new instance of Disassembler subclass if binary data given in |
+// |buffer| and |length| matches a known binary format, otherwise null. |
+scoped_ptr<Disassembler> DetectDisassembler(const void* buffer, size_t length) { |
+ scoped_ptr<Disassembler> disassembler; |
+ |
+ disassembler.reset(new DisassemblerWin32X86(buffer, length)); |
+ if (disassembler->ParseHeader()) |
+ return disassembler; |
+ |
+ disassembler.reset(new DisassemblerWin32X64(buffer, length)); |
+ if (disassembler->ParseHeader()) |
+ return disassembler; |
+ |
+ disassembler.reset(new DisassemblerElf32X86(buffer, length)); |
+ if (disassembler->ParseHeader()) |
+ return disassembler; |
+ |
+ disassembler.reset(new DisassemblerElf32ARM(buffer, length)); |
+ if (disassembler->ParseHeader()) |
+ return disassembler; |
+ |
+ return nullptr; |
+} |
+ |
+} // namespace |
+ |
+Status DetectExecutableType(const void* buffer, |
+ size_t length, |
+ ExecutableType* type, |
+ size_t* detected_length) { |
+ scoped_ptr<Disassembler> disassembler(DetectDisassembler(buffer, length)); |
+ |
+ if (!disassembler) { // We failed to detect anything. |
+ *type = EXE_UNKNOWN; |
+ *detected_length = 0; |
+ return C_INPUT_NOT_RECOGNIZED; |
+ } |
+ |
+ *type = disassembler->kind(); |
+ *detected_length = disassembler->length(); |
+ return C_OK; |
+} |
+ |
+Status ParseDetectedExecutable(const void* buffer, |
+ size_t length, |
+ scoped_ptr<AssemblyProgram>* output) { |
+ output->reset(nullptr); |
+ |
+ scoped_ptr<Disassembler> disassembler(DetectDisassembler(buffer, length)); |
+ if (!disassembler) |
+ return C_INPUT_NOT_RECOGNIZED; |
+ |
+ scoped_ptr<AssemblyProgram> program( |
+ new AssemblyProgram(disassembler->kind())); |
+ |
+ if (!disassembler->Disassemble(program.get())) |
+ return C_DISASSEMBLY_FAILED; |
+ |
+ if (!program->TrimLabels()) |
+ return C_TRIM_FAILED; |
+ |
+ *output = std::move(program); |
+ return C_OK; |
+} |
+ |
+} // namespace courgette |