Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  WindowsDllBlocklist.cpp   Sprache: C

 
/* -*- Mode: C++; tab-width: 40; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */


#include <windows.h>
#include <winternl.h>

#pragma warning(push)
#pragma warning(disable : 4275 4530)  // See msvc-stl-wrapper.template.h
#include <map>
#pragma warning(pop)

#include "Authenticode.h"
#include "BaseProfiler.h"
#include "nsWindowsDllInterceptor.h"
#include "mozilla/CmdLineAndEnvUtils.h"
#include "mozilla/StackWalk_windows.h"
#include "mozilla/TimeStamp.h"
#include "mozilla/UniquePtr.h"
#include "mozilla/Vector.h"
#include "mozilla/WindowsProcessMitigations.h"
#include "mozilla/WindowsVersion.h"
#include "mozilla/WinHeaderOnlyUtils.h"
#include "nsWindowsHelpers.h"
#include "WindowsDllBlocklist.h"
#include "mozilla/AutoProfilerLabel.h"
#include "mozilla/glue/Debug.h"
#include "mozilla/glue/WindowsDllServices.h"
#include "mozilla/glue/WinUtils.h"

// Start new implementation
#include "LoaderObserver.h"
#include "ModuleLoadFrame.h"
#include "mozilla/glue/WindowsUnicode.h"

namespace mozilla {

glue::Win32SRWLock gDllServicesLock;
glue::detail::DllServicesBase* gDllServices;

}  // namespace mozilla

using namespace mozilla;

#define DLL_BLOCKLIST_ENTRY(name, ...) {name, __VA_ARGS__},
#define DLL_BLOCKLIST_STRING_TYPE const char*
#include "mozilla/WindowsDllBlocklistLegacyDefs.h"

// define this for very verbose dll load debug spew
#undef DEBUG_very_verbose

using WritableBuffer = mozilla::glue::detail::WritableBuffer<1024>;

static uint32_t sInitFlags;
static bool sBlocklistInitAttempted;
static bool sBlocklistInitFailed;
static bool sUser32BeforeBlocklist;
MOZ_RUNINIT static WritableBuffer sBlocklistWriter;

typedef MOZ_NORETURN_PTR void(__fastcall* BaseThreadInitThunk_func)(
    BOOL aIsInitialThread, void* aStartAddress, void* aThreadParam);
static WindowsDllInterceptor::FuncHookType<BaseThreadInitThunk_func>
    stub_BaseThreadInitThunk;

typedef NTSTATUS(NTAPI* LdrLoadDll_func)(PWCHAR filePath, PULONG flags,
                                         PUNICODE_STRING moduleFileName,
                                         PHANDLE handle);
static WindowsDllInterceptor::FuncHookType<LdrLoadDll_func> stub_LdrLoadDll;

template <class T>
struct RVAMap {
  RVAMap(HANDLE map, DWORD offset) {
    SYSTEM_INFO info;
    GetSystemInfo(&info);

    DWORD alignedOffset =
        (offset / info.dwAllocationGranularity) * info.dwAllocationGranularity;

    MOZ_ASSERT(offset - alignedOffset < info.dwAllocationGranularity, "Wtf");

    mRealView = ::MapViewOfFile(map, FILE_MAP_READ, 0, alignedOffset,
                                sizeof(T) + (offset - alignedOffset));

    mMappedView =
        mRealView
            ? reinterpret_cast<T*>((char*)mRealView + (offset - alignedOffset))
            : nullptr;
  }
  ~RVAMap() {
    if (mRealView) {
      ::UnmapViewOfFile(mRealView);
    }
  }
  operator const T*() const { return mMappedView; }
  const T* operator->() const { return mMappedView; }

 private:
  const T* mMappedView;
  void* mRealView;
};

