144 lines
3.0 KiB
C++
144 lines
3.0 KiB
C++
|
/*++
|
||
|
|
||
|
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
|
||
|
|