1477 lines
50 KiB
C++
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
|
||
|
|
||
|
|