static DWORD GetTimestamp(const wchar_t* path) {
  DWORD timestamp = 0;

  HANDLE file = ::CreateFileW(path, GENERIC_READ, FILE_SHARE_READ, nullptr,
                              OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr);
  if (file != INVALID_HANDLE_VALUE) {
    HANDLE map =
        ::CreateFileMappingW(file, nullptr, PAGE_READONLY, 0, 0, nullptr);
    if (map) {
      RVAMap<IMAGE_DOS_HEADER> peHeader(map, 0);
      if (peHeader) {
        RVAMap<IMAGE_NT_HEADERS> ntHeader(map, peHeader->e_lfanew);
        if (ntHeader) {
          timestamp = ntHeader->FileHeader.TimeDateStamp;
        }
      }
      ::CloseHandle(map);
    }
    ::CloseHandle(file);
  }

  return timestamp;
}

// This lock protects both the reentrancy sentinel and the crash reporter
// data structures.
static CRITICAL_SECTION sLock;

/**
 * Some versions of Windows call LoadLibraryEx to get the version information
 * for a DLL, which causes our patched LdrLoadDll implementation to re-enter
 * itself and cause infinite recursion and a stack-exhaustion crash. We protect
 * against reentrancy by allowing recursive loads of the same DLL.
 *
 * Note that we don't use __declspec(thread) because that doesn't work in DLLs
 * loaded via LoadLibrary and there can be a limited number of TLS slots, so
 * we roll our own.
 */

class ReentrancySentinel {
 public:
  explicit ReentrancySentinel(const char* dllName) {
    DWORD currentThreadId = GetCurrentThreadId();
    AutoCriticalSection lock(&sLock);
    mPreviousDllName = (*sThreadMap)[currentThreadId];

    // If there is a DLL currently being loaded and it has the same name
    // as the current attempt, we're re-entering.
    mReentered = mPreviousDllName && !stricmp(mPreviousDllName, dllName);
    (*sThreadMap)[currentThreadId] = dllName;
  }

  ~ReentrancySentinel() {
    DWORD currentThreadId = GetCurrentThreadId();
    AutoCriticalSection lock(&sLock);
    (*sThreadMap)[currentThreadId] = mPreviousDllName;
  }

  bool BailOut() const { return mReentered; };

  static void InitializeStatics() {
    InitializeCriticalSection(&sLock);
    sThreadMap = new std::map<DWORD, const char*>;
  }

 private:
  static std::map<DWORD, const char*>* sThreadMap;

  const char* mPreviousDllName;
  bool mReentered;
};

std::map<DWORD, const char*>* ReentrancySentinel::sThreadMap;

/**
 * This is a linked list of DLLs that have been blocked. It doesn't use
 * mozilla::LinkedList because this is an append-only list and doesn't need
 * to be doubly linked.
 */

class DllBlockSet {
 public:
  static void Add(const char* name, unsigned long long version);

  // Write the list of blocked DLLs to a WritableBuffer object. This method is
  // run after a crash occurs and must therefore not use the heap, etc.
  static void Write(WritableBuffer& buffer);

 private:
  DllBlockSet(const char* name, unsigned long long version)
      : mName(name), mVersion(version), mNext(nullptr) {}

  const char* mName;  // points into the gWindowsDllBlocklist string
  unsigned long long mVersion;
  DllBlockSet* mNext;

  static DllBlockSet* gFirst;
};

DllBlockSet* DllBlockSet::gFirst;

void DllBlockSet::Add(const char* name, unsigned long long version) {
  AutoCriticalSection lock(&sLock);
  for (DllBlockSet* b = gFirst; b; b = b->mNext) {
    if (0 == strcmp(b->mName, name) && b->mVersion == version) {
      return;
    }
  }
  // Not already present
  DllBlockSet* n = new DllBlockSet(name, version);
  n->mNext = gFirst;
  gFirst = n;
}

