windows-nt/Source/XPSP1/NT/windows/appcompat/shims/specific/sysadmiral.cpp

144 lines
2.8 KiB
C++
Raw Normal View History

2020-09-26 03:20:57 -05:00
/*++
Copyright (c) 2000 Microsoft Corporation
Module Name:
SysAdmiral.cpp
Abstract:
Application's service control routine does not properly restore the stack
when returning.
History:
10/22/2001 robkenny Created
--*/
#include "precomp.h"
IMPLEMENT_SHIM_BEGIN(SysAdmiral)
#include "ShimHookMacro.h"
APIHOOK_ENUM_BEGIN
APIHOOK_ENUM_ENTRY(StartServiceCtrlDispatcherA)
APIHOOK_ENUM_END
typedef BOOL (* _pfn_StartServiceCtrlDispatcherA)(CONST LPSERVICE_TABLE_ENTRYA lpServiceTable);
/*++
0x12345678 is replaced with the original service control routine's address
--*/
__declspec(naked)
void
Stub()
{
__asm
{
// save the current stack pointer in ESI
push esi
mov esi, esp
mov eax, 0x12345678
// push the arguments to the routine
push [esi+0xc]
push [esi+0x8]
// call the routine
call eax
// Restore the stack to its value before the routine.
mov esp, esi
pop esi
ret 0x8
}
}
#define Stub_OrigApi_Offset 0x4
#define STUB_SIZE 0x20
/*++
Create an in-memory routine to save and restore the stack.
This is used rather than a subroutine because we cannot pass any parameters
to the routine and it needs to know the address of the original service
routine. A subroutine would have to use a global pointer to the service
routine, limiting this shim to handling only a *single* service routine.
--*/
LPSERVICE_MAIN_FUNCTIONA
BuildStackSaver(LPSERVICE_MAIN_FUNCTIONA lpServiceProc)
{
// Create the stub
LPBYTE pStub = (LPBYTE) VirtualAlloc(
0,
STUB_SIZE,
MEM_COMMIT,
PAGE_EXECUTE_READWRITE);
if (!pStub)
{
DPFN( eDbgLevelError, "Could not allocate memory for stub");
return NULL;
}
// Copy the template code into the memory.
MoveMemory(pStub, Stub, STUB_SIZE);
// Replace the place holding function pointer
DWORD_PTR * origApi = (DWORD_PTR *)(pStub + Stub_OrigApi_Offset);
*origApi = (DWORD_PTR)lpServiceProc;
return (LPSERVICE_MAIN_FUNCTIONA)pStub;
}
/*++
Application's service routine does not properly restore the stack when returning.
--*/
BOOL
APIHOOK(StartServiceCtrlDispatcherA)(
CONST LPSERVICE_TABLE_ENTRYA lpServiceTable // service table
)
{
SERVICE_TABLE_ENTRYA myServiceTable = *lpServiceTable;
//
// Create our in-memory stack restoring functiono
//
myServiceTable.lpServiceProc = BuildStackSaver(lpServiceTable->lpServiceProc);
if (myServiceTable.lpServiceProc)
{
return ORIGINAL_API(StartServiceCtrlDispatcherA)(&myServiceTable);
}
else
{
return FALSE;
}
}
/*++
Register hooked functions
--*/
HOOK_BEGIN
APIHOOK_ENTRY(ADVAPI32.DLL, StartServiceCtrlDispatcherA)
HOOK_END
IMPLEMENT_SHIM_END