| Index: courgette/disassembler.cc
|
| diff --git a/courgette/disassembler.cc b/courgette/disassembler.cc
|
| index b9fce8bdc0efc7d01bc4a1864738378430ef45b3..568114c52701816720816b785a74786c66967625 100644
|
| --- a/courgette/disassembler.cc
|
| +++ b/courgette/disassembler.cc
|
| @@ -4,7 +4,100 @@
|
|
|
| #include "courgette/disassembler.h"
|
|
|
| +#include <stddef.h>
|
| +#include <stdint.h>
|
| +
|
| +#include <algorithm>
|
| +#include <string>
|
| +#include <vector>
|
| +
|
| +#include "base/logging.h"
|
| +#include "base/memory/scoped_ptr.h"
|
| +#include "courgette/assembly_program.h"
|
| +#include "courgette/courgette.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"
|
| +#include "courgette/encoded_program.h"
|
| +
|
| namespace courgette {
|
| +
|
| +////////////////////////////////////////////////////////////////////////////////
|
| +
|
| +Disassembler* DetectDisassembler(const void* buffer, size_t length) {
|
| + Disassembler* disassembler = NULL;
|
| +
|
| + disassembler = new DisassemblerWin32X86(buffer, length);
|
| + if (disassembler->ParseHeader())
|
| + return disassembler;
|
| + else
|
| + delete disassembler;
|
| +
|
| + disassembler = new DisassemblerWin32X64(buffer, length);
|
| + if (disassembler->ParseHeader())
|
| + return disassembler;
|
| + else
|
| + delete disassembler;
|
| +
|
| + disassembler = new DisassemblerElf32X86(buffer, length);
|
| + if (disassembler->ParseHeader())
|
| + return disassembler;
|
| + else
|
| + delete disassembler;
|
| +
|
| + disassembler = new DisassemblerElf32ARM(buffer, length);
|
| + if (disassembler->ParseHeader())
|
| + return disassembler;
|
| + else
|
| + delete disassembler;
|
| +
|
| + return NULL;
|
| +}
|
| +
|
| +Status DetectExecutableType(const void* buffer, size_t length,
|
| + ExecutableType* type,
|
| + size_t* detected_length) {
|
| +
|
| + Disassembler* disassembler = DetectDisassembler(buffer, length);
|
| +
|
| + if (disassembler) {
|
| + *type = disassembler->kind();
|
| + *detected_length = disassembler->length();
|
| + delete disassembler;
|
| + return C_OK;
|
| + }
|
| +
|
| + // We failed to detect anything
|
| + *type = EXE_UNKNOWN;
|
| + *detected_length = 0;
|
| + return C_INPUT_NOT_RECOGNIZED;
|
| +}
|
| +
|
| +Status ParseDetectedExecutable(const void* buffer, size_t length,
|
| + AssemblyProgram** output) {
|
| + *output = 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 = program.release();
|
| + return C_OK;
|
| +}
|
| +
|
| +void DeleteAssemblyProgram(AssemblyProgram* program) {
|
| + delete program;
|
| +}
|
|
|
| Disassembler::Disassembler(const void* start, size_t length)
|
| : failure_reason_("uninitialized") {
|
|
|