void DllBlockSet::Write(WritableBuffer& buffer) {
  // It would be nicer to use AutoCriticalSection here. However, its destructor
  // might not run if an exception occurs, in which case we would never leave
  // the critical section. (MSVC warns about this possibility.) So we
  // enter and leave manually.
  ::EnterCriticalSection(&sLock);

  // Because this method is called after a crash occurs, and uses heap memory,
  // protect this entire block with a structured exception handler.
  MOZ_SEH_TRY {
    for (DllBlockSet* b = gFirst; b; b = b->mNext) {
      // write name[,v.v.v.v];
      buffer.Write(b->mName, strlen(b->mName));
      if (b->mVersion != DllBlockInfo::ALL_VERSIONS) {
        buffer.Write(",", 1);
        uint16_t parts[4];
        parts[0] = b->mVersion >> 48;
        parts[1] = (b->mVersion >> 32) & 0xFFFF;
        parts[2] = (b->mVersion >> 16) & 0xFFFF;
        parts[3] = b->mVersion & 0xFFFF;
        for (int p = 0; p < 4; ++p) {
          char buf[32];
          _ltoa_s(parts[p], buf, sizeof(buf), 10);
          buffer.Write(buf, strlen(buf));
          if (p != 3) {
            buffer.Write(".", 1);
          }
        }
      }
      buffer.Write(";", 1);
    }
  }
  MOZ_SEH_EXCEPT(EXCEPTION_EXECUTE_HANDLER) {}

  ::LeaveCriticalSection(&sLock);
}

static UniquePtr<wchar_t[]> getFullPath(PWCHAR filePath, wchar_t* fname) {
  // In Windows 8, the first parameter seems to be used for more than just the
  // path name.  For example, its numerical value can be 1.  Passing a non-valid
  // pointer to SearchPathW will cause a crash, so we need to check to see if we
  // are handed a valid pointer, and otherwise just pass nullptr to SearchPathW.
  PWCHAR sanitizedFilePath = nullptr;
  if ((uintptr_t(filePath) >= 65536) && ((uintptr_t(filePath) & 1) == 0)) {
    sanitizedFilePath = filePath;
  }

  // figure out the length of the string that we need
  DWORD pathlen =
      SearchPathW(sanitizedFilePath, fname, L".dll", 0, nullptr, nullptr);
  if (pathlen == 0) {
    return nullptr;
  }

  auto full_fname = MakeUnique<wchar_t[]>(pathlen + 1);
  if (!full_fname) {
    // couldn't allocate memory?
    return nullptr;
  }

  // now actually grab it
  SearchPathW(sanitizedFilePath, fname, L".dll", pathlen + 1, full_fname.get(),
              nullptr);
  return full_fname;
}

// No builtin function to find the last character matching a set
static wchar_t* lastslash(wchar_t* s, int len) {
  for (wchar_t* c = s + len - 1; c >= s; --c) {
    if (*c == L'\\' || *c == L'/') {
      return c;
    }
  }
  return nullptr;
}

