// Copyright 2017 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 "components/zucchini/element_detection.h"

#include <utility>

#include "base/logging.h"
#include "components/zucchini/buildflags.h"
#include "components/zucchini/disassembler.h"
#include "components/zucchini/disassembler_no_op.h"

#if BUILDFLAG(ENABLE_DEX)
#include "components/zucchini/disassembler_dex.h"
#endif  // BUILDFLAG(ENABLE_DEX)

#if BUILDFLAG(ENABLE_WIN)
#include "components/zucchini/disassembler_win32.h"
#endif  // BUILDFLAG(ENABLE_WIN)

#if BUILDFLAG(ENABLE_ELF)
#include "components/zucchini/disassembler_elf.h"
#endif  // BUILDFLAG(ENABLE_ELF)

#if BUILDFLAG(ENABLE_ZTF)
#include "components/zucchini/disassembler_ztf.h"
#endif  // BUILDFLAG(ENABLE_ZTF)

namespace zucchini {

namespace {

// Impose a minimal program size to eliminate pathological cases.
enum : size_t { kMinProgramSize = 16 };

}  // namespace

/******** Utility Functions ********/

std::unique_ptr<Disassembler> MakeDisassemblerWithoutFallback(
    ConstBufferView image) {
#if BUILDFLAG(ENABLE_WIN)
  if (DisassemblerWin32X86::QuickDetect(image)) {
    auto disasm = Disassembler::Make<DisassemblerWin32X86>(image);
    if (disasm && disasm->size() >= kMinProgramSize)
      return disasm;
  }

  if (DisassemblerWin32X64::QuickDetect(image)) {
    auto disasm = Disassembler::Make<DisassemblerWin32X64>(image);
    if (disasm && disasm->size() >= kMinProgramSize)
      return disasm;
  }
#endif  // BUILDFLAG(ENABLE_WIN)

#if BUILDFLAG(ENABLE_ELF)
  if (DisassemblerElfX86::QuickDetect(image)) {
    auto disasm = Disassembler::Make<DisassemblerElfX86>(image);
    if (disasm && disasm->size() >= kMinProgramSize)
      return disasm;
  }

  if (DisassemblerElfX64::QuickDetect(image)) {
    auto disasm = Disassembler::Make<DisassemblerElfX64>(image);
    if (disasm && disasm->size() >= kMinProgramSize)
      return disasm;
  }
#endif  // BUILDFLAG(ENABLE_ELF)

#if BUILDFLAG(ENABLE_DEX)
  if (DisassemblerDex::QuickDetect(image)) {
    auto disasm = Disassembler::Make<DisassemblerDex>(image);
    if (disasm && disasm->size() >= kMinProgramSize)
      return disasm;
  }
#endif  // BUILDFLAG(ENABLE_DEX)

#if BUILDFLAG(ENABLE_ZTF)
  if (DisassemblerZtf::QuickDetect(image)) {
    // This disallows very short examples like "ZTxtxtZ\n" in ensemble patching.
    auto disasm = Disassembler::Make<DisassemblerZtf>(image);
    if (disasm && disasm->size() >= kMinProgramSize)
      return disasm;
  }
#endif  // BUILDFLAG(ENABLE_ZTF)

  return nullptr;
}

std::unique_ptr<Disassembler> MakeDisassemblerOfType(ConstBufferView image,
                                                     ExecutableType exe_type) {
  switch (exe_type) {
#if BUILDFLAG(ENABLE_WIN)
    case kExeTypeWin32X86:
      return Disassembler::Make<DisassemblerWin32X86>(image);
    case kExeTypeWin32X64:
      return Disassembler::Make<DisassemblerWin32X64>(image);
#endif  // BUILDFLAG(ENABLE_WIN)
#if BUILDFLAG(ENABLE_ELF)
    case kExeTypeElfX86:
      return Disassembler::Make<DisassemblerElfX86>(image);
    case kExeTypeElfX64:
      return Disassembler::Make<DisassemblerElfX64>(image);
#endif  // BUILDFLAG(ENABLE_ELF)
#if BUILDFLAG(ENABLE_DEX)
    case kExeTypeDex:
      return Disassembler::Make<DisassemblerDex>(image);
#endif  // BUILDFLAG(ENABLE_DEX)
#if BUILDFLAG(ENABLE_ZTF)
    case kExeTypeZtf:
      return Disassembler::Make<DisassemblerZtf>(image);
#endif  // BUILDFLAG(ENABLE_ZTF)
    case kExeTypeNoOp:
      return Disassembler::Make<DisassemblerNoOp>(image);
    default:
      // If an architecture is disabled then null is handled gracefully.
      return nullptr;
  }
}

base::Optional<Element> DetectElementFromDisassembler(ConstBufferView image) {
  std::unique_ptr<Disassembler> disasm = MakeDisassemblerWithoutFallback(image);
  if (disasm)
    return Element({0, disasm->size()}, disasm->GetExeType());
  return base::nullopt;
}

/******** ProgramScanner ********/

ElementFinder::ElementFinder(ConstBufferView image, ElementDetector&& detector)
    : image_(image), detector_(std::move(detector)) {}

ElementFinder::~ElementFinder() = default;

base::Optional<Element> ElementFinder::GetNext() {
  for (; pos_ < image_.size(); ++pos_) {
    ConstBufferView test_image =
        ConstBufferView::FromRange(image_.begin() + pos_, image_.end());
    base::Optional<Element> element = detector_.Run(test_image);
    if (element) {
      element->offset += pos_;
      pos_ = element->EndOffset();
      return element;
    }
  }
  return base::nullopt;
}

}  // namespace zucchini
