242 lines
5.9 KiB
C++
242 lines
5.9 KiB
C++
|
/*++
|
||
|
|
||
|
Copyright (c) 2000 Microsoft Corporation
|
||
|
|
||
|
Module Name:
|
||
|
|
||
|
DerandomizeExeName.cpp
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
See markder
|
||
|
|
||
|
History:
|
||
|
|
||
|
10/13/1999 markder created.
|
||
|
05/16/2000 robkenny Check for memory alloc failure.
|
||
|
03/12/2001 robkenny Converted to CString
|
||
|
|
||
|
--*/
|
||
|
|
||
|
#include "precomp.h"
|
||
|
|
||
|
IMPLEMENT_SHIM_BEGIN(DeRandomizeExeName)
|
||
|
#include "ShimHookMacro.h"
|
||
|
|
||
|
APIHOOK_ENUM_BEGIN
|
||
|
APIHOOK_ENUM_ENTRY(CreateProcessA)
|
||
|
APIHOOK_ENUM_END
|
||
|
|
||
|
CString * g_csFilePattern = NULL;
|
||
|
CString * g_csNewFileName = NULL;
|
||
|
|
||
|
BOOL
|
||
|
APIHOOK(CreateProcessA)(
|
||
|
LPCSTR lpApplicationName, // name of executable module
|
||
|
LPSTR lpCommandLine, // command line string
|
||
|
LPSECURITY_ATTRIBUTES lpProcessAttributes,
|
||
|
LPSECURITY_ATTRIBUTES lpThreadAttributes,
|
||
|
BOOL bInheritHandles, // handle inheritance flag
|
||
|
DWORD dwCreationFlags, // creation flags
|
||
|
LPVOID lpEnvironment, // new environment block
|
||
|
LPCSTR lpCurrentDirectory, // current directory name
|
||
|
LPSTARTUPINFOA lpStartupInfo,
|
||
|
LPPROCESS_INFORMATION lpProcessInformation
|
||
|
)
|
||
|
{
|
||
|
|
||
|
CSTRING_TRY
|
||
|
{
|
||
|
AppAndCommandLine appAndCommandLine(lpApplicationName, lpCommandLine);
|
||
|
|
||
|
const CString & csOrigAppName = appAndCommandLine.GetApplicationName();
|
||
|
CString fileName;
|
||
|
|
||
|
//
|
||
|
// Grab the filename portion of the string only.
|
||
|
//
|
||
|
csOrigAppName.GetLastPathComponent(fileName);
|
||
|
|
||
|
BOOL bMatchesPattern = fileName.PatternMatch(*g_csFilePattern);
|
||
|
if (bMatchesPattern)
|
||
|
{
|
||
|
//
|
||
|
// Replace the randomized app name with the specified name
|
||
|
//
|
||
|
CString csNewAppName(csOrigAppName);
|
||
|
csNewAppName.Replace(fileName, *g_csNewFileName);
|
||
|
|
||
|
//
|
||
|
// Copy the exe to the specified name.
|
||
|
//
|
||
|
if (CopyFileW(csOrigAppName.Get(), csNewAppName.Get(), FALSE))
|
||
|
{
|
||
|
|
||
|
LOGN(
|
||
|
eDbgLevelInfo,
|
||
|
"[CreateProcessA] Derandomized pathname from (%S) to (%S)",
|
||
|
csOrigAppName.Get(), csNewAppName.Get());
|
||
|
|
||
|
//
|
||
|
// Mark the file for deletion after we reboot,
|
||
|
// otherwise the file will never get removed.
|
||
|
//
|
||
|
MoveFileExW(csNewAppName.Get(), NULL, MOVEFILE_DELAY_UNTIL_REBOOT);
|
||
|
|
||
|
//
|
||
|
// We have successfully copied the exe to a new file with the specified name
|
||
|
// it is now safe to replace the lpApplicationName to our new file.
|
||
|
//
|
||
|
|
||
|
return ORIGINAL_API(CreateProcessA) (
|
||
|
csNewAppName.GetAnsi(),
|
||
|
lpCommandLine,
|
||
|
lpProcessAttributes,
|
||
|
lpThreadAttributes,
|
||
|
bInheritHandles,
|
||
|
dwCreationFlags,
|
||
|
lpEnvironment,
|
||
|
lpCurrentDirectory,
|
||
|
lpStartupInfo,
|
||
|
lpProcessInformation);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
CSTRING_CATCH
|
||
|
{
|
||
|
// Fall through
|
||
|
}
|
||
|
|
||
|
return ORIGINAL_API(CreateProcessA) (
|
||
|
lpApplicationName,
|
||
|
lpCommandLine,
|
||
|
lpProcessAttributes,
|
||
|
lpThreadAttributes,
|
||
|
bInheritHandles,
|
||
|
dwCreationFlags,
|
||
|
lpEnvironment,
|
||
|
lpCurrentDirectory,
|
||
|
lpStartupInfo,
|
||
|
lpProcessInformation);
|
||
|
}
|
||
|
|
||
|
#if TEST_MATCH
|
||
|
void
|
||
|
TestMatch(
|
||
|
const char* a,
|
||
|
const char* b
|
||
|
)
|
||
|
{
|
||
|
BOOL bMatch = PatternMatchA(a, b);
|
||
|
|
||
|
if (bMatch)
|
||
|
{
|
||
|
DPFN(
|
||
|
eDbgLevelSpew,
|
||
|
"[TestMatch] (%s) == (%s)\n", a, b);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
DPFN(
|
||
|
eDbgLevelSpew,
|
||
|
"[TestMatch] (%s) != (%s)\n", a, b);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void TestLots()
|
||
|
{
|
||
|
TestMatch("", "");
|
||
|
TestMatch("", "ABC");
|
||
|
TestMatch("*", "");
|
||
|
TestMatch("?", "");
|
||
|
TestMatch("abc", "ABC");
|
||
|
TestMatch("?", "ABC");
|
||
|
TestMatch("?bc", "ABC");
|
||
|
TestMatch("a?c", "ABC");
|
||
|
TestMatch("ab?", "ABC");
|
||
|
TestMatch("a??", "ABC");
|
||
|
TestMatch("?b?", "ABC");
|
||
|
TestMatch("??c", "ABC");
|
||
|
TestMatch("???", "ABC");
|
||
|
TestMatch("*", "ABC");
|
||
|
TestMatch("*.", "ABC");
|
||
|
TestMatch("*.", "ABC.");
|
||
|
TestMatch("*.?", "ABC.");
|
||
|
TestMatch("??*", "ABC");
|
||
|
TestMatch("*??", "ABC");
|
||
|
TestMatch("ABC", "ABC");
|
||
|
TestMatch(".*", "ABC");
|
||
|
TestMatch("?*", "ABC");
|
||
|
TestMatch("???*", "ABC");
|
||
|
TestMatch("*.txt", "ABC.txt");
|
||
|
TestMatch("*.txt", ".txt");
|
||
|
TestMatch("*.txt", ".abc");
|
||
|
TestMatch("*.txt", "txt.abc");
|
||
|
TestMatch("***", "");
|
||
|
TestMatch("***", "a");
|
||
|
TestMatch("***", "ab");
|
||
|
TestMatch("***", "abc");
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
|
||
|
BOOL
|
||
|
ParseCommandLine(void)
|
||
|
{
|
||
|
CSTRING_TRY
|
||
|
{
|
||
|
CStringToken csTok(COMMAND_LINE, ";");
|
||
|
|
||
|
g_csFilePattern = new CString;
|
||
|
g_csNewFileName = new CString;
|
||
|
|
||
|
if (g_csFilePattern &&
|
||
|
g_csNewFileName &&
|
||
|
csTok.GetToken(*g_csFilePattern) &&
|
||
|
csTok.GetToken(*g_csNewFileName))
|
||
|
{
|
||
|
return TRUE;
|
||
|
}
|
||
|
}
|
||
|
CSTRING_CATCH
|
||
|
{
|
||
|
// Do nothing
|
||
|
}
|
||
|
|
||
|
LOGN(
|
||
|
eDbgLevelError,
|
||
|
"[ParseCommandLine] Illegal command line");
|
||
|
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
BOOL
|
||
|
NOTIFY_FUNCTION(
|
||
|
DWORD fdwReason
|
||
|
)
|
||
|
{
|
||
|
if (fdwReason == DLL_PROCESS_ATTACH)
|
||
|
{
|
||
|
#if TEST_MATCH
|
||
|
TestLots();
|
||
|
#endif
|
||
|
|
||
|
return ParseCommandLine();
|
||
|
}
|
||
|
|
||
|
return TRUE;
|
||
|
}
|
||
|
|
||
|
|
||
|
HOOK_BEGIN
|
||
|
|
||
|
CALL_NOTIFY_FUNCTION
|
||
|
|
||
|
APIHOOK_ENTRY(KERNEL32.DLL, CreateProcessA)
|
||
|
|
||
|
HOOK_END
|
||
|
|
||
|
|
||
|
IMPLEMENT_SHIM_END
|
||
|
|