static bool ShouldBlockBasedOnBlockInfo(const DllBlockInfo& info,
                                        const char* dllName, PWCHAR filePath,
                                        wchar_t* fname,
                                        unsigned long long* fVersion) {
#ifdef DEBUG_very_verbose
  printf_stderr("LdrLoadDll: info->mName: '%s'\n", info->mName);
#endif

  if (info.mFlags & DllBlockInfoFlags::REDIRECT_TO_NOOP_ENTRYPOINT) {
    printf_stderr(
        "LdrLoadDll: "
        "Ignoring the REDIRECT_TO_NOOP_ENTRYPOINT flag\n");
  }

  if ((info.mFlags & DllBlockInfoFlags::CHILD_PROCESSES_ONLY) &&
      !(sInitFlags & eDllBlocklistInitFlagIsChildProcess)) {
    return false;
  }

  if ((info.mFlags & DllBlockInfoFlags::UTILITY_PROCESSES_ONLY) &&
      !(sInitFlags & eDllBlocklistInitFlagIsUtilityProcess)) {
    return false;
  }

  if ((info.mFlags & DllBlockInfoFlags::SOCKET_PROCESSES_ONLY) &&
      !(sInitFlags & eDllBlocklistInitFlagIsSocketProcess)) {
    return false;
  }

  if ((info.mFlags & DllBlockInfoFlags::GPU_PROCESSES_ONLY) &&
      !(sInitFlags & eDllBlocklistInitFlagIsGPUProcess)) {
    return false;
  }

  if ((info.mFlags & DllBlockInfoFlags::BROWSER_PROCESS_ONLY) &&
      (sInitFlags & eDllBlocklistInitFlagIsChildProcess)) {
    return false;
  }

  if ((info.mFlags & DllBlockInfoFlags::GMPLUGIN_PROCESSES_ONLY) &&
      !(sInitFlags & eDllBlocklistInitFlagIsGMPluginProcess)) {
    return false;
  }

  *fVersion = DllBlockInfo::ALL_VERSIONS;

  if (info.mMaxVersion != DllBlockInfo::ALL_VERSIONS) {
    ReentrancySentinel sentinel(dllName);
    if (sentinel.BailOut()) {
      return false;
    }

    UniquePtr<wchar_t[]> full_fname = getFullPath(filePath, fname);
    if (!full_fname) {
      // uh, we couldn't find the DLL at all, so...
      printf_stderr(
          "LdrLoadDll: Blocking load of '%s' (SearchPathW didn't find "
          "it?)\n",
          dllName);
      return true;
    }

    if (info.mFlags & DllBlockInfoFlags::USE_TIMESTAMP) {
      *fVersion = GetTimestamp(full_fname.get());
      if (*fVersion > info.mMaxVersion) {
        return false;
      }
    } else {
      LauncherResult<ModuleVersion> version =
          GetModuleVersion(full_fname.get());
      // If we failed to get the version information, we block.
      if (version.isOk()) {
        return info.IsVersionBlocked(version.unwrap());
      }
    }
  }
  // Falling through to here means we should block.
  return true;
}

struct CaseSensitiveStringComparator {
  explicit CaseSensitiveStringComparator(const char* aTarget)
      : mTarget(aTarget) {}

  int operator()(const DllBlockInfo& aVal) const {
    return strcmp(mTarget, aVal.mName);
  }

  const char* mTarget;
};

