📄 pathproc.c
字号:
pusFilename = &ObjectName;
/*
* is the filename referenced in relation to some directory?
* if so, append the filename to a specified directory name
*/
if (ARGUMENT_PRESENT(ObjectAttributes->RootDirectory))
{
if (! NT_SUCCESS( ObReferenceObjectByHandle(ObjectAttributes->RootDirectory, 0, 0,
KernelMode, &Object, NULL) ))
{
ObDereferenceObject(Object);
FINISH_GetPathFromOA(("GetPathFromOA(): ObReferenceObjectByHandle() failed\n"));
}
if (Object == NULL)
{
ObDereferenceObject(Object);
FINISH_GetPathFromOA(("GetPathFromOA(): Object = NULL\n"));
}
if (! NT_SUCCESS( ObQueryNameString(Object, pONI, bMAX_PATH, &len) ))
{
ObDereferenceObject(Object);
FINISH_GetPathFromOA(("GetPathFromOA(): ObQueryNameString() failed\n"));
}
ObDereferenceObject(Object);
Object = NULL;
/* extracted directory name */
pusFilename = &pONI->Name;
/* is the directory name too long? */
if (pusFilename->Length >= bMAX_PATH - sizeof(WCHAR))
FINISH_GetPathFromOA(("GetPathFromOA(): directory name is too long\n"));
/*
* pusFilename points to a buffer of MAX_PATH size, ObQueryNameString() sets MaximumLength to the length
* of the directory name, we need to reset this back to MAX_PATH to be able to append a filename
* (reusing the same buffer)
*/
pusFilename->MaximumLength = bMAX_PATH;
pusFilename->Buffer[ pusFilename->Length / sizeof(WCHAR) ] = L'\\';
pusFilename->Length += sizeof(WCHAR);
if (RtlAppendUnicodeStringToString(pusFilename, ObjectAttributes->ObjectName) == STATUS_BUFFER_TOO_SMALL)
{
LOG(LOG_SS_PATHPROC, LOG_PRIORITY_VERBOSE, ("GetPathFromOA: 1 %S\n", pusFilename->Buffer));
LOG(LOG_SS_PATHPROC, LOG_PRIORITY_VERBOSE, ("GetPathFromOA: 2 %S\n", ObjectAttributes->ObjectName->Buffer));
FINISH_GetPathFromOA(("GetPathFromOA(): RtlAppendUnicodeStringToString() = STATUS_BUFFER_TOO_SMALL\n"));
}
}
if (ResolveLinks == TRUE)
{
ret = ResolveFilenameW(pusFilename, OutBuffer, OutBufferSize);
}
//XXX
if (NT_SUCCESS(RtlUnicodeStringToAnsiString(&name, pusFilename, TRUE)))
{
if (ResolveLinks == TRUE)
{
ret = ResolveFilename(name.Buffer, OutBuffer, OutBufferSize);
}
else
{
if (name.Length >= OutBufferSize - 1)
{
LOG(LOG_SS_PATHPROC, LOG_PRIORITY_DEBUG, ("GetPathFromOA: Pathname too long %d\n", name.Length));
OutBuffer[0] = 0;
ret = FALSE;
}
else
{
strcpy(OutBuffer, name.Buffer);
ret = TRUE;
}
}
RtlFreeAnsiString(&name);
}
// LOG(LOG_SS_PATHPROC, LOG_PRIORITY_VERBOSE, ("%d GetPathFromOA: %s (%S)\n", (ULONG) PsGetCurrentProcessId(), OutBuffer, pusFilename->Buffer));
return ret;
}
/*
* ConvertLongFileNameToShort()
*
* Description:
* Converts long windows filenames to their DOS short equivalent filenames
* (i.e. c:\program files to c:\progra~1).
*
* Parameters:
* LongFileName - long filename buffer.
* ShortFileName - output buffer where a short filename is written to.
* ShortFileNameSize - size of an output buffer (in bytes).
*
* Returns:
* TRUE to indicate success, FALSE if failed.
*/
#if 0
BOOLEAN
ConvertLongFileNameToShort(IN PCHAR LongFileName, OUT PCHAR ShortFileName, IN USHORT ShortFileNameSize)
{
int LongFileNameIndex = 0, ShortFileNameIndex = 0, CurrentFileNameLength, TotalLength, ExtensionLength, NumberOfSpaces;
BOOLEAN ProcessingExtension = FALSE;
CHAR ch, Extension[3];
if (LongFileName == NULL)
return FALSE;
TotalLength = strlen(LongFileName);
/* if the filename does not start with X:\ then assume \device\blah\ format and skip over the first 2 slashes */
if (LongFileName[0] == '\\')
{
int Slashes = 0;
do
{
if ( (ch = ShortFileName[ShortFileNameIndex++] = LongFileName[LongFileNameIndex++]) == '\0') return TRUE;
if (ch == '\\') ++Slashes;
} while (Slashes != 3);
}
for (NumberOfSpaces = ExtensionLength = CurrentFileNameLength = 0; ; LongFileNameIndex++)
{
/* if we finished traversing the entire directory path or reached a '\' then process the filename (append the extension if necessary) */
if (LongFileNameIndex == TotalLength || LongFileName[LongFileNameIndex] == '\\')
{
/*
* if the filename is longer than 8 chars or extension is longer than 3 chars then we need
* to create a 6 char filename followed by a '~1' and the first 3 chars of the last extension
*/
if (CurrentFileNameLength > 8 || ExtensionLength > 3 || NumberOfSpaces > 0)
{
CurrentFileNameLength -= NumberOfSpaces;
if (CurrentFileNameLength > 7)
{
ShortFileName[ShortFileNameIndex - 2] = '~';
ShortFileName[ShortFileNameIndex - 1] = '1';
}
else if (CurrentFileNameLength == 7)
{
ShortFileName[ShortFileNameIndex - 1] = '~';
ShortFileName[ShortFileNameIndex++] = '1';
}
else
{
ShortFileName[ShortFileNameIndex++] = '~';
ShortFileName[ShortFileNameIndex++] = '1';
}
}
if (ExtensionLength > 0)
{
ShortFileName[ShortFileNameIndex++] = '.';
ShortFileName[ShortFileNameIndex++] = Extension[0];
if (ExtensionLength > 1)
{
ShortFileName[ShortFileNameIndex++] = Extension[1];
if (ExtensionLength > 2)
ShortFileName[ShortFileNameIndex++] = Extension[2];
}
ExtensionLength = 0;
ProcessingExtension = FALSE;
}
/* if we are done traversing the entire path than we can bail */
if (LongFileNameIndex == TotalLength)
break;
ShortFileName[ShortFileNameIndex++] = '\\';
NumberOfSpaces = CurrentFileNameLength = 0;
continue;
}
if (LongFileName[LongFileNameIndex] == '.')
{
ProcessingExtension = TRUE;
ExtensionLength = 0;
continue;
}
if (ProcessingExtension == TRUE)
{
if (ExtensionLength++ < 3)
Extension[ExtensionLength - 1] = LongFileName[LongFileNameIndex];
continue;
}
if (((CurrentFileNameLength++) - NumberOfSpaces) < 8)
{
if (LongFileName[LongFileNameIndex] != ' ')
ShortFileName[ShortFileNameIndex++] = LongFileName[LongFileNameIndex];
else
++NumberOfSpaces;
}
}
ShortFileName[ShortFileNameIndex++] = 0;
return TRUE;
}
#endif
/*
* GetNameFromHandle()
*
* Description:
* Resolve an object handle to an object name.
*
* Parameters:
* ObjectHandle - handle of an object whose name we are trying to obtain.
* OutBuffer - output buffer where an object name will be saved to.
* OutBufferSize - size of an output buffer (in bytes).
*
* Returns:
* TRUE to indicate success, FALSE if failed.
*/
PWSTR
GetNameFromHandle(IN HANDLE ObjectHandle, OUT PWSTR OutBuffer, IN USHORT OutBufferSize)
{
PVOID Object = NULL;
NTSTATUS rc;
POBJECT_NAME_INFORMATION pONI = (POBJECT_NAME_INFORMATION) OutBuffer;
ULONG len;
rc = ObReferenceObjectByHandle(ObjectHandle, GENERIC_READ, NULL, KernelMode, &Object, NULL);
if (! NT_SUCCESS(rc))
{
LOG(LOG_SS_PATHPROC, LOG_PRIORITY_DEBUG, ("%d GetNameFromHandle: ObReferenceObjectByHandle failed\n", (ULONG) PsGetCurrentProcessId()));
return NULL;
}
rc = ObQueryNameString(Object, pONI, OutBufferSize - sizeof(OBJECT_NAME_INFORMATION)*sizeof(WCHAR), &len);
if (! NT_SUCCESS(rc))
{
LOG(LOG_SS_PATHPROC, LOG_PRIORITY_VERBOSE, ("%d GetNameFromHandle: ObQueryNameString failed\n", (ULONG) PsGetCurrentProcessId()));
return NULL;
}
// _snprintf(OutBuffer, OutBufferSize, "%S", pONI->Name.Buffer);
// OutBuffer[OutBufferSize - 1] = 0;
// LOG(LOG_SS_PATHPROC, LOG_PRIORITY_DEBUG, ("%S (%s)\n", pONI->Name.Buffer, OutBuffer));
ObDereferenceObject(Object);
return pONI->Name.Buffer;
// return TRUE;
}
/*
* StripFileMacros()
*
* Description:
* Strip file names of %SystemRoot% and %SystemDrive% macros as well as any specifications.
*
* Parameters:
* Path - ASCII file path to parse.
* Buffer - pointer to an Object where the final result will be saved.
* BufferSize - size of the output Buffer.
*
* Returns:
* Pointer to a stripped ASCII path.
*/
PCHAR
StripFileMacros(IN PCHAR Path, OUT PCHAR Buffer, IN USHORT BufferSize)
{
if (_strnicmp(Path, "%systemdrive%:", 14) == 0)
{
return Path + 14;
}
if (_strnicmp(Path, "%systemroot%\\", 13) == 0)
{
if (_snprintf(Buffer, MAX_PATH, "%s%s", SystemRootUnresolved, Path + 12) < 0)
return NULL;
Path = Buffer;
}
if (Path[1] == ':' && Path[2] == '\\' && (isalpha(Path[0]) || Path[0] == '?' || Path[0] == '*'))
{
Path += 2;
}
return Path;
}
/*
* FixupFilename()
*
* Description:
* Get canonical name for a file (without the drive specification, i.e. \windows\blah.exe)
*
* Parameters:
* szFileName - filename to resolve.
* szResult - output buffer.
* szResultSize - size of an output buffer.
*
* Returns:
* TRUE to indicate success, FALSE if failed.
*/
BOOLEAN
FixupFilename(IN PCHAR szFileName, OUT PCHAR szResult, IN USHORT szResultSize)
{
/* skip over \??\ */
if (_strnicmp(szFileName, "\\??\\", 4) == 0)
{
szFileName += 4;
}
/* replace "\SystemRoot" references with the actual system root directory */
if (_strnicmp(szFileName, "\\SystemRoot\\", 12) == 0)
{
_snprintf(szResult, szResultSize, "%s\\%s", SystemRootDirectory, szFileName + 12);
szResult[ szResultSize - 1 ] = 0;
return TRUE;
}
/* skip over X: drive specifications */
if (isalpha(szFileName[0]) && szFileName[1] == ':' && szFileName[2] == '\\')
{
szFileName += 2;
}
strncpy(szResult, szFileName, szResultSize);
szResult[ szResultSize - 1 ] = 0;
return TRUE;
}
/*
* AreMalformedExtensionsAllowed()
*
* Description:
* Check whether the current process is allowed to run binaries with malformed file extensions.
*
* Parameters:
* None.
*
* Returns:
* FALSE if binaries with malformed extensions are not allowed to run. TRUE otherwise.
*/
BOOLEAN
AreMalformedExtensionsAllowed()
{
PIMAGE_PID_ENTRY CurrentProcess;
BOOLEAN MalformedExtensionsAllowed = FALSE;
/* check the global policy first */
if (! IS_EXTENSION_PROTECTION_ON(gSecPolicy))
return TRUE;
/* now check the process specific policy */
CurrentProcess = FindImagePidEntry(CURRENT_PROCESS_PID, 0);
if (CurrentProcess != NULL)
{
MalformedExtensionsAllowed = ! IS_EXTENSION_PROTECTION_ON(CurrentProcess->SecPolicy);
}
else
{
LOG(LOG_SS_PATHPROC, LOG_PRIORITY_DEBUG, ("%d AreMalformedExtensionsAllowed: CurrentProcess = NULL!\n", (ULONG) PsGetCurrentProcessId()));
}
return MalformedExtensionsAllowed;
}
/*
* VerifyExecutableName()
*
* Description:
* Make sure the executed binary does not have a funny filename.
* Look out for non-standard extensions (.exe, etc) and double
* extensions that are commonly "ab"used by malware.
*
* Parameters:
* szFileName - filename to verify.
*
* Returns:
* TRUE to indicate success, FALSE if failed.
*/
#define CHECK_LEARNING_MODE() \
if (LearningMode == TRUE) \
{ \
TURN_EXTENSION_PROTECTION_OFF(NewPolicy); \
return TRUE; \
}
BOOLEAN
VerifyExecutableName(IN PCHAR szFileName)
{
SHORT i, len;
BOOLEAN FirstExtension = TRUE;
if (LearningMode == FALSE && AreMalformedExtensionsAllowed() == TRUE)
{
/* no need to check anything further, malformed extensions are allowed */
return TRUE;
}
if ((len = (SHORT) strlen(szFileName)) == 0)
return TRUE;
for (i = len - 1; i >= 0; i--)
{
/* bail out once we reach the end of the filename */
if (szFileName[i] == '\\')
break;
if (szFileName[i] == '.')
{
if (FirstExtension == FALSE)
{
CHECK_LEARNING_MODE();
LOG(LOG_SS_PATHPROC, LOG_PRIORITY_DEBUG, ("VerifyExecutableName: Executing a binary with more than one extension '%s'\n", szFileName));
LogAlert(ALERT_SS_PROCESS, OP_PROC_EXECUTE, ALERT_RULE_PROCESS_EXEC_2EXTS, ACTION_LOG, ALERT_PRIORITY_HIGH, NULL, 0, szFileName);
return FALSE;
}
if (len - i != 4)
{
CHECK_LEARNING_MODE();
LOG(LOG_SS_PATHPROC, LOG_PRIORITY_DEBUG, ("VerifyExecutableName: Executing a binary with an unknown extension '%s'\n", szFileName));
LogAlert(ALERT_SS_PROCESS, OP_PROC_EXECUTE, ALERT_RULE_PROCESS_EXEC_UNKNOWN, ACTION_LOG, ALERT_PRIORITY_HIGH, NULL, 0, szFileName);
return FALSE;
}
else
{
if (_stricmp(szFileName + i + 1, "exe") != 0 &&
_stricmp(szFileName + i + 1, "com") != 0 &&
_stricmp(szFileName + i + 1, "bat") != 0 &&
_stricmp(szFileName + i + 1, "scr") != 0 &&
_stricmp(szFileName + i + 1, "dir") != 0 &&
_stricmp(szFileName + i + 1, "tmp") != 0 &&
_stricmp(szFileName + i + 1, "_mp") != 0)
{
CHECK_LEARNING_MODE();
LOG(LOG_SS_PATHPROC, LOG_PRIORITY_DEBUG, ("VerifyExecutableName: Executing a binary with an unknown extension '%s'\n", szFileName));
LogAlert(ALERT_SS_PROCESS, OP_PROC_EXECUTE, ALERT_RULE_PROCESS_EXEC_UNKNOWN, ACTION_LOG, ALERT_PRIORITY_HIGH, NULL, 0, szFileName);
return FALSE;
}
}
FirstExtension = FALSE;
}
}
if (FirstExtension == TRUE)
{
CHECK_LEARNING_MODE();
LOG(LOG_SS_PATHPROC, LOG_PRIORITY_DEBUG, ("VerifyExecutableName: Executing binary without an extension '%s'\n", szFileName));
LogAlert(ALERT_SS_PROCESS, OP_PROC_EXECUTE, ALERT_RULE_PROCESS_EXEC_NOEXT, ACTION_LOG, ALERT_PRIORITY_HIGH, NULL, 0, szFileName);
return FALSE;
}
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -