250 lines
5.5 KiB
C++
250 lines
5.5 KiB
C++
/*++
|
|
|
|
Copyright (c) 2000 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
IgnoreScheduler.cpp
|
|
|
|
Abstract:
|
|
|
|
Includes the following hooks:
|
|
|
|
SetThreadPriority: Normalize the thread priority to prevent some application synchronization
|
|
issues.
|
|
|
|
SetPriorityClass: Normalize process class.
|
|
|
|
SuspendThread: Prevent a thread from suspending itself.
|
|
|
|
ResumeThread: Prevent a thread from resumming itself.
|
|
|
|
Notes:
|
|
|
|
This is a general purpose shim.
|
|
|
|
History:
|
|
|
|
10/20/2000 jpipkins Created: SetPriorityClass created and merged with SetThreadPriority(linstev),
|
|
SuspendThread/ResumeThread(dmunsil/a-brienw).
|
|
|
|
--*/
|
|
|
|
#include "precomp.h"
|
|
|
|
IMPLEMENT_SHIM_BEGIN(IgnoreScheduler)
|
|
#include "ShimHookMacro.h"
|
|
|
|
APIHOOK_ENUM_BEGIN
|
|
APIHOOK_ENUM_ENTRY(CreateProcessA)
|
|
APIHOOK_ENUM_ENTRY(CreateProcessW)
|
|
APIHOOK_ENUM_ENTRY(SetThreadPriority)
|
|
APIHOOK_ENUM_ENTRY(SetPriorityClass)
|
|
APIHOOK_ENUM_ENTRY(ResumeThread)
|
|
APIHOOK_ENUM_ENTRY(SuspendThread)
|
|
APIHOOK_ENUM_END
|
|
|
|
/*++
|
|
|
|
Remove any creation flags that specify process priority.
|
|
|
|
--*/
|
|
|
|
#define PRIORITYMASK (ABOVE_NORMAL_PRIORITY_CLASS | BELOW_NORMAL_PRIORITY_CLASS | HIGH_PRIORITY_CLASS | IDLE_PRIORITY_CLASS | REALTIME_PRIORITY_CLASS)
|
|
|
|
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
|
|
)
|
|
{
|
|
if (dwCreationFlags & PRIORITYMASK) {
|
|
LOGN(eDbgLevelInfo, "[CreateProcessA] Forcing priority class to normal");
|
|
|
|
dwCreationFlags &= ~PRIORITYMASK;
|
|
dwCreationFlags |= NORMAL_PRIORITY_CLASS;
|
|
}
|
|
|
|
return ORIGINAL_API(CreateProcessA)(lpApplicationName, lpCommandLine,
|
|
lpProcessAttributes, lpThreadAttributes, bInheritHandles,
|
|
dwCreationFlags, lpEnvironment, lpCurrentDirectory, lpStartupInfo,
|
|
lpProcessInformation);
|
|
}
|
|
|
|
/*++
|
|
|
|
Remove any creation flags that specify process priority.
|
|
|
|
--*/
|
|
|
|
BOOL
|
|
APIHOOK(CreateProcessW)(
|
|
LPCWSTR lpApplicationName,
|
|
LPWSTR lpCommandLine,
|
|
LPSECURITY_ATTRIBUTES lpProcessAttributes,
|
|
LPSECURITY_ATTRIBUTES lpThreadAttributes,
|
|
BOOL bInheritHandles,
|
|
DWORD dwCreationFlags,
|
|
LPVOID lpEnvironment,
|
|
LPCWSTR lpCurrentDirectory,
|
|
LPSTARTUPINFOW lpStartupInfo,
|
|
LPPROCESS_INFORMATION lpProcessInformation
|
|
)
|
|
{
|
|
if (dwCreationFlags & PRIORITYMASK) {
|
|
LOGN(eDbgLevelInfo, "[CreateProcessW] Forcing priority class to normal");
|
|
|
|
dwCreationFlags &= ~PRIORITYMASK;
|
|
dwCreationFlags |= NORMAL_PRIORITY_CLASS;
|
|
}
|
|
|
|
return ORIGINAL_API(CreateProcessW)(lpApplicationName, lpCommandLine,
|
|
lpProcessAttributes, lpThreadAttributes, bInheritHandles,
|
|
dwCreationFlags, lpEnvironment, lpCurrentDirectory, lpStartupInfo,
|
|
lpProcessInformation);
|
|
}
|
|
|
|
/*++
|
|
|
|
Normalize thread priority.
|
|
|
|
--*/
|
|
|
|
BOOL
|
|
APIHOOK(SetThreadPriority)(
|
|
HANDLE hThread,
|
|
int nPriority
|
|
)
|
|
{
|
|
if (nPriority != THREAD_PRIORITY_NORMAL) {
|
|
LOGN(
|
|
eDbgLevelInfo,
|
|
"[SetThreadPriority] Forcing thread priority to normal.");
|
|
}
|
|
|
|
return ORIGINAL_API(SetThreadPriority)(hThread, THREAD_PRIORITY_NORMAL);
|
|
}
|
|
|
|
/*++
|
|
|
|
Normalize Class priority.
|
|
|
|
--*/
|
|
|
|
BOOL
|
|
APIHOOK(SetPriorityClass)(
|
|
HANDLE hProcess,
|
|
DWORD dwPriorityClass
|
|
)
|
|
{
|
|
if (dwPriorityClass != NORMAL_PRIORITY_CLASS) {
|
|
LOGN(
|
|
eDbgLevelInfo,
|
|
"[SetPriorityClass] Forcing priority class to normal.");
|
|
}
|
|
|
|
return ORIGINAL_API(SetPriorityClass)(hProcess, NORMAL_PRIORITY_CLASS);
|
|
}
|
|
|
|
/*++
|
|
|
|
Get Thread ID for ResumeThread and SuspendThread Hooks
|
|
|
|
--*/
|
|
|
|
|
|
DWORD
|
|
dwGetThreadID(
|
|
HANDLE hThread
|
|
)
|
|
{
|
|
THREAD_BASIC_INFORMATION ThreadBasicInfo;
|
|
NTSTATUS Status;
|
|
|
|
Status = NtQueryInformationThread(hThread,
|
|
ThreadBasicInformation,
|
|
&ThreadBasicInfo,
|
|
sizeof(ThreadBasicInfo),
|
|
NULL);
|
|
|
|
if (NT_SUCCESS(Status)) {
|
|
return (DWORD)ThreadBasicInfo.ClientId.UniqueThread;
|
|
} else {
|
|
LOGN(
|
|
eDbgLevelError,
|
|
"[dwGetThreadID] NtQueryInfomationThread failed.");
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
/*++
|
|
|
|
Disallow suspending self
|
|
|
|
--*/
|
|
|
|
DWORD
|
|
APIHOOK(SuspendThread)(
|
|
HANDLE hThread // handle to the thread
|
|
)
|
|
{
|
|
//
|
|
// If we're trying to suspend our own thread, refuse.
|
|
//
|
|
if (dwGetThreadID(hThread) != dwGetThreadID(GetCurrentThread())) {
|
|
return ORIGINAL_API(SuspendThread)(hThread);
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
/*++
|
|
|
|
Disallow resuming self, for same reason
|
|
|
|
--*/
|
|
|
|
DWORD
|
|
APIHOOK(ResumeThread)(
|
|
HANDLE hThread // handle to the thread
|
|
)
|
|
{
|
|
//
|
|
// If we're trying to resume our own thread, refuse.
|
|
//
|
|
if (dwGetThreadID(hThread) != dwGetThreadID(GetCurrentThread())) {
|
|
return ORIGINAL_API(ResumeThread)(hThread);
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
/*++
|
|
|
|
Register hooked functions
|
|
|
|
--*/
|
|
|
|
HOOK_BEGIN
|
|
|
|
APIHOOK_ENTRY(KERNEL32.DLL, CreateProcessA)
|
|
APIHOOK_ENTRY(KERNEL32.DLL, CreateProcessW)
|
|
APIHOOK_ENTRY(KERNEL32.DLL, SetThreadPriority)
|
|
APIHOOK_ENTRY(KERNEL32.DLL, SetPriorityClass)
|
|
APIHOOK_ENTRY(KERNEL32.DLL, SuspendThread)
|
|
APIHOOK_ENTRY(KERNEL32.DLL, ResumeThread)
|
|
|
|
HOOK_END
|
|
|
|
|
|
IMPLEMENT_SHIM_END
|
|
|