📄 verifier.c
字号:
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// This source code is licensed under Microsoft Shared Source License
// Version 1.0 for Windows CE.
// For a copy of the license visit http://go.microsoft.com/fwlink/?LinkId=3223.
//
//------------------------------------------------------------------------------
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
//------------------------------------------------------------------------------
//
// Module Name:
//
// verifier.c
//
// Abstract:
//
// Implements the shim engine.
//
//------------------------------------------------------------------------------
#include <kernel.h>
#include "altimports.h"
DBGPARAM dpCurSettings = { TEXT("ShimEngine"), {
TEXT("Entry"), TEXT("Entry2"), TEXT("Search"), TEXT("NotifyList"),
TEXT("<unused>"), TEXT("<unused>"), TEXT("<unused>"), TEXT("<unused>"),
TEXT("<unused>"), TEXT("<unused>"), TEXT("<unused>"), TEXT("<unused>"),
TEXT("<unused>"), TEXT("<unused>"), TEXT("<unused>"), TEXT("<unused>") },
0x00000000};
#undef ZONE_ENTRY
#define ZONE_ENTRY DEBUGZONE(0)
#define ZONE_ENTRY2 DEBUGZONE(1)
#define ZONE_SEARCH DEBUGZONE(2)
#define ZONE_NOTIFYLIST DEBUGZONE(3)
//------------------------------------------------------------------------------
// Globals
// Inputs from kernel
VerifierImportTable g_Imports;
CRITICAL_SECTION llcs;
BOOL g_fInit;
BOOL g_fLoadingShim;
BOOL g_fUnLoadingShim;
HINSTANCE gDllInstance;
HANDLE hCoreDll;
LPDWORD pIsExiting;
//------------------------------------------------------------------------------
//
BOOL
IsShimDll(
PMODULE pMod
);
BOOL
GetNameFromE32(
e32_lite *eptr,
LPWSTR lpszModuleName,
DWORD cchModuleName,
PMODULE *ppModule
);
typedef struct _SHIMINFO {
WORD wPool;
WORD wPad;
PMODULE pMod;
LPTSTR pszName;
struct _SHIMINFO *pNext;
} SHIMINFO, *LPSHIMINFO;
LPSHIMINFO
FindShimInfo(
LPSHIMINFO pShimInfo,
LPTSTR szShimName
);
typedef struct _SHIMREF {
LPSHIMINFO pShimInfo [MAX_PROCESSES];
} SHIMREF, *LPSHIMREF;
ERRFALSE(sizeof(SHIMREF) <= sizeof(MUTEX));
#define HEAP_SHIMREF HEAP_MUTEX
#define BASE_SHIM _T("shim_verifier.dll")
#define BASE_SHIM_LEN 17
//------------------------------------------------------------------------------
// Somewhat more abstracted input interface (yuck)
#define WIN32CALL(Api, Args) ((g_Imports.pWin32Methods[W32_ ## Api]) Args)
#undef RegOpenKeyEx
#define RegOpenKeyEx (g_Imports.pExtraMethods[13])
#undef RegQueryValueEx
#define RegQueryValueEx (g_Imports.pExtraMethods[14])
#undef RegCloseKey
#define RegCloseKey (g_Imports.pExtraMethods[23])
#undef KData
#define KData (*(g_Imports.pKData))
#ifndef SHIP_BUILD
#undef RETAILMSG
#define RETAILMSG(cond, printf_exp) ((cond)?(g_Imports.NKDbgPrintfW printf_exp),1:0)
#endif // SHIP_BUILD
#ifdef DEBUG
#undef DEBUGMSG
#define DEBUGMSG RETAILMSG
#endif // DEBUG
#ifdef DEBUG
#undef DBGCHK
#undef DEBUGCHK
#define DBGCHK(module,exp) \
((void)((exp)?1 \
:(g_Imports.NKDbgPrintfW(TEXT("%s: DEBUGCHK failed in file %s at line %d\r\n"), \
(LPWSTR)module, TEXT(__FILE__), __LINE__), \
DebugBreak(), \
0 \
)))
#define DEBUGCHK(exp) DBGCHK(dpCurSettings.lpszName, exp)
#endif // DEBUG
#define LOG(x) RETAILMSG(1, (_T("%s = 0x%x\n"), _T(#x), x))
#define VLOG_DLL_NAME _T("vlog.dll")
#define VLOG_DLL_NAME_LEN 8
#define MAX_DLLNAME_LEN 32
#define EXE_BASE_ADDR 0x00010000
// CRT string manipulation function pointers
size_t (*vrf_wcslen)(const wchar_t *wcs);
wchar_t *(*vrf_wcscpy)(wchar_t *strDest, const wchar_t *strSource);
wchar_t *(*vrf_wcsncpy)(wchar_t *strDest, const wchar_t *strSource, size_t count);
wchar_t (*vrf_tolower)(wchar_t c);
int (*vrf_wcsnicmp)(const wchar_t *psz1, const wchar_t *psz2, size_t cb);
int (*vrf_wcsicmp)(const wchar_t *str1, const wchar_t*str2);
BOOL IsFilesysReady (void)
{
// Can only check the local registry if the filesys API is registered.
return (UserKInfo[KINX_API_MASK] & (1 << SH_FILESYS_APIS)) != 0;
}
PMODULE LoadShim (LPCTSTR pszShim)
{
PMODULE pModRet;
g_fLoadingShim = TRUE;
pModRet = (PMODULE) g_Imports.LoadOneLibraryW (pszShim, 0, 0);
g_fLoadingShim = FALSE;
return pModRet;
}
BOOL AddShimToList (LPCTSTR pszShim, PMODULE pModShim, PMODULE pModOwner)
{
LPSHIMINFO pShimInfo;
LPName lpName;
lpName = (LPName) g_Imports.AllocName (sizeof (SHIMINFO) + (vrf_wcslen (pszShim) + 1) * sizeof (TCHAR));
if (!lpName) {
DEBUGCHK (0);
return FALSE;
}
// Fill in the structure (use the name field)
pShimInfo = (LPSHIMINFO) lpName;
pShimInfo->wPool = lpName->wPool;
pShimInfo->wPad = 0;
pShimInfo->pMod = pModShim;
pShimInfo->pszName = (LPTSTR)(pShimInfo + 1);
vrf_wcscpy (pShimInfo->pszName, pszShim);
// Link in this new SHIMINFO structure
if (pModOwner) {
// This is a dll
pShimInfo->pNext = ((LPSHIMREF)pModOwner->pShimInfo)->pShimInfo [pCurProc->procnum];
((LPSHIMREF)pModOwner->pShimInfo)->pShimInfo [pCurProc->procnum] = pShimInfo;
}
else {
// This is an exe
pShimInfo->pNext = pCurProc->pShimInfo;
pCurProc->pShimInfo = pShimInfo;
}
return TRUE;
}
LPSHIMINFO FindShimInfo (LPSHIMINFO pShimInfo, LPTSTR szShimName)
{
// Walk the list of shims loaded by this image (dll or exe), and see if the
// desired shim is already loaded.
for (; pShimInfo; pShimInfo = pShimInfo->pNext) {
if (!vrf_wcsicmp (pShimInfo->pszName, szShimName)) {
DEBUGCHK (pShimInfo->pMod && IsShimDll (pShimInfo->pMod));
return pShimInfo;
}
}
return NULL;
}
HKEY OpenShimKey (LPTSTR pszSettingName, BOOL fIsProcess)
{
PTCHAR p;
PTCHAR pszSettingNameBare;
TCHAR szKeyName [MAX_PATH] = { TEXT("ShimEngine\\") };
size_t cchKeyName;
LONG lRet;
HKEY hKey = NULL;
// Fix up the setting name, if needed. It must have an extension.
if (vrf_wcsicmp (pszSettingName, _T("{all}"))) {
// Strip off path
for (p = pszSettingNameBare = pszSettingName; *p; p++) {
if ((*p == _T('\\')) || (*p == _T('/')))
pszSettingNameBare = p + 1;
}
vrf_wcscpy (szKeyName + 11, pszSettingNameBare);
cchKeyName = vrf_wcslen (szKeyName);
if (szKeyName [cchKeyName - 4] != _T('.')) {
// There's no extension - append one
vrf_wcscpy (szKeyName + cchKeyName, fIsProcess ? _T(".exe") : _T(".dll"));
}
}
else {
vrf_wcscpy (szKeyName + 11, pszSettingName);
}
lRet = RegOpenKeyEx (HKEY_LOCAL_MACHINE, szKeyName, 0, 0, & hKey);
DEBUGMSG (ZONE_SEARCH, (_T("Opening reg key '%s' --> 0x%08x\r\n"), szKeyName, hKey));
return (ERROR_SUCCESS == lRet) ? hKey : NULL;
}
BOOL ShouldShimLoadedModules (HKEY hKey)
{
DWORD cbData;
LONG lRet;
DWORD dwType;
BOOL fShimModules = FALSE;
cbData = sizeof (BOOL);
lRet = RegQueryValueEx (hKey, TEXT("ShimModules"), 0, & dwType, & fShimModules, & cbData);
// Does the registry specify whether to shim modules?
if (ERROR_SUCCESS == lRet) {
DEBUGMSG(ZONE_SEARCH, (TEXT("This process (%s) does %sallow shimming loaded modules.\r\n"),
pCurProc->lpszProcName, fShimModules ? _T("") : _T("not ")));
}
return fShimModules;
}
BOOL
IsShimBinary(
LPCTSTR szModuleName
)
{
TCHAR Buffer [MAX_PATH];
if (WIN32CALL(LoadStringW, (hCurProc, 1, Buffer, MAX_PATH))) {
if (0 == vrf_wcsicmp (Buffer, _T("AppVerifier"))) {
return TRUE;
}
}
return FALSE;
}
BOOL ShouldShimThisModuleROM (LPMODULE pMod, LPCTSTR szModuleName)
{
DEBUGMSG(1, (TEXT("++ShouldHookFromThisModuleROM (0x%08x, %s)\r\n"), pMod, szModuleName));
// TODO
return FALSE;
}
BOOL ShouldShimThisModule (LPMODULE pMod, LPTSTR szModuleName)
{
HKEY hKey = 0;
BOOL fShouldHook = FALSE;
DEBUGMSG(ZONE_ENTRY, (TEXT("++ShouldHookFromThisModule (0x%08x, %s)\r\n"), pMod, szModuleName));
if (g_fLoadingShim)
return FALSE;
// Don't alter a shim's imports
if (pMod && IsShimDll (pMod)) {
DEBUGMSG(1, (TEXT("Dynamically loading shim dll '%s'\r\n"), szModuleName));
return FALSE;
}
else if (!pMod && IsShimBinary (szModuleName)) {
DEBUGMSG (1, (TEXT("Not shimming app verifier binaries\r\n")));
return FALSE;
}
if (!IsFilesysReady ()) {
// We can't use the registry, look for a .ini file in ROM
return ShouldShimThisModuleROM (pMod, szModuleName);
}
// First, check {all}
if (hKey = OpenShimKey (_T("{all}"), TRUE)) {
fShouldHook = TRUE;
}
// Then, check szModuleName
else if (hKey = OpenShimKey (szModuleName, pMod ? FALSE : TRUE)) {
fShouldHook = TRUE;
}
// Finally, check the current process and ShimModules, if this is a dll
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -