Source code of Windows XP (NT5)
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.

241 lines
5.9 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. DerandomizeExeName.cpp
  5. Abstract:
  6. See markder
  7. History:
  8. 10/13/1999 markder created.
  9. 05/16/2000 robkenny Check for memory alloc failure.
  10. 03/12/2001 robkenny Converted to CString
  11. --*/
  12. #include "precomp.h"
  13. IMPLEMENT_SHIM_BEGIN(DeRandomizeExeName)
  14. #include "ShimHookMacro.h"
  15. APIHOOK_ENUM_BEGIN
  16. APIHOOK_ENUM_ENTRY(CreateProcessA)
  17. APIHOOK_ENUM_END
  18. CString * g_csFilePattern = NULL;
  19. CString * g_csNewFileName = NULL;
  20. BOOL
  21. APIHOOK(CreateProcessA)(
  22. LPCSTR lpApplicationName, // name of executable module
  23. LPSTR lpCommandLine, // command line string
  24. LPSECURITY_ATTRIBUTES lpProcessAttributes,
  25. LPSECURITY_ATTRIBUTES lpThreadAttributes,
  26. BOOL bInheritHandles, // handle inheritance flag
  27. DWORD dwCreationFlags, // creation flags
  28. LPVOID lpEnvironment, // new environment block
  29. LPCSTR lpCurrentDirectory, // current directory name
  30. LPSTARTUPINFOA lpStartupInfo,
  31. LPPROCESS_INFORMATION lpProcessInformation
  32. )
  33. {
  34. CSTRING_TRY
  35. {
  36. AppAndCommandLine appAndCommandLine(lpApplicationName, lpCommandLine);
  37. const CString & csOrigAppName = appAndCommandLine.GetApplicationName();
  38. CString fileName;
  39. //
  40. // Grab the filename portion of the string only.
  41. //
  42. csOrigAppName.GetLastPathComponent(fileName);
  43. BOOL bMatchesPattern = fileName.PatternMatch(*g_csFilePattern);
  44. if (bMatchesPattern)
  45. {
  46. //
  47. // Replace the randomized app name with the specified name
  48. //
  49. CString csNewAppName(csOrigAppName);
  50. csNewAppName.Replace(fileName, *g_csNewFileName);
  51. //
  52. // Copy the exe to the specified name.
  53. //
  54. if (CopyFileW(csOrigAppName.Get(), csNewAppName.Get(), FALSE))
  55. {
  56. LOGN(
  57. eDbgLevelInfo,
  58. "[CreateProcessA] Derandomized pathname from (%S) to (%S)",
  59. csOrigAppName.Get(), csNewAppName.Get());
  60. //
  61. // Mark the file for deletion after we reboot,
  62. // otherwise the file will never get removed.
  63. //
  64. MoveFileExW(csNewAppName.Get(), NULL, MOVEFILE_DELAY_UNTIL_REBOOT);
  65. //
  66. // We have successfully copied the exe to a new file with the specified name
  67. // it is now safe to replace the lpApplicationName to our new file.
  68. //
  69. return ORIGINAL_API(CreateProcessA) (
  70. csNewAppName.GetAnsi(),
  71. lpCommandLine,
  72. lpProcessAttributes,
  73. lpThreadAttributes,
  74. bInheritHandles,
  75. dwCreationFlags,
  76. lpEnvironment,
  77. lpCurrentDirectory,
  78. lpStartupInfo,
  79. lpProcessInformation);
  80. }
  81. }
  82. }
  83. CSTRING_CATCH
  84. {
  85. // Fall through
  86. }
  87. return ORIGINAL_API(CreateProcessA) (
  88. lpApplicationName,
  89. lpCommandLine,
  90. lpProcessAttributes,
  91. lpThreadAttributes,
  92. bInheritHandles,
  93. dwCreationFlags,
  94. lpEnvironment,
  95. lpCurrentDirectory,
  96. lpStartupInfo,
  97. lpProcessInformation);
  98. }
  99. #if TEST_MATCH
  100. void
  101. TestMatch(
  102. const char* a,
  103. const char* b
  104. )
  105. {
  106. BOOL bMatch = PatternMatchA(a, b);
  107. if (bMatch)
  108. {
  109. DPFN(
  110. eDbgLevelSpew,
  111. "[TestMatch] (%s) == (%s)\n", a, b);
  112. }
  113. else
  114. {
  115. DPFN(
  116. eDbgLevelSpew,
  117. "[TestMatch] (%s) != (%s)\n", a, b);
  118. }
  119. }
  120. void TestLots()
  121. {
  122. TestMatch("", "");
  123. TestMatch("", "ABC");
  124. TestMatch("*", "");
  125. TestMatch("?", "");
  126. TestMatch("abc", "ABC");
  127. TestMatch("?", "ABC");
  128. TestMatch("?bc", "ABC");
  129. TestMatch("a?c", "ABC");
  130. TestMatch("ab?", "ABC");
  131. TestMatch("a??", "ABC");
  132. TestMatch("?b?", "ABC");
  133. TestMatch("??c", "ABC");
  134. TestMatch("???", "ABC");
  135. TestMatch("*", "ABC");
  136. TestMatch("*.", "ABC");
  137. TestMatch("*.", "ABC.");
  138. TestMatch("*.?", "ABC.");
  139. TestMatch("??*", "ABC");
  140. TestMatch("*??", "ABC");
  141. TestMatch("ABC", "ABC");
  142. TestMatch(".*", "ABC");
  143. TestMatch("?*", "ABC");
  144. TestMatch("???*", "ABC");
  145. TestMatch("*.txt", "ABC.txt");
  146. TestMatch("*.txt", ".txt");
  147. TestMatch("*.txt", ".abc");
  148. TestMatch("*.txt", "txt.abc");
  149. TestMatch("***", "");
  150. TestMatch("***", "a");
  151. TestMatch("***", "ab");
  152. TestMatch("***", "abc");
  153. }
  154. #endif
  155. BOOL
  156. ParseCommandLine(void)
  157. {
  158. CSTRING_TRY
  159. {
  160. CStringToken csTok(COMMAND_LINE, ";");
  161. g_csFilePattern = new CString;
  162. g_csNewFileName = new CString;
  163. if (g_csFilePattern &&
  164. g_csNewFileName &&
  165. csTok.GetToken(*g_csFilePattern) &&
  166. csTok.GetToken(*g_csNewFileName))
  167. {
  168. return TRUE;
  169. }
  170. }
  171. CSTRING_CATCH
  172. {
  173. // Do nothing
  174. }
  175. LOGN(
  176. eDbgLevelError,
  177. "[ParseCommandLine] Illegal command line");
  178. return FALSE;
  179. }
  180. BOOL
  181. NOTIFY_FUNCTION(
  182. DWORD fdwReason
  183. )
  184. {
  185. if (fdwReason == DLL_PROCESS_ATTACH)
  186. {
  187. #if TEST_MATCH
  188. TestLots();
  189. #endif
  190. return ParseCommandLine();
  191. }
  192. return TRUE;
  193. }
  194. HOOK_BEGIN
  195. CALL_NOTIFY_FUNCTION
  196. APIHOOK_ENTRY(KERNEL32.DLL, CreateProcessA)
  197. HOOK_END
  198. IMPLEMENT_SHIM_END