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.

206 lines
4.9 KiB

  1. /*++
  2. Copyright (c) 2001 Microsoft Corporation
  3. Module Name:
  4. NetManageViewNow.cpp
  5. Abstract:
  6. The app doesnt follow stdcall conventions for the ServiceMain function
  7. it registers with SCM. This is resulting in an AV as the ServiceMain
  8. is not cleaning up the stack on return, after being called by SCM.
  9. We clean up the stack for the app registered ServiceMain by hooking
  10. StartServiceCtrlDispatcher and registering our own ServiceMain routine,
  11. which makes the actual call to the app registered servicemain and then
  12. pop 8 bytes of the stack before returning.
  13. Notes:
  14. This is an app specific shim.
  15. History:
  16. 03/08/2001 a-leelat Created
  17. --*/
  18. #include "precomp.h"
  19. IMPLEMENT_SHIM_BEGIN(NetManageViewNow)
  20. #include "ShimHookMacro.h"
  21. APIHOOK_ENUM_BEGIN
  22. APIHOOK_ENUM_ENTRY(StartServiceCtrlDispatcherA)
  23. APIHOOK_ENUM_ENTRY(StartServiceCtrlDispatcherW)
  24. APIHOOK_ENUM_END
  25. //last entry of the service table are supposed to be NULL entries
  26. SERVICE_TABLE_ENTRYA g_SvcTableA[] = { {NULL,NULL},{NULL,NULL} };
  27. SERVICE_TABLE_ENTRYW g_SvcTableW[] = { {NULL,NULL},{NULL,NULL} };
  28. LPSERVICE_MAIN_FUNCTIONA g_pfnActualMainA = NULL;
  29. LPSERVICE_MAIN_FUNCTIONW g_pfnActualMainW = NULL;
  30. VOID WINAPI ServiceMainA(
  31. DWORD dwArgc, // number of arguments
  32. LPSTR *lpszArgv // array of arguments
  33. )
  34. {
  35. //call the actual routine
  36. (g_pfnActualMainA)(dwArgc,lpszArgv);
  37. //pop 8 bytes of stack to compensate for
  38. //the app not following stdcall convention
  39. __asm
  40. {
  41. add esp,8
  42. }
  43. }
  44. VOID WINAPI ServiceMainW(
  45. DWORD dwArgc, // number of arguments
  46. LPWSTR *lpszArgv // array of arguments
  47. )
  48. {
  49. //call the actual routine
  50. (g_pfnActualMainW)(dwArgc,lpszArgv);
  51. //pop 8 bytes of stack to compensate for
  52. //the app not following stdcall convention
  53. __asm
  54. {
  55. add esp, 8
  56. }
  57. }
  58. BOOL APIHOOK(StartServiceCtrlDispatcherA)(
  59. CONST LPSERVICE_TABLE_ENTRYA lpServiceTable // service table
  60. )
  61. {
  62. BOOL bRet = false;
  63. LPSERVICE_TABLE_ENTRYA lpSvcTblToPass = lpServiceTable;
  64. DWORD ccbServiceName = (strlen(lpServiceTable->lpServiceName) + 1) * sizeof(*lpServiceTable->lpServiceName);
  65. LPSTR serviceName = (LPSTR) malloc(ccbServiceName);
  66. if (serviceName == NULL)
  67. {
  68. DPFN( eDbgLevelError,
  69. "[StartServiceCtrlDispatcherA] Buffer allocation failure");
  70. }
  71. else
  72. {
  73. //Setup our service table to register with SCM
  74. //Copy the service name as defined by the app
  75. HRESULT hr = StringCbCopyA(serviceName, ccbServiceName, lpServiceTable->lpServiceName);
  76. if (SUCCEEDED(hr))
  77. {
  78. g_SvcTableA[0].lpServiceName = serviceName;
  79. //Now put our service routine
  80. g_SvcTableA[0].lpServiceProc = ServiceMainA;
  81. //Save the old servicemain func ptr
  82. g_pfnActualMainA = lpServiceTable->lpServiceProc;
  83. //Set the service table to our table
  84. lpSvcTblToPass = &g_SvcTableA[0];
  85. DPFN( eDbgLevelInfo,
  86. "[StartServiceCtrlDispatcherA] Hooked ServiceMainA");
  87. }
  88. }
  89. //Call the Original API
  90. bRet = StartServiceCtrlDispatcherA(lpSvcTblToPass);
  91. return bRet;
  92. }
  93. BOOL APIHOOK(StartServiceCtrlDispatcherW)(
  94. CONST LPSERVICE_TABLE_ENTRYW lpServiceTable // service table
  95. )
  96. {
  97. BOOL bRet = false;
  98. LPSERVICE_TABLE_ENTRYW lpSvcTblToPass = lpServiceTable;
  99. DWORD ccbServiceName = (wcslen(lpServiceTable->lpServiceName) + 1) * sizeof(*lpServiceTable->lpServiceName);
  100. LPWSTR serviceName = (LPWSTR) malloc(ccbServiceName);
  101. if (serviceName == NULL)
  102. {
  103. DPFN( eDbgLevelError,
  104. "[StartServiceCtrlDispatcherW] Buffer allocation failure");
  105. }
  106. else
  107. {
  108. //Setup our service table to register with SCM
  109. //Copy the service name as defined by the app
  110. HRESULT hr = StringCbCopyW(serviceName, ccbServiceName, lpServiceTable->lpServiceName);
  111. if (SUCCEEDED(hr))
  112. {
  113. g_SvcTableW[0].lpServiceName = serviceName;
  114. //Now put our service routine
  115. g_SvcTableW[0].lpServiceProc = ServiceMainW;
  116. //Save the old servicemain func ptr
  117. g_pfnActualMainW = lpServiceTable->lpServiceProc;
  118. //Set the service table to our table
  119. lpSvcTblToPass = &g_SvcTableW[0];
  120. DPFN( eDbgLevelInfo,
  121. "[StartServiceCtrlDispatcherW] Hooked ServiceMainW");
  122. }
  123. }
  124. //Call the Original API
  125. bRet = StartServiceCtrlDispatcherW(lpSvcTblToPass);
  126. return bRet;
  127. }
  128. /*++
  129. Register hooked functions
  130. --*/
  131. HOOK_BEGIN
  132. APIHOOK_ENTRY(ADVAPI32.DLL, StartServiceCtrlDispatcherA)
  133. APIHOOK_ENTRY(ADVAPI32.DLL, StartServiceCtrlDispatcherW)
  134. HOOK_END
  135. IMPLEMENT_SHIM_END