static NTSTATUS NTAPI patched_LdrLoadDll(PWCHAR filePath, PULONG flags,
                                         PUNICODE_STRING moduleFileName,
                                         PHANDLE handle) {
  // We have UCS2 (UTF16?), we want ASCII, but we also just want the filename
  // portion
#define DLLNAME_MAX 128
  char dllName[DLLNAME_MAX + 1];
  wchar_t* dll_part;
  char* dot;

  int len = moduleFileName->Length / 2;
  wchar_t* fname = moduleFileName->Buffer;

  // The filename isn't guaranteed to be null terminated, but in practice
  // it always will be; ensure that this is so, and bail if not.
  // This is done instead of the more robust approach because of bug 527122,
  // where lots of weird things were happening when we tried to make a copy.
  if (moduleFileName->MaximumLength < moduleFileName->Length + 2 ||
      fname[len] != 0) {
#ifdef DEBUG
    printf_stderr("LdrLoadDll: non-null terminated string found!\n");
#endif
    goto continue_loading;
  }

  dll_part = lastslash(fname, len);
  if (dll_part) {
    dll_part = dll_part + 1;
    len -= dll_part - fname;
  } else {
    dll_part = fname;
  }

#ifdef DEBUG_very_verbose
  printf_stderr("LdrLoadDll: dll_part '%S' %d\n", dll_part, len);
#endif

  // if it's too long, then, we assume we won't want to block it,
  // since DLLNAME_MAX should be at least long enough to hold the longest
  // entry in our blocklist.
  if (len > DLLNAME_MAX) {
#ifdef DEBUG
    printf_stderr("LdrLoadDll: len too long! %d\n", len);
#endif
    goto continue_loading;
  }

  // copy over to our char byte buffer, lowercasing ASCII as we go
  for (int i = 0; i < len; i++) {
    wchar_t c = dll_part[i];

    if (c > 0x7f) {
      // welp, it's not ascii; if we need to add non-ascii things to
      // our blocklist, we'll have to remove this limitation.
      goto continue_loading;
    }

    // ensure that dll name is all lowercase
    if (c >= 'A' && c <= 'Z') c += 'a' - 'A';

    dllName[i] = (char)c;
  }

  dllName[len] = 0;

#ifdef DEBUG_very_verbose
  printf_stderr("LdrLoadDll: dll name '%s'\n", dllName);
#endif

  if (!(sInitFlags & eDllBlocklistInitFlagWasBootstrapped)) {
    // Block a suspicious binary that uses various 12-digit hex strings
    // e.g. MovieMode.48CA2AEFA22D.dll (bug 973138)
    dot = strchr(dllName, '.');
    if (dot && (strchr(dot + 1, '.') == dot + 13)) {
      char* end = nullptr;
      _strtoui64(dot + 1, &end, 16);
      if (end == dot + 13) {
        return STATUS_DLL_NOT_FOUND;
      }
    }
    // Block binaries where the filename is at least 16 hex digits
    if (dot && ((dot - dllName) >= 16)) {
      char* current = dllName;
      while (current < dot && isxdigit(*current)) {
        current++;
      }
      if (current == dot) {
        return STATUS_DLL_NOT_FOUND;
      }
    }

    // then compare to everything on the blocklist
    DECLARE_POINTER_TO_FIRST_DLL_BLOCKLIST_ENTRY(info);
    DECLARE_DLL_BLOCKLIST_NUM_ENTRIES(infoNumEntries);
    CaseSensitiveStringComparator comp(dllName);
    size_t match = LowerBound(info, 0, infoNumEntries, comp);
    if (match != infoNumEntries) {
      // There may be multiple entries on the list. Since LowerBound() returns
      // the first entry that matches (if there are any matches),
      // search forward from there.
      while (match < infoNumEntries && (comp(info[match]) == 0)) {
        unsigned long long fVersion;
        if (ShouldBlockBasedOnBlockInfo(info[match], dllName, filePath, fname,
                                        &fVersion)) {
          printf_stderr(
              "LdrLoadDll: Blocking load of '%s' -- see "
              "http://www.mozilla.com/en-US/blocklist/\n",
              dllName);
          DllBlockSet::Add(info[match].mName, fVersion);
          return STATUS_DLL_NOT_FOUND;
        }
        ++match;
      }
    }
  }

continue_loading:
#ifdef DEBUG_very_verbose
  printf_stderr("LdrLoadDll: continuing load... ('%S')\n",
                moduleFileName->Buffer);
#endif

  glue::ModuleLoadFrame loadFrame(moduleFileName);

  NTSTATUS ret;
  HANDLE myHandle;

  ret = stub_LdrLoadDll(filePath, flags, moduleFileName, &myHandle);

  if (handle) {
    *handle = myHandle;
  }

  loadFrame.SetLoadStatus(ret, myHandle);

  return ret;
}

#if defined(BLOCK_LOADLIBRARY_INJECTION)
// Map of specific thread proc addresses we should block. In particular,
// LoadLibrary* APIs which indicate DLL injection
static void* gStartAddressesToBlock[4];
#endif  // defined(BLOCK_LOADLIBRARY_INJECTION)

static bool ShouldBlockThread(void* aStartAddress) {
  // Allows crashfirefox.exe to continue to work. Also if your threadproc is
  // null, this crash is intentional.
  if (aStartAddress == nullptr) {
    return false;
  }

#if defined(BLOCK_LOADLIBRARY_INJECTION)
  for (auto p : gStartAddressesToBlock) {
    if (p == aStartAddress) {
      return true;
    }
  }
#endif

  bool shouldBlock = false;
  MEMORY_BASIC_INFORMATION startAddressInfo = {0};
  if (VirtualQuery(aStartAddress, &startAddressInfo,
                   sizeof(startAddressInfo))) {
    shouldBlock |= startAddressInfo.State != MEM_COMMIT;
    shouldBlock |= startAddressInfo.Protect != PAGE_EXECUTE_READ;
  }

  return shouldBlock;
}

// Allows blocked threads to still run normally through BaseThreadInitThunk, in
// case there's any magic there that we shouldn't skip.
static DWORD WINAPI NopThreadProc(void/* aThreadParam */) { return 0; }

static MOZ_NORETURN void __fastcall patched_BaseThreadInitThunk(
    BOOL aIsInitialThread, void* aStartAddress, void* aThreadParam) {
  if (ShouldBlockThread(aStartAddress)) {
    aStartAddress = (void*)NopThreadProc;
  }

  stub_BaseThreadInitThunk(aIsInitialThread, aStartAddress, aThreadParam);
}

MOZ_RUNINIT static WindowsDllInterceptor NtDllIntercept;
MOZ_RUNINIT static WindowsDllInterceptor Kernel32Intercept;

static void GetNativeNtBlockSetWriter();

static glue::LoaderObserver gMozglueLoaderObserver;
MOZ_RUNINIT static nt::WinLauncherServices gWinLauncher;

MFBT_API void DllBlocklist_Initialize(uint32_t aInitFlags) {
  if (sBlocklistInitAttempted) {
    return;
  }
  sBlocklistInitAttempted = true;

  sInitFlags = aInitFlags;

  glue::ModuleLoadFrame::StaticInit(&gMozglueLoaderObserver, &gWinLauncher);

  // Bug 1361410: WRusr.dll will overwrite our hook and cause a crash.
  // Workaround: If we detect WRusr.dll, don't hook.
  if (!GetModuleHandleW(L"WRusr.dll")) {
    Kernel32Intercept.Init(L"kernel32.dll");
    if (!stub_BaseThreadInitThunk.SetDetour(Kernel32Intercept,
                                            "BaseThreadInitThunk",
                                            &patched_BaseThreadInitThunk)) {
#ifdef DEBUG
      printf_stderr("BaseThreadInitThunk hook failed\n");
#endif
    }
  }

#if defined(BLOCK_LOADLIBRARY_INJECTION)
  // Populate a list of thread start addresses to block.
  HMODULE hKernel = GetModuleHandleW(L"kernel32.dll");
  if (hKernel) {
    void* pProc;

    pProc = (void*)GetProcAddress(hKernel, "LoadLibraryA");
    gStartAddressesToBlock[0] = pProc;

    pProc = (void*)GetProcAddress(hKernel, "LoadLibraryW");
    gStartAddressesToBlock[1] = pProc;

    pProc = (void*)GetProcAddress(hKernel, "LoadLibraryExA");
    gStartAddressesToBlock[2] = pProc;

    pProc = (void*)GetProcAddress(hKernel, "LoadLibraryExW");
    gStartAddressesToBlock[3] = pProc;
  }
#endif

  if (aInitFlags & eDllBlocklistInitFlagWasBootstrapped) {
    GetNativeNtBlockSetWriter();
    return;
  }

  // There are a couple of exceptional cases where we skip user32.dll check.
  // - If the the process was bootstrapped by the launcher process, AppInit
  //   DLLs will be intercepted by the new DllBlockList.  No need to check
  //   here.
  // - The code to initialize the base profiler loads winmm.dll which
  //   statically links user32.dll on an older Windows.  This means if the base
  //   profiler is active before coming here, we cannot fully intercept AppInit
  //   DLLs.  Given that the base profiler is used outside the typical use
  //   cases, it's ok not to check user32.dll in this scenario.
  const bool skipUser32Check =
      (sInitFlags & eDllBlocklistInitFlagWasBootstrapped) ||
      (!IsWin10AnniversaryUpdateOrLater() &&
       baseprofiler::profiler_is_active());

  // In order to be effective against AppInit DLLs, the blocklist must be
  // initialized before user32.dll is loaded into the process (bug 932100).
  if (!skipUser32Check && GetModuleHandleW(L"user32.dll")) {
    sUser32BeforeBlocklist = true;
#ifdef DEBUG
    printf_stderr("DLL blocklist was unable to intercept AppInit DLLs.\n");
#endif
  }

  NtDllIntercept.Init("ntdll.dll");

  ReentrancySentinel::InitializeStatics();

  // We specifically use a detour, because there are cases where external
  // code also tries to hook LdrLoadDll, and doesn't know how to relocate our
  // nop space patches. (Bug 951827)
  bool ok = stub_LdrLoadDll.SetDetour(NtDllIntercept, "LdrLoadDll",
                                      &patched_LdrLoadDll);

  if (!ok) {
    sBlocklistInitFailed = true;
#ifdef DEBUG
    printf_stderr("LdrLoadDll hook failed, no dll blocklisting active\n");
#endif
  }

  // If someone injects a thread early that causes user32.dll to load off the
  // main thread this causes issues, so load it as soon as we've initialized
  // the block-list. (See bug 1400637)
  if (!sUser32BeforeBlocklist && !IsWin32kLockedDown()) {
    ::LoadLibraryW(L"user32.dll");
  }
}

