274 lines
6.9 KiB
C++
274 lines
6.9 KiB
C++
|
/*++
|
||
|
|
||
|
Copyright (c) 2001-2002 Microsoft Corporation
|
||
|
|
||
|
Module Name:
|
||
|
|
||
|
ISA.cpp
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
The ISA setup needs to successfully open the SharedAccess service and get the
|
||
|
its status in order to succeed. But on whistler we remove this from advanced
|
||
|
server since it's a consumer feature so the ISA setup bails out.
|
||
|
|
||
|
We fake the service API call return values to make the ISA setup happy.
|
||
|
|
||
|
History:
|
||
|
|
||
|
04/24/2001 maonis Created
|
||
|
02/15/2002 robkenny Conversion to CompareString was incorrect
|
||
|
Security review.
|
||
|
|
||
|
--*/
|
||
|
|
||
|
#include "precomp.h"
|
||
|
|
||
|
IMPLEMENT_SHIM_BEGIN(ISA)
|
||
|
#include "ShimHookMacro.h"
|
||
|
|
||
|
APIHOOK_ENUM_BEGIN
|
||
|
APIHOOK_ENUM_ENTRY(OpenServiceA)
|
||
|
APIHOOK_ENUM_ENTRY(OpenServiceW)
|
||
|
APIHOOK_ENUM_ENTRY(QueryServiceStatus)
|
||
|
APIHOOK_ENUM_ENTRY(QueryServiceConfigA)
|
||
|
APIHOOK_ENUM_ENTRY(ChangeServiceConfigA)
|
||
|
APIHOOK_ENUM_ENTRY(CloseServiceHandle)
|
||
|
APIHOOK_ENUM_END
|
||
|
|
||
|
|
||
|
SC_HANDLE BogusSharedAccessHandle = (SC_HANDLE)0xBAADF00D;
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
This checks to see if the service is being opened is SharedAccess.
|
||
|
If so we simply return a fake handle.
|
||
|
|
||
|
History:
|
||
|
|
||
|
04/24/2001 maonis Created
|
||
|
|
||
|
--*/
|
||
|
|
||
|
SC_HANDLE
|
||
|
APIHOOK(OpenServiceA)(
|
||
|
SC_HANDLE hSCManager, // handle to SCM database
|
||
|
LPCSTR lpServiceName, // service name
|
||
|
DWORD dwDesiredAccess // access
|
||
|
)
|
||
|
{
|
||
|
DPFN(eDbgLevelInfo, "Calling OpenServiceA on %s", lpServiceName);
|
||
|
|
||
|
SC_HANDLE hService = ORIGINAL_API(OpenServiceA)(hSCManager, lpServiceName, dwDesiredAccess);
|
||
|
if (hService == NULL)
|
||
|
{
|
||
|
if (lpServiceName)
|
||
|
{
|
||
|
// Check to see if the app is attempting to open the SharedAccess service,
|
||
|
// if it is, fake success by returning a bogus (non-NULL) handle
|
||
|
|
||
|
DWORD lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
|
||
|
if ((CompareStringA(lcid, NORM_IGNORECASE, lpServiceName, -1, "SharedAccess", -1) == CSTR_EQUAL))
|
||
|
{
|
||
|
LOGN(eDbgLevelError, "App is attempting to open the SharedAccess server, faking success");
|
||
|
return BogusSharedAccessHandle;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return hService;
|
||
|
}
|
||
|
|
||
|
SC_HANDLE
|
||
|
APIHOOK(OpenServiceW)(
|
||
|
SC_HANDLE hSCManager, // handle to SCM database
|
||
|
LPCWSTR lpServiceName, // service name
|
||
|
DWORD dwDesiredAccess // access
|
||
|
)
|
||
|
{
|
||
|
DPFN(eDbgLevelInfo, "Calling OpenServiceW on %S", lpServiceName);
|
||
|
|
||
|
SC_HANDLE hService = ORIGINAL_API(OpenServiceW)(hSCManager, lpServiceName, dwDesiredAccess);
|
||
|
if (hService == NULL)
|
||
|
{
|
||
|
// Check to see if the app is attempting to open the SharedAccess service,
|
||
|
// if it is, fake success by returning a bogus (non-NULL) handle
|
||
|
|
||
|
DWORD lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
|
||
|
if ((CompareStringW(lcid, NORM_IGNORECASE, lpServiceName, -1, L"SharedAccess", -1) == CSTR_EQUAL))
|
||
|
{
|
||
|
LOGN(eDbgLevelError, "App is attempting to open the SharedAccess server, faking success");
|
||
|
return BogusSharedAccessHandle;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return hService;
|
||
|
}
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
This checks to see if the service handle is 0xBAADF00D, if so just sets
|
||
|
the service status to SERVICE_STOPPED.
|
||
|
|
||
|
History:
|
||
|
|
||
|
04/24/2001 maonis Created
|
||
|
|
||
|
--*/
|
||
|
|
||
|
BOOL
|
||
|
APIHOOK(QueryServiceStatus)(
|
||
|
SC_HANDLE hService, // handle to service
|
||
|
LPSERVICE_STATUS lpServiceStatus // service status
|
||
|
)
|
||
|
{
|
||
|
if (hService == BogusSharedAccessHandle)
|
||
|
{
|
||
|
lpServiceStatus->dwCurrentState = SERVICE_STOPPED;
|
||
|
return TRUE;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return ORIGINAL_API(QueryServiceStatus)(hService, lpServiceStatus);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
ISA calls this API first with a NULL lpServiceConfig to get the size
|
||
|
of the buffer needs to be allocated for the structure; then it calls
|
||
|
the API again with the pointer to the structure.
|
||
|
|
||
|
History:
|
||
|
|
||
|
05/07/2001 maonis Created
|
||
|
|
||
|
--*/
|
||
|
|
||
|
BOOL
|
||
|
APIHOOK(QueryServiceConfigA)(
|
||
|
SC_HANDLE hService, // handle to service
|
||
|
LPQUERY_SERVICE_CONFIGA lpServiceConfig, // buffer
|
||
|
DWORD cbBufSize, // size of buffer
|
||
|
LPDWORD pcbBytesNeeded // bytes needed
|
||
|
)
|
||
|
{
|
||
|
if (hService == BogusSharedAccessHandle)
|
||
|
{
|
||
|
if (lpServiceConfig)
|
||
|
{
|
||
|
lpServiceConfig->lpDependencies = NULL;
|
||
|
return TRUE;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
*pcbBytesNeeded = sizeof(QUERY_SERVICE_CONFIGA);
|
||
|
SetLastError(ERROR_INSUFFICIENT_BUFFER);
|
||
|
return TRUE;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return ORIGINAL_API(QueryServiceConfigA)(hService, lpServiceConfig, cbBufSize, pcbBytesNeeded);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
We simply make this API succeed when hService is 0xBAADF00D.
|
||
|
|
||
|
History:
|
||
|
|
||
|
05/07/2001 maonis Created
|
||
|
|
||
|
--*/
|
||
|
|
||
|
BOOL
|
||
|
APIHOOK(ChangeServiceConfigA)(
|
||
|
SC_HANDLE hService, // handle to service
|
||
|
DWORD dwServiceType, // type of service
|
||
|
DWORD dwStartType, // when to start service
|
||
|
DWORD dwErrorControl, // severity of start failure
|
||
|
LPCSTR lpBinaryPathName, // service binary file name
|
||
|
LPCSTR lpLoadOrderGroup, // load ordering group name
|
||
|
LPDWORD lpdwTagId, // tag identifier
|
||
|
LPCSTR lpDependencies, // array of dependency names
|
||
|
LPCSTR lpServiceStartName, // account name
|
||
|
LPCSTR lpPassword, // account password
|
||
|
LPCSTR lpDisplayName // display name
|
||
|
)
|
||
|
{
|
||
|
if (hService == BogusSharedAccessHandle)
|
||
|
{
|
||
|
return TRUE;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return ORIGINAL_API(ChangeServiceConfigA)(
|
||
|
hService,
|
||
|
dwServiceType,
|
||
|
dwStartType,
|
||
|
dwErrorControl,
|
||
|
lpBinaryPathName,
|
||
|
lpLoadOrderGroup,
|
||
|
lpdwTagId,
|
||
|
lpDependencies,
|
||
|
lpServiceStartName,
|
||
|
lpPassword,
|
||
|
lpDisplayName);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
This checks to see if the service handle is 0xBAADF00D, if so simply return
|
||
|
|
||
|
History:
|
||
|
|
||
|
04/24/2001 maonis Created
|
||
|
|
||
|
--*/
|
||
|
|
||
|
BOOL
|
||
|
APIHOOK(CloseServiceHandle)(
|
||
|
SC_HANDLE hSCObject // handle to service or SCM object
|
||
|
)
|
||
|
{
|
||
|
if (hSCObject == BogusSharedAccessHandle)
|
||
|
{
|
||
|
return TRUE;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
return ORIGINAL_API(CloseServiceHandle)(hSCObject);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*++
|
||
|
|
||
|
Register hooked functions
|
||
|
|
||
|
--*/
|
||
|
|
||
|
HOOK_BEGIN
|
||
|
APIHOOK_ENTRY(Advapi32.DLL, OpenServiceA)
|
||
|
APIHOOK_ENTRY(Advapi32.DLL, OpenServiceW)
|
||
|
APIHOOK_ENTRY(Advapi32.DLL, QueryServiceStatus)
|
||
|
APIHOOK_ENTRY(Advapi32.DLL, QueryServiceConfigA)
|
||
|
APIHOOK_ENTRY(Advapi32.DLL, ChangeServiceConfigA)
|
||
|
APIHOOK_ENTRY(Advapi32.DLL, CloseServiceHandle)
|
||
|
HOOK_END
|
||
|
|
||
|
IMPLEMENT_SHIM_END
|
||
|
|