Windows2003-3790/windows/appcompat/shims/general/derandomizeexename.cpp
2020-09-30 16:53:55 +02:00

242 lines
6.1 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