Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

143 lines
3.0 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. SysAdmiral.cpp
  5. Abstract:
  6. Application's service control routine does not properly restore the stack
  7. when returning.
  8. History:
  9. 10/22/2001 robkenny Created
  10. --*/
  11. #include "precomp.h"
  12. IMPLEMENT_SHIM_BEGIN(SysAdmiral)
  13. #include "ShimHookMacro.h"
  14. APIHOOK_ENUM_BEGIN
  15. APIHOOK_ENUM_ENTRY(StartServiceCtrlDispatcherA)
  16. APIHOOK_ENUM_END
  17. typedef BOOL (* _pfn_StartServiceCtrlDispatcherA)(CONST LPSERVICE_TABLE_ENTRYA lpServiceTable);
  18. /*++
  19. 0x12345678 is replaced with the original service control routine's address
  20. --*/
  21. __declspec(naked)
  22. void
  23. Stub()
  24. {
  25. __asm
  26. {
  27. // save the current stack pointer in ESI
  28. push esi
  29. mov esi, esp
  30. mov eax, 0x12345678
  31. // push the arguments to the routine
  32. push [esi+0xc]
  33. push [esi+0x8]
  34. // call the routine
  35. call eax
  36. // Restore the stack to its value before the routine.
  37. mov esp, esi
  38. pop esi
  39. ret 0x8
  40. }
  41. }
  42. #define Stub_OrigApi_Offset 0x4
  43. #define STUB_SIZE 0x20
  44. /*++
  45. Create an in-memory routine to save and restore the stack.
  46. This is used rather than a subroutine because we cannot pass any parameters
  47. to the routine and it needs to know the address of the original service
  48. routine. A subroutine would have to use a global pointer to the service
  49. routine, limiting this shim to handling only a *single* service routine.
  50. --*/
  51. LPSERVICE_MAIN_FUNCTIONA
  52. BuildStackSaver(LPSERVICE_MAIN_FUNCTIONA lpServiceProc)
  53. {
  54. // Create the stub
  55. LPBYTE pStub = (LPBYTE) VirtualAlloc(
  56. 0,
  57. STUB_SIZE,
  58. MEM_COMMIT,
  59. PAGE_EXECUTE_READWRITE);
  60. if (!pStub)
  61. {
  62. DPFN( eDbgLevelError, "Could not allocate memory for stub");
  63. return NULL;
  64. }
  65. // Copy the template code into the memory.
  66. MoveMemory(pStub, Stub, STUB_SIZE);
  67. // Replace the place holding function pointer
  68. DWORD_PTR * origApi = (DWORD_PTR *)(pStub + Stub_OrigApi_Offset);
  69. *origApi = (DWORD_PTR)lpServiceProc;
  70. return (LPSERVICE_MAIN_FUNCTIONA)pStub;
  71. }
  72. /*++
  73. Application's service routine does not properly restore the stack when returning.
  74. --*/
  75. BOOL
  76. APIHOOK(StartServiceCtrlDispatcherA)(
  77. CONST LPSERVICE_TABLE_ENTRYA lpServiceTable // service table
  78. )
  79. {
  80. SERVICE_TABLE_ENTRYA myServiceTable = *lpServiceTable;
  81. //
  82. // Create our in-memory stack restoring functiono
  83. //
  84. myServiceTable.lpServiceProc = BuildStackSaver(lpServiceTable->lpServiceProc);
  85. if (myServiceTable.lpServiceProc)
  86. {
  87. return ORIGINAL_API(StartServiceCtrlDispatcherA)(&myServiceTable);
  88. }
  89. else
  90. {
  91. return FALSE;
  92. }
  93. }
  94. /*++
  95. Register hooked functions
  96. --*/
  97. HOOK_BEGIN
  98. APIHOOK_ENTRY(ADVAPI32.DLL, StartServiceCtrlDispatcherA)
  99. HOOK_END
  100. IMPLEMENT_SHIM_END