#ifdef DEBUG
MFBT_API void DllBlocklist_Shutdown() {}
#endif  // DEBUG

static void InternalWriteNotes(WritableBuffer& aBuffer) {
  DllBlockSet::Write(aBuffer);
}

using WriterFn = void (*)(WritableBuffer& aBuffer);
static WriterFn gWriterFn = &InternalWriteNotes;

static void GetNativeNtBlockSetWriter() {
  auto nativeWriter = reinterpret_cast<WriterFn>(
      ::GetProcAddress(::GetModuleHandleW(nullptr), "NativeNtBlockSet_Write"));
  if (nativeWriter) {
    gWriterFn = nativeWriter;
  }
}

MFBT_API void DllBlocklist_WriteNotes() { gWriterFn(sBlocklistWriter); }

MFBT_API bool DllBlocklist_CheckStatus() {
  if (sBlocklistInitFailed || sUser32BeforeBlocklist) return false;
  return true;
}

MFBT_API bool* DllBlocklist_GetBlocklistInitFailedPointer() {
  return &sBlocklistInitFailed;
}

MFBT_API bool* DllBlocklist_GetUser32BeforeBlocklistPointer() {
  return &sUser32BeforeBlocklist;
}

MFBT_API const char* DllBlocklist_GetBlocklistWriterData() {
  return sBlocklistWriter.Data();
}

// ============================================================================
// This section is for DLL Services
// ============================================================================

namespace mozilla {
Authenticode* GetAuthenticode();
}  // namespace mozilla

/**
 * Please note that DllBlocklist_SetFullDllServices is called with
 * aSvc = nullptr to de-initialize the resources even though they
 * have been initialized via DllBlocklist_SetBasicDllServices.
 */

MFBT_API void DllBlocklist_SetFullDllServices(
    mozilla::glue::detail::DllServicesBase* aSvc) {
  glue::AutoExclusiveLock lock(gDllServicesLock);
  if (aSvc) {
    aSvc->SetAuthenticodeImpl(GetAuthenticode());
    aSvc->SetWinLauncherServices(gWinLauncher);
    gMozglueLoaderObserver.Forward(aSvc);
  }

  gDllServices = aSvc;
}

MFBT_API void DllBlocklist_SetBasicDllServices(
    mozilla::glue::detail::DllServicesBase* aSvc) {
  if (!aSvc) {
    return;
  }

  aSvc->SetAuthenticodeImpl(GetAuthenticode());
  gMozglueLoaderObserver.Disable();
}

Messung V0.5
C=94 H=93 G=93

¤ Dauer der Verarbeitung: 0.7 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge