windows-nt/Source/XPSP1/NT/windows/appcompat/shims/verifier/securitychecks.cpp
2020-09-26 16:20:57 +08:00

1477 lines
50 KiB
C++

/*++
Copyright (c) 2001 Microsoft Corporation
Module Name:
SecurityChecks.cpp
Abstract:
This AppVerifier shim hooks CreateProcess, CreateProcessAsUser,
and WinExec and checks to see if some conditions exist that
might allow trojan horse behavior to occur.
Notes:
This is a general purpose shim.
History:
12/13/2001 rparsons Created
--*/
#include "precomp.h"
IMPLEMENT_SHIM_BEGIN(SecurityChecks)
#include "ShimHookMacro.h"
//
// verifier log entries
//
BEGIN_DEFINE_VERIFIER_LOG(SecurityChecks)
VERIFIER_LOG_ENTRY(VLOG_SECURITYCHECKS_BADARGUMENTS)
VERIFIER_LOG_ENTRY(VLOG_SECURITYCHECKS_WINEXEC)
VERIFIER_LOG_ENTRY(VLOG_SECURITYCHECKS_NULL_DACL)
VERIFIER_LOG_ENTRY(VLOG_SECURITYCHECKS_WORLDWRITE_DACL)
END_DEFINE_VERIFIER_LOG(SecurityChecks)
INIT_VERIFIER_LOG(SecurityChecks);
APIHOOK_ENUM_BEGIN
APIHOOK_ENUM_ENTRY(CreateProcessA)
APIHOOK_ENUM_ENTRY(CreateProcessW)
APIHOOK_ENUM_ENTRY(CreateProcessAsUserA)
APIHOOK_ENUM_ENTRY(CreateProcessAsUserW)
APIHOOK_ENUM_ENTRY(WinExec)
APIHOOK_ENUM_ENTRY(CreateFileA)
APIHOOK_ENUM_ENTRY(CreateFileW)
APIHOOK_ENUM_ENTRY(CreateDesktopA)
APIHOOK_ENUM_ENTRY(CreateDesktopW)
APIHOOK_ENUM_ENTRY(CreateWindowStationA)
APIHOOK_ENUM_ENTRY(CreateWindowStationW)
APIHOOK_ENUM_ENTRY(RegCreateKeyExA)
APIHOOK_ENUM_ENTRY(RegCreateKeyExW)
APIHOOK_ENUM_ENTRY(RegSaveKeyA)
APIHOOK_ENUM_ENTRY(RegSaveKeyW)
APIHOOK_ENUM_ENTRY(RegSaveKeyExA)
APIHOOK_ENUM_ENTRY(RegSaveKeyExW)
APIHOOK_ENUM_ENTRY(CreateFileMappingA)
APIHOOK_ENUM_ENTRY(CreateFileMappingW)
APIHOOK_ENUM_ENTRY(CreateJobObjectA)
APIHOOK_ENUM_ENTRY(CreateJobObjectW)
APIHOOK_ENUM_ENTRY(CreateThread)
APIHOOK_ENUM_ENTRY(CreateRemoteThread)
APIHOOK_ENUM_ENTRY(CreateDirectoryA)
APIHOOK_ENUM_ENTRY(CreateDirectoryW)
APIHOOK_ENUM_ENTRY(CreateDirectoryExA)
APIHOOK_ENUM_ENTRY(CreateDirectoryExW)
APIHOOK_ENUM_ENTRY(CreateHardLinkA)
APIHOOK_ENUM_ENTRY(CreateHardLinkW)
APIHOOK_ENUM_ENTRY(CreateMailslotA)
APIHOOK_ENUM_ENTRY(CreateMailslotW)
APIHOOK_ENUM_ENTRY(CreateNamedPipeA)
APIHOOK_ENUM_ENTRY(CreateNamedPipeW)
APIHOOK_ENUM_ENTRY(CreatePipe)
APIHOOK_ENUM_ENTRY(CreateMutexA)
APIHOOK_ENUM_ENTRY(CreateMutexW)
APIHOOK_ENUM_ENTRY(CreateSemaphoreA)
APIHOOK_ENUM_ENTRY(CreateSemaphoreW)
APIHOOK_ENUM_ENTRY(CreateWaitableTimerA)
APIHOOK_ENUM_ENTRY(CreateWaitableTimerW)
//APIHOOK_ENUM_ENTRY(ClusterRegCreateKey)
//APIHOOK_ENUM_ENTRY(CreateNtmsMediaPoolA)
//APIHOOK_ENUM_ENTRY(CreateNtmsMediaPoolW)
APIHOOK_ENUM_END
BYTE g_ajSidBuffer[SECURITY_MAX_SID_SIZE];
PSID g_pWorldSid = NULL;
WCHAR g_wszWinDir[MAX_PATH];
DWORD g_dwWinDirLen = 0;
void
InitWorldSid(
void
)
{
DWORD dwSidSize = sizeof(g_ajSidBuffer);
if (CreateWellKnownSid(WinWorldSid, NULL, g_ajSidBuffer, &dwSidSize)) {
g_pWorldSid = g_ajSidBuffer;
} else {
g_pWorldSid = NULL;
}
}
void
CheckSecurityDescriptor(
PSECURITY_DESCRIPTOR pSecurityDescriptor,
LPCWSTR szCaller,
LPCWSTR szParam,
LPCWSTR szName
)
{
BOOL bDaclPresent = FALSE;
BOOL bDaclDefaulted = FALSE;
PACL pDacl = NULL;
if (!pSecurityDescriptor || !szName || !szName[0]) {
//
// there's no attributes, so they get the default, which is fine,
// or the object doesn't have a name, so it can't be highjacked
//
return;
}
if (GetSecurityDescriptorDacl(pSecurityDescriptor, &bDaclPresent, &pDacl, &bDaclDefaulted)) {
if (bDaclPresent) {
if (!pDacl) {
//
// we have a NULL dacl -- log a problem
//
VLOG(VLOG_LEVEL_ERROR,
VLOG_SECURITYCHECKS_NULL_DACL,
"Called %ls, and specified a NULL DACL in %ls for object '%ls.'",
szCaller,
szParam,
szName);
return;
}
if (!g_pWorldSid) {
//
// we never were able to get the world Sid
//
return;
}
for (DWORD i = 0; i < pDacl->AceCount; ++i) {
PACE_HEADER pAceHeader = NULL;
PSID pSID;
ACCESS_MASK dwAccessMask;
if (!GetAce(pDacl, i, (LPVOID*)&pAceHeader)) {
continue;
}
//
// if it's not some form of ACCESS_ALLOWED ACE, we aren't interested
//
if (pAceHeader->AceType == ACCESS_ALLOWED_ACE_TYPE) {
pSID = &(((PACCESS_ALLOWED_ACE)pAceHeader)->SidStart);
dwAccessMask = ((PACCESS_ALLOWED_ACE)pAceHeader)->Mask;
} else if (pAceHeader->AceType == ACCESS_ALLOWED_OBJECT_ACE_TYPE) {
PACCESS_ALLOWED_OBJECT_ACE pAAOAce = (PACCESS_ALLOWED_OBJECT_ACE)pAceHeader;
//
// who the heck came up with this system? The Sid starts at a different place
// depending on the flags. Anyone ever heard of multiple structs? Sigh.
//
if ((pAAOAce->Flags & ACE_OBJECT_TYPE_PRESENT) && (pAAOAce->Flags & ACE_INHERITED_OBJECT_TYPE_PRESENT)) {
pSID = &(pAAOAce->SidStart);
} else if ((pAAOAce->Flags & ACE_OBJECT_TYPE_PRESENT) || (pAAOAce->Flags & ACE_INHERITED_OBJECT_TYPE_PRESENT)){
pSID = (PSID)&(pAAOAce->InheritedObjectType);
} else {
pSID = (PSID)&(pAAOAce->ObjectType);
}
dwAccessMask = ((PACCESS_ALLOWED_OBJECT_ACE)pAceHeader)->Mask;
} else {
continue;
}
//
// check the validity of the SID, just to be safe
//
if (!IsValidSid(pSID)) {
continue;
}
//
// if the SID is the world, and the access mask allows WRITE_DAC and WRITE_OWNER, we have a problem
//
if ((dwAccessMask & (WRITE_DAC | WRITE_OWNER)) && EqualSid(pSID, g_pWorldSid)) {
VLOG(VLOG_LEVEL_ERROR,
VLOG_SECURITYCHECKS_WORLDWRITE_DACL,
"Called %ls, and specified a DACL with WRITE_DAC and/or WRITE_OWNER for WORLD in %ls for object '%ls.'",
szCaller,
szParam,
szName);
return;
}
}
}
}
}
void
CheckSecurityAttributes(
LPSECURITY_ATTRIBUTES pSecurityAttrib,
LPCWSTR szCaller,
LPCWSTR szParam,
LPCWSTR szName
)
{
PSECURITY_DESCRIPTOR pSecurityDescriptor = NULL;
if (!pSecurityAttrib) {
//
// there's no attributes, so they get the default, which is fine
//
return;
}
pSecurityDescriptor = (PSECURITY_DESCRIPTOR)pSecurityAttrib->lpSecurityDescriptor;
CheckSecurityDescriptor(pSecurityDescriptor, szCaller, szParam, szName);
}
void
CheckCreateProcess(
LPCWSTR pwszApplicationName,
LPCWSTR pwszCommandLine,
LPCWSTR pwszCaller
)
{
//
// if applicationname is non-null, there's no problem
//
if (pwszApplicationName) {
return;
}
//
// if there's no command line, there's a problem, but not one we want to solve
//
if (!pwszCommandLine) {
return;
}
//
// if there are no spaces, no problem
//
LPWSTR pSpaceLoc = wcschr(pwszCommandLine, L' ');
if (!pSpaceLoc) {
return;
}
//
// if the beginning of the command line is quoted, no problem
//
if (pwszCommandLine[0] == L'\"') {
return;
}
//
// if the phrase '.exe ' appears before the first space, we'll call that good
//
LPWSTR pExeLoc = wcsistr(pwszCommandLine, L".exe ");
if (pExeLoc && pExeLoc < pSpaceLoc) {
return;
}
//
// if the first part of the command line is windir, we'll call that good
//
if (g_dwWinDirLen && _wcsnicmp(pwszCommandLine, g_wszWinDir, g_dwWinDirLen) == 0) {
return;
}
if (_wcsicmp(pwszCaller, L"winexec") == 0) {
VLOG(VLOG_LEVEL_ERROR,
VLOG_SECURITYCHECKS_BADARGUMENTS,
"Called %ls with command line '%ls'. The command line has spaces, and the exe name is not in quotes.",
pwszCaller,
pwszCommandLine);
} else {
VLOG(VLOG_LEVEL_ERROR,
VLOG_SECURITYCHECKS_BADARGUMENTS,
"Called %ls with command line '%ls'. The lpApplicationName argument is NULL, lpCommandLine has spaces, and the exe name is not in quotes.",
pwszCaller,
pwszCommandLine);
}
}
void
CheckForNoPathInFileName(
LPCWSTR pwszFilePath,
LPCWSTR pwszCaller
)
{
if (!pwszFilePath || !pwszCaller) {
return;
}
//
// skip quotes and space if necessary
//
DWORD dwBegin = 0;
while (pwszFilePath[dwBegin] == L'\"' || pwszFilePath[dwBegin] == L' ') {
dwBegin++;
}
//
// if there's nothing left of the string, get out
//
if (!pwszFilePath[dwBegin] || !pwszFilePath[dwBegin + 1]) {
return;
}
//
// check for DOS (x:...) and UNC (\\...) full paths
//
if (pwszFilePath[dwBegin + 1] == L':' || (pwszFilePath[dwBegin] == L'\\' && pwszFilePath[dwBegin + 1] == L'\\')) {
//
// full path
//
return;
}
VLOG(VLOG_LEVEL_ERROR,
VLOG_SECURITYCHECKS_BADARGUMENTS,
"Called '%ls' with '%ls' specified. Use a full path to the file to ensure that you get the executable you want, and not a malicious exe with the same name.",
pwszCaller,
pwszFilePath);
}
BOOL
APIHOOK(CreateProcessA)(
LPCSTR lpApplicationName,
LPSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
BOOL bInheritHandles,
DWORD dwCreationFlags,
LPVOID lpEnvironment,
LPCSTR lpCurrentDirectory,
LPSTARTUPINFOA lpStartupInfo,
LPPROCESS_INFORMATION lpProcessInformation
)
{
LPWSTR pwszApplicationName = ToUnicode(lpApplicationName);
LPWSTR pwszCommandLine = ToUnicode(lpCommandLine);
CheckCreateProcess(pwszApplicationName, pwszCommandLine, L"CreateProcess");
if (pwszApplicationName) {
CheckForNoPathInFileName(pwszApplicationName, L"CreateProcess");
CheckSecurityAttributes(lpProcessAttributes, L"CreateProcess", L"lpProcessAttributes", pwszApplicationName);
CheckSecurityAttributes(lpThreadAttributes, L"CreateProcess", L"lpThreadAttributes", pwszApplicationName);
} else {
CheckForNoPathInFileName(pwszCommandLine, L"CreateProcess");
CheckSecurityAttributes(lpProcessAttributes, L"CreateProcess", L"lpProcessAttributes", pwszCommandLine);
CheckSecurityAttributes(lpThreadAttributes, L"CreateProcess", L"lpThreadAttributes", pwszCommandLine);
}
if (pwszApplicationName) {
free(pwszApplicationName);
pwszApplicationName = NULL;
}
if (pwszCommandLine) {
free(pwszCommandLine);
pwszCommandLine = NULL;
}
return ORIGINAL_API(CreateProcessA)(lpApplicationName,
lpCommandLine,
lpProcessAttributes,
lpThreadAttributes,
bInheritHandles,
dwCreationFlags,
lpEnvironment,
lpCurrentDirectory,
lpStartupInfo,
lpProcessInformation);
}
BOOL
APIHOOK(CreateProcessW)(
LPCWSTR lpApplicationName,
LPWSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
BOOL bInheritHandles,
DWORD dwCreationFlags,
LPVOID lpEnvironment,
LPWSTR lpCurrentDirectory,
LPSTARTUPINFOW lpStartupInfo,
LPPROCESS_INFORMATION lpProcessInformation
)
{
CheckCreateProcess(lpApplicationName, lpCommandLine, L"CreateProcess");
if (lpApplicationName) {
CheckForNoPathInFileName(lpApplicationName, L"CreateProcess");
CheckSecurityAttributes(lpProcessAttributes, L"CreateProcess", L"lpProcessAttributes", lpApplicationName);
CheckSecurityAttributes(lpThreadAttributes, L"CreateProcess", L"lpThreadAttributes", lpApplicationName);
} else {
CheckForNoPathInFileName(lpCommandLine, L"CreateProcess");
CheckSecurityAttributes(lpProcessAttributes, L"CreateProcess", L"lpProcessAttributes", lpCommandLine);
CheckSecurityAttributes(lpThreadAttributes, L"CreateProcess", L"lpThreadAttributes", lpCommandLine);
}
return ORIGINAL_API(CreateProcessW)(lpApplicationName,
lpCommandLine,
lpProcessAttributes,
lpThreadAttributes,
bInheritHandles,
dwCreationFlags,
lpEnvironment,
lpCurrentDirectory,
lpStartupInfo,
lpProcessInformation);
}
BOOL
APIHOOK(CreateProcessAsUserA)(
HANDLE hToken,
LPCSTR lpApplicationName,
LPSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
BOOL bInheritHandles,
DWORD dwCreationFlags,
LPVOID lpEnvironment,
LPCSTR lpCurrentDirectory,
LPSTARTUPINFOA lpStartupInfo,
LPPROCESS_INFORMATION lpProcessInformation
)
{
LPWSTR pwszApplicationName = ToUnicode(lpApplicationName);
LPWSTR pwszCommandLine = ToUnicode(lpCommandLine);
CheckCreateProcess(pwszApplicationName, pwszCommandLine, L"CreateProcessAsUser");
if (pwszApplicationName) {
CheckForNoPathInFileName(pwszApplicationName, L"CreateProcessAsUser");
CheckSecurityAttributes(lpProcessAttributes, L"CreateProcessAsUser", L"lpProcessAttributes", pwszApplicationName);
CheckSecurityAttributes(lpThreadAttributes, L"CreateProcessAsUser", L"lpThreadAttributes", pwszApplicationName);
} else {
CheckForNoPathInFileName(pwszCommandLine, L"CreateProcessAsUser");
CheckSecurityAttributes(lpProcessAttributes, L"CreateProcessAsUser", L"lpProcessAttributes", pwszCommandLine);
CheckSecurityAttributes(lpThreadAttributes, L"CreateProcessAsUser", L"lpThreadAttributes", pwszCommandLine);
}
if (pwszApplicationName) {
free(pwszApplicationName);
pwszApplicationName = NULL;
}
if (pwszCommandLine) {
free(pwszCommandLine);
pwszCommandLine = NULL;
}
return ORIGINAL_API(CreateProcessAsUserA)(hToken,
lpApplicationName,
lpCommandLine,
lpProcessAttributes,
lpThreadAttributes,
bInheritHandles,
dwCreationFlags,
lpEnvironment,
lpCurrentDirectory,
lpStartupInfo,
lpProcessInformation);
}
BOOL
APIHOOK(CreateProcessAsUserW)(
HANDLE hToken,
LPCWSTR lpApplicationName,
LPWSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
BOOL bInheritHandles,
DWORD dwCreationFlags,
LPVOID lpEnvironment,
LPWSTR lpCurrentDirectory,
LPSTARTUPINFOW lpStartupInfo,
LPPROCESS_INFORMATION lpProcessInformation
)
{
CheckCreateProcess(lpApplicationName, lpCommandLine, L"CreateProcessAsUser");
if (lpApplicationName) {
CheckForNoPathInFileName(lpApplicationName, L"CreateProcessAsUser");
CheckSecurityAttributes(lpProcessAttributes, L"CreateProcessAsUser", L"lpProcessAttributes", lpApplicationName);
CheckSecurityAttributes(lpThreadAttributes, L"CreateProcessAsUser", L"lpThreadAttributes", lpApplicationName);
} else {
CheckForNoPathInFileName(lpCommandLine, L"CreateProcessAsUser");
CheckSecurityAttributes(lpProcessAttributes, L"CreateProcessAsUser", L"lpProcessAttributes", lpCommandLine);
CheckSecurityAttributes(lpThreadAttributes, L"CreateProcessAsUser", L"lpThreadAttributes", lpCommandLine);
}
return ORIGINAL_API(CreateProcessAsUserW)(hToken,
lpApplicationName,
lpCommandLine,
lpProcessAttributes,
lpThreadAttributes,
bInheritHandles,
dwCreationFlags,
lpEnvironment,
lpCurrentDirectory,
lpStartupInfo,
lpProcessInformation);
}
UINT
APIHOOK(WinExec)(
LPCSTR lpCmdLine,
UINT uCmdShow
)
{
LPWSTR pwszCmdLine = ToUnicode(lpCmdLine);
VLOG(VLOG_LEVEL_ERROR, VLOG_SECURITYCHECKS_WINEXEC, "Called WinExec.");
CheckForNoPathInFileName(pwszCmdLine, L"WinExec");
CheckCreateProcess(NULL, pwszCmdLine, L"WinExec");
if (pwszCmdLine) {
free(pwszCmdLine);
pwszCmdLine = NULL;
}
return ORIGINAL_API(WinExec)(lpCmdLine, uCmdShow);
}
HANDLE
APIHOOK(CreateFileA)(
LPCSTR lpFileName, // file name
DWORD dwDesiredAccess, // access mode
DWORD dwShareMode, // share mode
LPSECURITY_ATTRIBUTES lpSecurityAttributes, // SD
DWORD dwCreationDisposition, // how to create
DWORD dwFlagsAndAttributes, // file attributes
HANDLE hTemplateFile // handle to template file
)
{
LPWSTR pwszName = ToUnicode(lpFileName);
CheckSecurityAttributes(lpSecurityAttributes, L"CreateFile", L"lpSecurityAttributes", pwszName);
if (pwszName) {
free(pwszName);
pwszName = NULL;
}
return ORIGINAL_API(CreateFileA)(lpFileName,
dwDesiredAccess,
dwShareMode,
lpSecurityAttributes,
dwCreationDisposition,
dwFlagsAndAttributes,
hTemplateFile);
}
HANDLE
APIHOOK(CreateFileW)(
LPCWSTR lpFileName, // file name
DWORD dwDesiredAccess, // access mode
DWORD dwShareMode, // share mode
LPSECURITY_ATTRIBUTES lpSecurityAttributes, // SD
DWORD dwCreationDisposition, // how to create
DWORD dwFlagsAndAttributes, // file attributes
HANDLE hTemplateFile // handle to template file
)
{
CheckSecurityAttributes(lpSecurityAttributes, L"CreateFile", L"lpSecurityAttributes", lpFileName);
return ORIGINAL_API(CreateFileW)(lpFileName,
dwDesiredAccess,
dwShareMode,
lpSecurityAttributes,
dwCreationDisposition,
dwFlagsAndAttributes,
hTemplateFile);
}
HDESK
APIHOOK(CreateDesktopA)(
LPCSTR lpszDesktop, // name of new desktop
LPCSTR lpszDevice, // reserved; must be NULL
LPDEVMODEA pDevmode, // reserved; must be NULL
DWORD dwFlags, // desktop interaction
ACCESS_MASK dwDesiredAccess, // access of returned handle
LPSECURITY_ATTRIBUTES lpsa // security attributes
)
{
LPWSTR pwszName = ToUnicode(lpszDesktop);
CheckSecurityAttributes(lpsa, L"CreateDesktop", L"lpsa", pwszName);
if (pwszName) {
free(pwszName);
pwszName = NULL;
}
return ORIGINAL_API(CreateDesktopA)(lpszDesktop,
lpszDevice,
pDevmode,
dwFlags,
dwDesiredAccess,
lpsa);
}
HDESK
APIHOOK(CreateDesktopW)(
LPCWSTR lpszDesktop, // name of new desktop
LPCWSTR lpszDevice, // reserved; must be NULL
LPDEVMODEW pDevmode, // reserved; must be NULL
DWORD dwFlags, // desktop interaction
ACCESS_MASK dwDesiredAccess, // access of returned handle
LPSECURITY_ATTRIBUTES lpsa // security attributes
)
{
CheckSecurityAttributes(lpsa, L"CreateDesktop", L"lpsa", lpszDesktop);
return ORIGINAL_API(CreateDesktopW)(lpszDesktop,
lpszDevice,
pDevmode,
dwFlags,
dwDesiredAccess,
lpsa);
}
HWINSTA
APIHOOK(CreateWindowStationA)(
LPSTR lpwinsta, // new window station name
DWORD dwReserved, // reserved; must be zero
ACCESS_MASK dwDesiredAccess, // requested access
LPSECURITY_ATTRIBUTES lpsa // security attributes
)
{
LPWSTR pwszName = ToUnicode(lpwinsta);
CheckSecurityAttributes(lpsa, L"CreateWindowStation", L"lpsa", pwszName);
if (pwszName) {
free(pwszName);
pwszName = NULL;
}
return ORIGINAL_API(CreateWindowStationA)(lpwinsta,
dwReserved,
dwDesiredAccess,
lpsa);
}
HWINSTA
APIHOOK(CreateWindowStationW)(
LPWSTR lpwinsta, // new window station name
DWORD dwReserved, // reserved; must be zero
ACCESS_MASK dwDesiredAccess, // requested access
LPSECURITY_ATTRIBUTES lpsa // security attributes
)
{
CheckSecurityAttributes(lpsa, L"CreateWindowStation", L"lpsa", lpwinsta);
return ORIGINAL_API(CreateWindowStationW)(lpwinsta,
dwReserved,
dwDesiredAccess,
lpsa);
}
LONG
APIHOOK(RegCreateKeyExA)(
HKEY hKey,
LPCSTR lpSubKey,
DWORD Reserved,
LPSTR lpClass,
DWORD dwOptions,
REGSAM samDesired,
LPSECURITY_ATTRIBUTES lpSecurityAttributes,
PHKEY phkResult,
LPDWORD lpdwDisposition
)
{
LPWSTR pwszName = ToUnicode(lpSubKey);
CheckSecurityAttributes(lpSecurityAttributes, L"RegCreateKeyEx", L"lpSecurityAttributes", pwszName);
if (pwszName) {
free(pwszName);
pwszName = NULL;
}
return ORIGINAL_API(RegCreateKeyExA)(hKey,
lpSubKey,
Reserved,
lpClass,
dwOptions,
samDesired,
lpSecurityAttributes,
phkResult,
lpdwDisposition);
}
LONG
APIHOOK(RegCreateKeyExW)(
HKEY hKey,
LPCWSTR lpSubKey,
DWORD Reserved,
LPWSTR lpClass,
DWORD dwOptions,
REGSAM samDesired,
LPSECURITY_ATTRIBUTES lpSecurityAttributes,
PHKEY phkResult,
LPDWORD lpdwDisposition
)
{
CheckSecurityAttributes(lpSecurityAttributes, L"RegCreateKeyEx", L"lpSecurityAttributes", lpSubKey);
return ORIGINAL_API(RegCreateKeyExW)(hKey,
lpSubKey,
Reserved,
lpClass,
dwOptions,
samDesired,
lpSecurityAttributes,
phkResult,
lpdwDisposition);
}
LONG
APIHOOK(RegSaveKeyA)(
HKEY hKey, // handle to key
LPCSTR lpFile, // data file
LPSECURITY_ATTRIBUTES lpSecurityAttributes // SD
)
{
LPWSTR pwszName = ToUnicode(lpFile);
CheckSecurityAttributes(lpSecurityAttributes, L"RegSaveKey", L"lpSecurityAttributes", pwszName);
if (pwszName) {
free(pwszName);
pwszName = NULL;
}
return ORIGINAL_API(RegSaveKeyA)(hKey,
lpFile,
lpSecurityAttributes);
}
LONG
APIHOOK(RegSaveKeyW)(
HKEY hKey, // handle to key
LPCWSTR lpFile, // data file
LPSECURITY_ATTRIBUTES lpSecurityAttributes // SD
)
{
CheckSecurityAttributes(lpSecurityAttributes, L"RegSaveKey", L"lpSecurityAttributes", lpFile);
return ORIGINAL_API(RegSaveKeyW)(hKey,
lpFile,
lpSecurityAttributes);
}
LONG
APIHOOK(RegSaveKeyExA)(
HKEY hKey, // handle to key
LPCSTR lpFile, // data file
LPSECURITY_ATTRIBUTES lpSecurityAttributes, // SD
DWORD Flags
)
{
LPWSTR pwszName = ToUnicode(lpFile);
CheckSecurityAttributes(lpSecurityAttributes, L"RegSaveKeyEx", L"lpSecurityAttributes", pwszName);
if (pwszName) {
free(pwszName);
pwszName = NULL;
}
return ORIGINAL_API(RegSaveKeyExA)(hKey,
lpFile,
lpSecurityAttributes,
Flags);
}
LONG
APIHOOK(RegSaveKeyExW)(
HKEY hKey, // handle to key
LPCWSTR lpFile, // data file
LPSECURITY_ATTRIBUTES lpSecurityAttributes, // SD
DWORD Flags
)
{
CheckSecurityAttributes(lpSecurityAttributes, L"RegSaveKeyEx", L"lpSecurityAttributes", lpFile);
return ORIGINAL_API(RegSaveKeyExW)(hKey,
lpFile,
lpSecurityAttributes,
Flags);
}
HANDLE
APIHOOK(CreateFileMappingA)(
HANDLE hFile,
LPSECURITY_ATTRIBUTES lpAttributes,
DWORD flProtect,
DWORD dwMaximumSizeHigh,
DWORD dwMaximumSizeLow,
LPCSTR lpName
)
{
LPWSTR pwszName = ToUnicode(lpName);
CheckSecurityAttributes(lpAttributes, L"CreateFileMapping", L"lpAttributes", pwszName);
if (pwszName) {
free(pwszName);
pwszName = NULL;
}
return ORIGINAL_API(CreateFileMappingA)(hFile,
lpAttributes,
flProtect,
dwMaximumSizeHigh,
dwMaximumSizeLow,
lpName);
}
HANDLE
APIHOOK(CreateFileMappingW)(
HANDLE hFile,
LPSECURITY_ATTRIBUTES lpAttributes,
DWORD flProtect,
DWORD dwMaximumSizeHigh,
DWORD dwMaximumSizeLow,
LPCWSTR lpName
)
{
CheckSecurityAttributes(lpAttributes, L"CreateFileMapping", L"lpAttributes", lpName);
return ORIGINAL_API(CreateFileMappingW)(hFile,
lpAttributes,
flProtect,
dwMaximumSizeHigh,
dwMaximumSizeLow,
lpName);
}
HANDLE
APIHOOK(CreateJobObjectA)(
LPSECURITY_ATTRIBUTES lpJobAttributes, // SD
LPCSTR lpName // job name
)
{
LPWSTR pwszName = ToUnicode(lpName);
CheckSecurityAttributes(lpJobAttributes, L"CreateJobObject", L"lpJobAttributes", pwszName);
if (pwszName) {
free(pwszName);
pwszName = NULL;
}
return ORIGINAL_API(CreateJobObjectA)(lpJobAttributes,
lpName);
}
HANDLE
APIHOOK(CreateJobObjectW)(
LPSECURITY_ATTRIBUTES lpJobAttributes, // SD
LPCWSTR lpName // job name
)
{
CheckSecurityAttributes(lpJobAttributes, L"CreateJobObject", L"lpJobAttributes", lpName);
return ORIGINAL_API(CreateJobObjectW)(lpJobAttributes,
lpName);
}
HANDLE
APIHOOK(CreateThread)(
LPSECURITY_ATTRIBUTES lpThreadAttributes, // SD
SIZE_T dwStackSize, // initial stack size
LPTHREAD_START_ROUTINE lpStartAddress, // thread function
LPVOID lpParameter, // thread argument
DWORD dwCreationFlags, // creation option
LPDWORD lpThreadId // thread identifier
)
{
CheckSecurityAttributes(lpThreadAttributes, L"CreateThread", L"lpThreadAttributes", L"Unnamed thread");
return ORIGINAL_API(CreateThread)(lpThreadAttributes,
(DWORD)dwStackSize,
lpStartAddress,
lpParameter,
dwCreationFlags,
lpThreadId);
}
HANDLE
APIHOOK(CreateRemoteThread)(
HANDLE hProcess, // handle to process
LPSECURITY_ATTRIBUTES lpThreadAttributes, // SD
SIZE_T dwStackSize, // initial stack size
LPTHREAD_START_ROUTINE lpStartAddress, // thread function
LPVOID lpParameter, // thread argument
DWORD dwCreationFlags, // creation option
LPDWORD lpThreadId // thread identifier
)
{
CheckSecurityAttributes(lpThreadAttributes, L"CreateRemoteThread", L"lpThreadAttributes", L"Unnamed thread");
return ORIGINAL_API(CreateRemoteThread)(hProcess,
lpThreadAttributes,
dwStackSize,
lpStartAddress,
lpParameter,
dwCreationFlags,
lpThreadId);
}
BOOL
APIHOOK(CreateDirectoryA)(
LPCSTR lpPathName, // directory name
LPSECURITY_ATTRIBUTES lpSecurityAttributes // SD
)
{
LPWSTR pwszName = ToUnicode(lpPathName);
CheckSecurityAttributes(lpSecurityAttributes, L"CreateDirectory", L"lpSecurityAttributes", pwszName);
if (pwszName) {
free(pwszName);
pwszName = NULL;
}
return ORIGINAL_API(CreateDirectoryA)(lpPathName,
lpSecurityAttributes);
}
BOOL
APIHOOK(CreateDirectoryW)(
LPCWSTR lpPathName, // directory name
LPSECURITY_ATTRIBUTES lpSecurityAttributes // SD
)
{
CheckSecurityAttributes(lpSecurityAttributes, L"CreateDirectory", L"lpSecurityAttributes", lpPathName);
return ORIGINAL_API(CreateDirectoryW)(lpPathName,
lpSecurityAttributes);
}
BOOL
APIHOOK(CreateDirectoryExA)(
LPCSTR lpTemplateDirectory, // template directory
LPCSTR lpNewDirectory, // directory name
LPSECURITY_ATTRIBUTES lpSecurityAttributes // SD
)
{
LPWSTR pwszName = ToUnicode(lpNewDirectory);
CheckSecurityAttributes(lpSecurityAttributes, L"CreateDirectoryEx", L"lpSecurityAttributes", pwszName);
if (pwszName) {
free(pwszName);
pwszName = NULL;
}
return ORIGINAL_API(CreateDirectoryExA)(lpTemplateDirectory,
lpNewDirectory,
lpSecurityAttributes);
}
BOOL
APIHOOK(CreateDirectoryExW)(
LPCWSTR lpTemplateDirectory, // template directory
LPCWSTR lpNewDirectory, // directory name
LPSECURITY_ATTRIBUTES lpSecurityAttributes // SD
)
{
CheckSecurityAttributes(lpSecurityAttributes, L"CreateDirectoryEx", L"lpSecurityAttributes", lpNewDirectory);
return ORIGINAL_API(CreateDirectoryExW)(lpTemplateDirectory,
lpNewDirectory,
lpSecurityAttributes);
}
BOOL
APIHOOK(CreateHardLinkA)(
LPCSTR lpFileName, // link name name
LPCSTR lpExistingFileName, // target file name
LPSECURITY_ATTRIBUTES lpSecurityAttributes
)
{
LPWSTR pwszName = ToUnicode(lpFileName);
CheckSecurityAttributes(lpSecurityAttributes, L"CreateHardLink", L"lpSecurityAttributes", pwszName);
if (pwszName) {
free(pwszName);
pwszName = NULL;
}
return ORIGINAL_API(CreateHardLinkA)(lpFileName,
lpExistingFileName,
lpSecurityAttributes);
}
BOOL
APIHOOK(CreateHardLinkW)(
LPCWSTR lpFileName, // link name name
LPCWSTR lpExistingFileName, // target file name
LPSECURITY_ATTRIBUTES lpSecurityAttributes
)
{
CheckSecurityAttributes(lpSecurityAttributes, L"CreateHardLink", L"lpSecurityAttributes", lpFileName);
return ORIGINAL_API(CreateHardLinkW)(lpFileName,
lpExistingFileName,
lpSecurityAttributes);
}
HANDLE
APIHOOK(CreateMailslotA)(
LPCSTR lpName, // mailslot name
DWORD nMaxMessageSize, // maximum message size
DWORD lReadTimeout, // read time-out interval
LPSECURITY_ATTRIBUTES lpSecurityAttributes // inheritance option
)
{
LPWSTR pwszName = ToUnicode(lpName);
CheckSecurityAttributes(lpSecurityAttributes, L"CreateMailslot", L"lpSecurityAttributes", pwszName);
if (pwszName) {
free(pwszName);
pwszName = NULL;
}
return ORIGINAL_API(CreateMailslotA)(lpName,
nMaxMessageSize,
lReadTimeout,
lpSecurityAttributes);
}
HANDLE
APIHOOK(CreateMailslotW)(
LPCWSTR lpName, // mailslot name
DWORD nMaxMessageSize, // maximum message size
DWORD lReadTimeout, // read time-out interval
LPSECURITY_ATTRIBUTES lpSecurityAttributes // inheritance option
)
{
CheckSecurityAttributes(lpSecurityAttributes, L"CreateMailslot", L"lpSecurityAttributes", lpName);
return ORIGINAL_API(CreateMailslotW)(lpName,
nMaxMessageSize,
lReadTimeout,
lpSecurityAttributes);
}
HANDLE
APIHOOK(CreateNamedPipeA)(
LPCSTR lpName, // pipe name
DWORD dwOpenMode, // pipe open mode
DWORD dwPipeMode, // pipe-specific modes
DWORD nMaxInstances, // maximum number of instances
DWORD nOutBufferSize, // output buffer size
DWORD nInBufferSize, // input buffer size
DWORD nDefaultTimeOut, // time-out interval
LPSECURITY_ATTRIBUTES lpSecurityAttributes // SD
)
{
LPWSTR pwszName = ToUnicode(lpName);
CheckSecurityAttributes(lpSecurityAttributes, L"CreateNamedPipe", L"lpSecurityAttributes", pwszName);
if (pwszName) {
free(pwszName);
pwszName = NULL;
}
return ORIGINAL_API(CreateNamedPipeA)(lpName,
dwOpenMode,
dwPipeMode,
nMaxInstances,
nOutBufferSize,
nInBufferSize,
nDefaultTimeOut,
lpSecurityAttributes);
}
HANDLE
APIHOOK(CreateNamedPipeW)(
LPCWSTR lpName, // pipe name
DWORD dwOpenMode, // pipe open mode
DWORD dwPipeMode, // pipe-specific modes
DWORD nMaxInstances, // maximum number of instances
DWORD nOutBufferSize, // output buffer size
DWORD nInBufferSize, // input buffer size
DWORD nDefaultTimeOut, // time-out interval
LPSECURITY_ATTRIBUTES lpSecurityAttributes // SD
)
{
CheckSecurityAttributes(lpSecurityAttributes, L"CreateNamedPipe", L"lpSecurityAttributes", lpName);
return ORIGINAL_API(CreateNamedPipeW)(lpName,
dwOpenMode,
dwPipeMode,
nMaxInstances,
nOutBufferSize,
nInBufferSize,
nDefaultTimeOut,
lpSecurityAttributes);
}
BOOL
APIHOOK(CreatePipe)(
PHANDLE hReadPipe, // read handle
PHANDLE hWritePipe, // write handle
LPSECURITY_ATTRIBUTES lpPipeAttributes, // security attributes
DWORD nSize // pipe size
)
{
CheckSecurityAttributes(lpPipeAttributes, L"CreatePipe", L"lpPipeAttributes", L"Unnamed pipe");
return ORIGINAL_API(CreatePipe)(hReadPipe,
hWritePipe,
lpPipeAttributes,
nSize);
}
HANDLE
APIHOOK(CreateMutexA)(
LPSECURITY_ATTRIBUTES lpMutexAttributes, // SD
BOOL bInitialOwner, // initial owner
LPCSTR lpName // object name
)
{
LPWSTR pwszName = ToUnicode(lpName);
CheckSecurityAttributes(lpMutexAttributes, L"CreateMutex", L"lpMutexAttributes", pwszName);
if (pwszName) {
free(pwszName);
pwszName = NULL;
}
return ORIGINAL_API(CreateMutexA)(lpMutexAttributes,
bInitialOwner,
lpName);
}
HANDLE
APIHOOK(CreateMutexW)(
LPSECURITY_ATTRIBUTES lpMutexAttributes, // SD
BOOL bInitialOwner, // initial owner
LPCWSTR lpName // object name
)
{
CheckSecurityAttributes(lpMutexAttributes, L"CreateMutex", L"lpMutexAttributes", lpName);
return ORIGINAL_API(CreateMutexW)(lpMutexAttributes,
bInitialOwner,
lpName);
}
HANDLE
APIHOOK(CreateSemaphoreA)(
LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, // SD
LONG lInitialCount, // initial count
LONG lMaximumCount, // maximum count
LPCSTR lpName // object name
)
{
LPWSTR pwszName = ToUnicode(lpName);
CheckSecurityAttributes(lpSemaphoreAttributes, L"CreateSemaphore", L"lpSemaphoreAttributes", pwszName);
if (pwszName) {
free(pwszName);
pwszName = NULL;
}
return ORIGINAL_API(CreateSemaphoreA)(lpSemaphoreAttributes,
lInitialCount,
lMaximumCount,
lpName);
}
HANDLE
APIHOOK(CreateSemaphoreW)(
LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, // SD
LONG lInitialCount, // initial count
LONG lMaximumCount, // maximum count
LPCWSTR lpName // object name
)
{
CheckSecurityAttributes(lpSemaphoreAttributes, L"CreateSemaphore", L"lpSemaphoreAttributes", lpName);
return ORIGINAL_API(CreateSemaphoreW)(lpSemaphoreAttributes,
lInitialCount,
lMaximumCount,
lpName);
}
HANDLE
APIHOOK(CreateWaitableTimerA)(
IN LPSECURITY_ATTRIBUTES lpTimerAttributes,
IN BOOL bManualReset,
IN LPCSTR lpTimerName
)
{
LPWSTR pwszName = ToUnicode(lpTimerName);
CheckSecurityAttributes(lpTimerAttributes, L"CreateWaitableTimer", L"lpTimerAttributes", pwszName);
if (pwszName) {
free(pwszName);
pwszName = NULL;
}
return ORIGINAL_API(CreateWaitableTimerA)(lpTimerAttributes,
bManualReset,
lpTimerName);
}
HANDLE
APIHOOK(CreateWaitableTimerW)(
IN LPSECURITY_ATTRIBUTES lpTimerAttributes,
IN BOOL bManualReset,
IN LPCWSTR lpTimerName
)
{
CheckSecurityAttributes(lpTimerAttributes, L"CreateWaitableTimer", L"lpTimerAttributes", lpTimerName);
return ORIGINAL_API(CreateWaitableTimerW)(lpTimerAttributes,
bManualReset,
lpTimerName);
}
#if 0
LONG
WINAPI
APIHOOK(ClusterRegCreateKey)(
HKEY hKey,
LPCWSTR lpszSubKey,
DWORD dwOptions,
REGSAM samDesired,
LPSECURITY_ATTRIBUTES lpSecurityAttributes,
PHKEY phkResult,
LPDWORD lpdwDisposition
)
{
CheckSecurityAttributes(lpSecurityAttributes, L"ClusterRegCreateKey", L"lpSecurityAttributes");
return ORIGINAL_API(ClusterRegCreateKey)(hKey,
lpszSubKey,
dwOptions,
samDesired,
lpSecurityAttributes,
phkResult,
lpdwDisposition);
}
DWORD
WINAPI
APIHOOK(CreateNtmsMediaPoolA)(
HANDLE hSession,
LPCSTR lpPoolName,
LPNTMS_GUID lpMediaType,
DWORD dwAction,
LPSECURITY_ATTRIBUTES lpSecurityAttributes,
LPNTMS_GUID lpPoolId // OUT
)
{
CheckSecurityAttributes(lpSecurityAttributes, L"CreateNtmsMediaPool", L"lpSecurityAttributes");
return ORIGINAL_API(CreateNtmsMediaPoolA)(hSession,
lpPoolName,
lpMediaType,
dwAction,
lpSecurityAttributes,
lpPoolId);
}
DWORD WINAPI
APIHOOK(CreateNtmsMediaPoolW)(
HANDLE hSession,
LPCWSTR lpPoolName,
LPNTMS_GUID lpMediaType,
DWORD dwAction,
LPSECURITY_ATTRIBUTES lpSecurityAttributes,
LPNTMS_GUID lpPoolId // OUT
)
{
CheckSecurityAttributes(lpSecurityAttributes, L"CreateNtmsMediaPool", L"lpSecurityAttributes");
return ORIGINAL_API(CreateNtmsMediaPoolW)(hSession,
lpPoolName,
lpMediaType,
dwAction,
lpSecurityAttributes,
lpPoolId);
}
#endif
SHIM_INFO_BEGIN()
SHIM_INFO_DESCRIPTION(AVS_SECURITYCHECKS_DESC)
SHIM_INFO_FRIENDLY_NAME(AVS_SECURITYCHECKS_FRIENDLY)
SHIM_INFO_FLAGS(0)
SHIM_INFO_GROUPS(0)
SHIM_INFO_VERSION(2, 3)
SHIM_INFO_INCLUDE_EXCLUDE("I:*")
SHIM_INFO_END()
/*++
Register hooked functions.
--*/
HOOK_BEGIN
if (fdwReason == DLL_PROCESS_ATTACH) {
DWORD dwSize;
InitWorldSid();
dwSize = GetSystemWindowsDirectoryW(g_wszWinDir, ARRAYSIZE(g_wszWinDir));
if (dwSize == 0 || dwSize > ARRAYSIZE(g_wszWinDir)) {
g_wszWinDir[0] = 0;
}
g_dwWinDirLen = wcslen(g_wszWinDir);
}
DUMP_VERIFIER_LOG_ENTRY(VLOG_SECURITYCHECKS_BADARGUMENTS,
AVS_SECURITYCHECKS_BADARGUMENTS,
AVS_SECURITYCHECKS_BADARGUMENTS_R,
AVS_SECURITYCHECKS_BADARGUMENTS_URL)
DUMP_VERIFIER_LOG_ENTRY(VLOG_SECURITYCHECKS_WINEXEC,
AVS_SECURITYCHECKS_WINEXEC,
AVS_SECURITYCHECKS_WINEXEC_R,
AVS_SECURITYCHECKS_WINEXEC_URL)
DUMP_VERIFIER_LOG_ENTRY(VLOG_SECURITYCHECKS_NULL_DACL,
AVS_SECURITYCHECKS_NULL_DACL,
AVS_SECURITYCHECKS_NULL_DACL_R,
AVS_SECURITYCHECKS_NULL_DACL_URL)
DUMP_VERIFIER_LOG_ENTRY(VLOG_SECURITYCHECKS_WORLDWRITE_DACL,
AVS_SECURITYCHECKS_WORLDWRITE_DACL,
AVS_SECURITYCHECKS_WORLDWRITE_DACL_R,
AVS_SECURITYCHECKS_WORLDWRITE_DACL_URL)
APIHOOK_ENTRY(KERNEL32.DLL, CreateProcessA)
APIHOOK_ENTRY(KERNEL32.DLL, CreateProcessW)
APIHOOK_ENTRY(ADVAPI32.DLL, CreateProcessAsUserA)
APIHOOK_ENTRY(ADVAPI32.DLL, CreateProcessAsUserW)
APIHOOK_ENTRY(KERNEL32.DLL, WinExec)
APIHOOK_ENTRY(KERNEL32.DLL, CreateFileA)
APIHOOK_ENTRY(KERNEL32.DLL, CreateFileW)
APIHOOK_ENTRY(USER32.DLL, CreateDesktopA)
APIHOOK_ENTRY(USER32.DLL, CreateDesktopW)
APIHOOK_ENTRY(USER32.DLL, CreateWindowStationA)
APIHOOK_ENTRY(USER32.DLL, CreateWindowStationW)
APIHOOK_ENTRY(ADVAPI32.DLL, RegCreateKeyExA)
APIHOOK_ENTRY(ADVAPI32.DLL, RegCreateKeyExW)
APIHOOK_ENTRY(ADVAPI32.DLL, RegSaveKeyA)
APIHOOK_ENTRY(ADVAPI32.DLL, RegSaveKeyW)
APIHOOK_ENTRY(ADVAPI32.DLL, RegSaveKeyExA)
APIHOOK_ENTRY(ADVAPI32.DLL, RegSaveKeyExW)
APIHOOK_ENTRY(KERNEL32.DLL, CreateFileMappingA)
APIHOOK_ENTRY(KERNEL32.DLL, CreateFileMappingW)
APIHOOK_ENTRY(KERNEL32.DLL, CreateJobObjectA)
APIHOOK_ENTRY(KERNEL32.DLL, CreateJobObjectW)
APIHOOK_ENTRY(KERNEL32.DLL, CreateThread)
APIHOOK_ENTRY(KERNEL32.DLL, CreateRemoteThread)
APIHOOK_ENTRY(KERNEL32.DLL, CreateDirectoryA)
APIHOOK_ENTRY(KERNEL32.DLL, CreateDirectoryW)
APIHOOK_ENTRY(KERNEL32.DLL, CreateDirectoryExA)
APIHOOK_ENTRY(KERNEL32.DLL, CreateDirectoryExW)
APIHOOK_ENTRY(KERNEL32.DLL, CreateHardLinkA)
APIHOOK_ENTRY(KERNEL32.DLL, CreateHardLinkW)
APIHOOK_ENTRY(KERNEL32.DLL, CreateMailslotA)
APIHOOK_ENTRY(KERNEL32.DLL, CreateMailslotW)
APIHOOK_ENTRY(KERNEL32.DLL, CreateNamedPipeA)
APIHOOK_ENTRY(KERNEL32.DLL, CreateNamedPipeW)
APIHOOK_ENTRY(KERNEL32.DLL, CreatePipe)
APIHOOK_ENTRY(KERNEL32.DLL, CreateMutexA)
APIHOOK_ENTRY(KERNEL32.DLL, CreateMutexW)
APIHOOK_ENTRY(KERNEL32.DLL, CreateSemaphoreA)
APIHOOK_ENTRY(KERNEL32.DLL, CreateSemaphoreW)
APIHOOK_ENTRY(KERNEL32.DLL, CreateWaitableTimerA)
APIHOOK_ENTRY(KERNEL32.DLL, CreateWaitableTimerW)
HOOK_END
IMPLEMENT_SHIM_END