Еще один способ разделения, если у команд нет пробелов, - это использовать ' '
в качестве разделителя и отбрасывать пустые записи:
var maliciousConsoleCommands = commands.Split(new[]{',',' '},StringSplitOptions.RemoveEmptyEntries)
.ToArray();
Это позволяет избежать временных строк, генерируемых каждой командой обработки строк.
Чтобы ваш код работал, вы должны использовать Contains
для каждой команды вместо StartWith
:
var isSuspicious = maliciousCommands.Any(cmd=>input.Contains(cmd));
Или даже:
var isSuspicious = maliciousCommands.Any(input.Contains);
Это может быть довольно медленным, если у вас несколько команд или если введенный текст большой
Альтернативное регулярное выражение
Гораздо более быстрый способ - использовать регулярное выражение. Это выполняет лот быстрее, чем поиск по отдельным ключевым словам:
var regex=new Regex("net|netsh|tasklist");
var isSuspicious=regex.IsMatch(inputTxt);
Регулярные выражения являются поточно-ориентированными, что означает, что они могут быть созданы один раз и повторно использованы различными потоками / запросами.
Используя Match/Matches
вместо IsMatch
, регулярное выражение может возвращать фактические обнаруженные ключевые слова:
var detection=regex.Match(inputTxt);
if (detection.Success)
{
var detectedKeyword=detection.Value;
....
}
Преобразование исходного списка, разделенного запятыми, в регулярное выражение можно выполнить с помощью одного String.Replace(", ")
или другого регулярного выражения, которое может обрабатывать любой символ пробела:
string commands = "net , netsh, \ttasklist";
var pattern=Regex.Replace(commands,@"\s*,\s*","|").Dump();
var regex=new Regex(pattern);
Обнаружение только целых слов
И Contains
, и исходное регулярное выражение будет соответствовать tasklist1
, а также tasklist
. Можно сопоставлять только целые слова, если шаблон окружен разделителем слов, \b
:
@"\b(" + pattern + @")\b"
Это будет соответствовать tasklist
и net
, но отклонить tasklist1