// Copyright 2013 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 "chrome_elf/blacklist/blacklist.h"

#include <assert.h>
#include <string.h>

#include <vector>

#include "base/basictypes.h"
#include "chrome_elf/blacklist/blacklist_interceptions.h"
#include "chrome_elf/chrome_elf_constants.h"
#include "chrome_elf/chrome_elf_util.h"
#include "chrome_elf/thunk_getter.h"
#include "sandbox/win/src/interception_internal.h"
#include "sandbox/win/src/internal_types.h"
#include "sandbox/win/src/service_resolver.h"

// http://blogs.msdn.com/oldnewthing/archive/2004/10/25/247180.aspx
extern "C" IMAGE_DOS_HEADER __ImageBase;

namespace blacklist{

// The DLLs listed here are known (or under strong suspicion) of causing crashes
// when they are loaded in the browser. DLLs should only be added to this list
// if there is nothing else Chrome can do to prevent those crashes.
// For more information about how this list is generated, and how to get off
// of it, see:
// https://sites.google.com/a/chromium.org/dev/Home/third-party-developers
// NOTE: Please remember to update the DllHash enum in histograms.xml when
//       adding a new value to the blacklist.
const wchar_t* g_troublesome_dlls[kTroublesomeDllsMaxCount] = {
  L"949ba8b6a9.dll",                    // Coupon Time.
  L"activedetect32.dll",                // Lenovo One Key Theater.
                                        // See crbug.com/379218.
  L"activedetect64.dll",                // Lenovo One Key Theater.
  L"bitguard.dll",                      // Unknown (suspected malware).
  L"bsvc.dll",                          // Unknown (suspected adware).
  L"chrmxtn.dll",                       // Unknown (keystroke logger).
  L"cplushook.dll",                     // Unknown (suspected malware).
  L"crdli.dll",                         // Linkury Inc.
  L"crdli64.dll",                       // Linkury Inc.
  L"datamngr.dll",                      // Unknown (suspected adware).
  L"dpinterface32.dll",                 // Unknown (suspected adware).
  L"explorerex.dll",                    // Unknown (suspected adware).
  L"hk.dll",                            // Unknown (keystroke logger).
  L"libapi2hook.dll",                   // V-Bates.
  L"libinject.dll",                     // V-Bates.
  L"libinject2.dll",                    // V-Bates.
  L"libredir2.dll",                     // V-Bates.
  L"libsvn_tsvn32.dll",                 // TortoiseSVN.
  L"libwinhook.dll",                    // V-Bates.
  L"lmrn.dll",                          // Unknown.
  L"minisp.dll",                        // Unknown (suspected malware).
  L"minisp32.dll",                      // Unknown (suspected malware).
  L"offerswizarddll.dll",               // Unknown (suspected adware).
  L"safetynut.dll",                     // Unknown (suspected adware).
  L"smdmf.dll",                         // Unknown (suspected adware).
  L"spappsv32.dll",                     // Unknown (suspected adware).
  L"systemk.dll",                       // Unknown (suspected adware).
  L"vntsrv.dll",                        // Virtual New Tab by APN LLC.
  L"wajam_goblin_64.dll",               // Wajam Internet Technologies.
  L"wajam_goblin.dll",                  // Wajam Internet Technologies.
  L"windowsapihookdll32.dll",           // Lenovo One Key Theater.
                                        // See crbug.com/379218.
  L"windowsapihookdll64.dll",           // Lenovo One Key Theater.
  L"virtualcamera.ax",                  // %PROGRAMFILES%\ASUS\VirtualCamera.
                                        // See crbug.com/422522.
  L"ycwebcamerasource.ax",              // CyberLink Youcam, crbug.com/424159
  // Keep this null pointer here to mark the end of the list.
  NULL,
};

bool g_blocked_dlls[kTroublesomeDllsMaxCount] = {};
int g_num_blocked_dlls = 0;

}  // namespace blacklist

// Allocate storage for thunks in a page of this module to save on doing
// an extra allocation at run time.
#pragma section(".crthunk",read,execute)
__declspec(allocate(".crthunk")) sandbox::ThunkData g_thunk_storage;

namespace {

// Record if the blacklist was successfully initialized so processes can easily
// determine if the blacklist is enabled for them.
bool g_blacklist_initialized = false;

// Helper to set DWORD registry values.
DWORD SetDWValue(HKEY* key, const wchar_t* property, DWORD value) {
  return ::RegSetValueEx(*key,
                         property,
                         0,
                         REG_DWORD,
                         reinterpret_cast<LPBYTE>(&value),
                         sizeof(value));
}

bool GenerateStateFromBeaconAndAttemptCount(HKEY* key, DWORD blacklist_state) {
  LONG result = 0;
  if (blacklist_state == blacklist::BLACKLIST_ENABLED) {
    // If the blacklist succeeded on the previous run reset the failure
    // counter.
    return (SetDWValue(key,
                       blacklist::kBeaconAttemptCount,
                       static_cast<DWORD>(0)) == ERROR_SUCCESS);
  } else {
    // Some part of the blacklist setup failed last time.  If this has occured
    // blacklist::kBeaconMaxAttempts times in a row we switch the state to
    // failed and skip setting up the blacklist.
    DWORD attempt_count = 0;
    DWORD attempt_count_size = sizeof(attempt_count);
    result = ::RegQueryValueEx(*key,
                               blacklist::kBeaconAttemptCount,
                               0,
                               NULL,
                               reinterpret_cast<LPBYTE>(&attempt_count),
                               &attempt_count_size);

    if (result == ERROR_FILE_NOT_FOUND)
      attempt_count = 0;
    else if (result != ERROR_SUCCESS)
      return false;

    ++attempt_count;
    SetDWValue(key, blacklist::kBeaconAttemptCount, attempt_count);

    if (attempt_count >= blacklist::kBeaconMaxAttempts) {
      blacklist_state = blacklist::BLACKLIST_SETUP_FAILED;
      SetDWValue(key, blacklist::kBeaconState, blacklist_state);
    }

    return false;
  }
}

}  // namespace

namespace blacklist {

#if defined(_WIN64)
  // Allocate storage for the pointer to the old NtMapViewOfSectionFunction.
#pragma section(".oldntmap",write,read)
  __declspec(allocate(".oldntmap"))
    NtMapViewOfSectionFunction g_nt_map_view_of_section_func = NULL;
#endif

bool LeaveSetupBeacon() {
  HKEY key = NULL;
  DWORD disposition = 0;
  LONG result = ::RegCreateKeyEx(HKEY_CURRENT_USER,
                                 kRegistryBeaconPath,
                                 0,
                                 NULL,
                                 REG_OPTION_NON_VOLATILE,
                                 KEY_QUERY_VALUE | KEY_SET_VALUE,
                                 NULL,
                                 &key,
                                 &disposition);
  if (result != ERROR_SUCCESS)
    return false;

  // Retrieve the current blacklist state.
  DWORD blacklist_state = BLACKLIST_STATE_MAX;
  DWORD blacklist_state_size = sizeof(blacklist_state);
  DWORD type = 0;
  result = ::RegQueryValueEx(key,
                             kBeaconState,
                             0,
                             &type,
                             reinterpret_cast<LPBYTE>(&blacklist_state),
                             &blacklist_state_size);

  if (result != ERROR_SUCCESS || blacklist_state == BLACKLIST_DISABLED ||
      type != REG_DWORD) {
    ::RegCloseKey(key);
    return false;
  }

  if (!GenerateStateFromBeaconAndAttemptCount(&key, blacklist_state)) {
    ::RegCloseKey(key);
    return false;
  }

  result = SetDWValue(&key, kBeaconState, BLACKLIST_SETUP_RUNNING);
  ::RegCloseKey(key);

  return (result == ERROR_SUCCESS);
}

bool ResetBeacon() {
  HKEY key = NULL;
  DWORD disposition = 0;
  LONG result = ::RegCreateKeyEx(HKEY_CURRENT_USER,
                                 kRegistryBeaconPath,
                                 0,
                                 NULL,
                                 REG_OPTION_NON_VOLATILE,
                                 KEY_QUERY_VALUE | KEY_SET_VALUE,
                                 NULL,
                                 &key,
                                 &disposition);
  if (result != ERROR_SUCCESS)
    return false;

  DWORD blacklist_state = BLACKLIST_STATE_MAX;
  DWORD blacklist_state_size = sizeof(blacklist_state);
  DWORD type = 0;
  result = ::RegQueryValueEx(key,
                             kBeaconState,
                             0,
                             &type,
                             reinterpret_cast<LPBYTE>(&blacklist_state),
                             &blacklist_state_size);

  if (result != ERROR_SUCCESS || type != REG_DWORD) {
    ::RegCloseKey(key);
    return false;
  }

  // Reaching this point with the setup running state means the setup did not
  // crash, so we reset to enabled.  Any other state indicates that setup was
  // skipped; in that case we leave the state alone for later recording.
  if (blacklist_state == BLACKLIST_SETUP_RUNNING)
    result = SetDWValue(&key, kBeaconState, BLACKLIST_ENABLED);

  ::RegCloseKey(key);
  return (result == ERROR_SUCCESS);
}

int BlacklistSize() {
  int size = -1;
  while (blacklist::g_troublesome_dlls[++size] != NULL) {}

  return size;
}

bool IsBlacklistInitialized() {
  return g_blacklist_initialized;
}

int GetBlacklistIndex(const wchar_t* dll_name) {
  for (int i = 0; i < kTroublesomeDllsMaxCount && g_troublesome_dlls[i]; ++i) {
    if (_wcsicmp(dll_name, g_troublesome_dlls[i]) == 0)
      return i;
  }
  return -1;
}

bool AddDllToBlacklist(const wchar_t* dll_name) {
  int blacklist_size = BlacklistSize();
  // We need to leave one space at the end for the null pointer.
  if (blacklist_size + 1 >= kTroublesomeDllsMaxCount)
    return false;
  for (int i = 0; i < blacklist_size; ++i) {
    if (!_wcsicmp(g_troublesome_dlls[i], dll_name))
      return true;
  }

  // Copy string to blacklist.
  wchar_t* str_buffer = new wchar_t[wcslen(dll_name) + 1];
  wcscpy(str_buffer, dll_name);

  g_troublesome_dlls[blacklist_size] = str_buffer;
  g_blocked_dlls[blacklist_size] = false;
  return true;
}

bool RemoveDllFromBlacklist(const wchar_t* dll_name) {
  int blacklist_size = BlacklistSize();
  for (int i = 0; i < blacklist_size; ++i) {
    if (!_wcsicmp(g_troublesome_dlls[i], dll_name)) {
      // Found the thing to remove. Delete it then replace it with the last
      // element.
      delete[] g_troublesome_dlls[i];
      g_troublesome_dlls[i] = g_troublesome_dlls[blacklist_size - 1];
      g_troublesome_dlls[blacklist_size - 1] = NULL;

      // Also update the stats recording if we have blocked this dll or not.
      if (g_blocked_dlls[i])
        --g_num_blocked_dlls;
      g_blocked_dlls[i] = g_blocked_dlls[blacklist_size - 1];
      return true;
    }
  }
  return false;
}

// TODO(csharp): Maybe store these values in the registry so we can
// still report them if Chrome crashes early.
void SuccessfullyBlocked(const wchar_t** blocked_dlls, int* size) {
  if (size == NULL)
    return;

  // If the array isn't valid or big enough, just report the size it needs to
  // be and return.
  if (blocked_dlls == NULL && *size < g_num_blocked_dlls) {
    *size = g_num_blocked_dlls;
    return;
  }

  *size = g_num_blocked_dlls;

  int strings_to_fill = 0;
  for (int i = 0; strings_to_fill < g_num_blocked_dlls && g_troublesome_dlls[i];
       ++i) {
    if (g_blocked_dlls[i]) {
      blocked_dlls[strings_to_fill] = g_troublesome_dlls[i];
      ++strings_to_fill;
    }
  }
}

void BlockedDll(size_t blocked_index) {
  assert(blocked_index < kTroublesomeDllsMaxCount);

  if (!g_blocked_dlls[blocked_index] &&
      blocked_index < kTroublesomeDllsMaxCount) {
    ++g_num_blocked_dlls;
    g_blocked_dlls[blocked_index] = true;
  }
}

bool Initialize(bool force) {
  // Check to see that we found the functions we need in ntdll.
  if (!InitializeInterceptImports())
    return false;

  // Check to see if this is a non-browser process, abort if so.
  if (IsNonBrowserProcess())
    return false;

  // Check to see if the blacklist beacon is still set to running (indicating a
  // failure) or disabled, and abort if so.
  if (!force && !LeaveSetupBeacon())
    return false;

  // It is possible for other dlls to have already patched code by now and
  // attempting to patch their code might result in crashes.
  const bool kRelaxed = false;

  // Create a thunk via the appropriate ServiceResolver instance.
  sandbox::ServiceResolverThunk* thunk = GetThunk(kRelaxed);

  // Don't try blacklisting on unsupported OS versions.
  if (!thunk)
    return false;

  BYTE* thunk_storage = reinterpret_cast<BYTE*>(&g_thunk_storage);

  // Mark the thunk storage as readable and writeable, since we
  // ready to write to it.
  DWORD old_protect = 0;
  if (!VirtualProtect(&g_thunk_storage,
                      sizeof(g_thunk_storage),
                      PAGE_EXECUTE_READWRITE,
                      &old_protect)) {
    return false;
  }

  thunk->AllowLocalPatches();

  // We declare this early so it can be used in the 64-bit block below and
  // still work on 32-bit build when referenced at the end of the function.
  BOOL page_executable = false;

  // Replace the default NtMapViewOfSection with our patched version.
#if defined(_WIN64)
  NTSTATUS ret = thunk->Setup(::GetModuleHandle(sandbox::kNtdllName),
                              reinterpret_cast<void*>(&__ImageBase),
                              "NtMapViewOfSection",
                              NULL,
                              &blacklist::BlNtMapViewOfSection64,
                              thunk_storage,
                              sizeof(sandbox::ThunkData),
                              NULL);

  // Keep a pointer to the original code, we don't have enough space to
  // add it directly to the call.
  g_nt_map_view_of_section_func = reinterpret_cast<NtMapViewOfSectionFunction>(
      thunk_storage);

  // Ensure that the pointer to the old function can't be changed.
 page_executable = VirtualProtect(&g_nt_map_view_of_section_func,
                                  sizeof(g_nt_map_view_of_section_func),
                                  PAGE_EXECUTE_READ,
                                  &old_protect);
#else
  NTSTATUS ret = thunk->Setup(::GetModuleHandle(sandbox::kNtdllName),
                              reinterpret_cast<void*>(&__ImageBase),
                              "NtMapViewOfSection",
                              NULL,
                              &blacklist::BlNtMapViewOfSection,
                              thunk_storage,
                              sizeof(sandbox::ThunkData),
                              NULL);
#endif
  delete thunk;

  // Record if we have initialized the blacklist.
  g_blacklist_initialized = NT_SUCCESS(ret);

  // Mark the thunk storage as executable and prevent any future writes to it.
  page_executable = page_executable && VirtualProtect(&g_thunk_storage,
                                                      sizeof(g_thunk_storage),
                                                      PAGE_EXECUTE_READ,
                                                      &old_protect);

  AddDllsFromRegistryToBlacklist();

  return NT_SUCCESS(ret) && page_executable;
}

void AddDllsFromRegistryToBlacklist() {
  HKEY key = NULL;
  LONG result = ::RegOpenKeyEx(HKEY_CURRENT_USER,
                               kRegistryFinchListPath,
                               0,
                               KEY_QUERY_VALUE | KEY_SET_VALUE,
                               &key);

  if (result != ERROR_SUCCESS)
    return;

  // We add dlls from the registry to the blacklist.
  DWORD value_len;
  DWORD name_len = MAX_PATH;
  std::vector<wchar_t> name_buffer(name_len);
  for (int i = 0; result == ERROR_SUCCESS; ++i) {
    name_len = MAX_PATH;
    value_len = 0;
    result = ::RegEnumValue(
        key, i, &name_buffer[0], &name_len, NULL, NULL, NULL, &value_len);
    if (result != ERROR_SUCCESS)
      break;

    name_len = name_len + 1;
    value_len = value_len + 1;
    std::vector<wchar_t> value_buffer(value_len);
    result = ::RegEnumValue(key, i, &name_buffer[0], &name_len, NULL, NULL,
                            reinterpret_cast<BYTE*>(&value_buffer[0]),
                            &value_len);
    if (result != ERROR_SUCCESS)
      break;
    value_buffer[value_len - 1] = L'\0';
    AddDllToBlacklist(&value_buffer[0]);
  }

  ::RegCloseKey(key);
  return;
}

}  // namespace blacklist
