1mod command;
2mod error;
3mod predicates;
4mod script_result;
5mod stream_message;
6mod token;
7mod value;
8mod variables;
9
10use std::collections::HashMap;
11
12pub(crate) use command::CommandError;
13use command::{Command, CommandElem};
14pub(crate) use stream_message::StreamMessage;
15use value::{RuntimeObject, ScriptBlock, ValResult};
16use variables::Scope;
17type ParserResult<T> = core::result::Result<T, ParserError>;
18use error::ParserError;
19type PestError = pest::error::Error<Rule>;
20use pest::Parser;
21use pest_derive::Parser;
22use predicates::{ArithmeticPred, BitwisePred, LogicalPred, StringPred};
23pub use script_result::{PsValue, ScriptResult};
24pub use token::{Token, Tokens};
25pub(crate) use value::{Val, ValType};
26pub use variables::Variables;
27use variables::{VarName, VariableError};
28
29use crate::parser::command::CommandOutput;
30
31type Pair<'i> = ::pest::iterators::Pair<'i, Rule>;
32type Pairs<'i> = ::pest::iterators::Pairs<'i, Rule>;
33
34pub(crate) const NEWLINE: &str = "\n";
35
36macro_rules! check_rule {
37 ($pair:expr, $rule:pat) => {
38 if !matches!($pair.as_rule(), $rule) {
39 panic!("rule: {:?}", $pair.as_rule());
40 }
41 };
42}
43
44#[derive(Parser)]
45#[grammar = "powershell.pest"]
46pub struct PowerShellSession {
47 variables: Variables,
48 tokens: Tokens,
49 errors: Vec<ParserError>,
50 output: Vec<StreamMessage>,
51 deobfuscated_statements: Vec<String>,
52}
53
54impl Default for PowerShellSession {
55 fn default() -> Self {
56 Self::new()
57 }
58}
59
60impl<'a> PowerShellSession {
61 pub fn new() -> Self {
81 Self {
82 variables: Variables::new(),
83 tokens: Tokens::new(),
84 errors: Vec::new(),
85 output: Vec::new(),
86 deobfuscated_statements: Vec::new(),
87 }
88 }
89
90 pub fn with_variables(mut self, variables: Variables) -> Self {
115 self.variables = variables;
116 self
117 }
118
119 pub fn safe_eval(&mut self, script: &str) -> Result<String, ParserError> {
151 Ok(self.parse_input(script)?.result().to_string())
152 }
153
154 pub fn parse_input(&mut self, input: &str) -> Result<ScriptResult, ParserError> {
186 let mut pairs = PowerShellSession::parse(Rule::program, input)?;
187 let program_token = pairs.next().expect("");
188
189 let mut script_last_output = Val::default();
191
192 if let Rule::program = program_token.as_rule() {
193 let pairs = program_token.into_inner();
194
195 for token in pairs {
198 let token_str = token.as_str();
199 let result = match token.as_rule() {
200 Rule::pipeline => {
201 let mut pairs = token.into_inner();
204 let token = pairs.next().unwrap();
205
206 match token.as_rule() {
207 Rule::assignment_exp => {
208 let result = self.eval_assigment_exp(token);
209 result.map(|_| Val::Null)
212 }
213 Rule::pipeline_with_tail => self.eval_pipeline_with_tail(token),
214 _ => panic!("not possible: {:?}", token.as_rule()),
215 }
216 }
217 Rule::if_statement => self.eval_if_statement(token),
218 Rule::statement_terminator => continue,
219 Rule::EOI => break,
220 _ => {
221 log::error!("parse_input not implemented: {:?}", token.as_rule());
222 Err(ParserError::NotImplemented(format!(
223 "Not implemented: {:?}",
224 token.as_rule()
225 )))
226 }
227 };
228
229 self.variables.set_status(result.is_ok());
230
231 script_last_output = match result {
232 Ok(val) => {
233 if val != Val::Null {
234 self.output.push(val.display().into());
235 }
236
237 val
238 }
239 Err(e) => {
240 self.errors.push(e);
241 self.deobfuscated_statements.push(token_str.into());
242 Val::Null
243 }
244 };
245 }
246 }
247
248 Ok(ScriptResult::new(
249 script_last_output,
250 std::mem::take(&mut self.output),
251 std::mem::take(&mut self.deobfuscated_statements),
252 std::mem::take(&mut self.tokens),
253 std::mem::take(&mut self.errors),
254 ))
255 }
256
257 pub(crate) fn eval_if_statement(&mut self, token: Pair<'a>) -> ParserResult<Val> {
258 check_rule!(token, Rule::if_statement);
259 let mut pair = token.into_inner();
260 let condition_token = pair.next().unwrap();
261 let true_token = pair.next().unwrap();
262 let condition_val = self.eval_pipeline(condition_token)?;
263 let res = if condition_val.cast_to_bool() {
264 self.eval_statement_block(true_token)?
265 } else {
266 if let Some(mut token) = pair.next() {
267 if token.as_rule() == Rule::elseif_clauses {
268 for else_if in token.into_inner() {
269 let mut pairs = else_if.into_inner();
270 let condition_token = pairs.next().unwrap();
271 let statement_token = pairs.next().unwrap();
272 let condition_val = self.eval_pipeline(condition_token)?;
273 if condition_val.cast_to_bool() {
274 return self.eval_statement_block(statement_token);
275 }
276 }
277 let Some(token2) = pair.next() else {
278 return Ok(Val::Null);
279 };
280 token = token2;
281 }
282 if token.as_rule() == Rule::else_condition {
283 let statement_token = token.into_inner().next().unwrap();
284 self.eval_statement_block(statement_token)?
285 } else {
286 Val::Null
287 }
288 } else {
289 Val::Null
290 }
291 };
292
293 Ok(res)
294 }
295
296 pub(crate) fn eval_script_block(
297 &mut self,
298 input: &ScriptBlock,
299 ps_item: &Val,
300 ) -> ParserResult<bool> {
301 self.variables.set_ps_item(ps_item.clone());
302 let mut new_session = PowerShellSession::new().with_variables(self.variables.clone());
303 let res = new_session
304 .parse_input(input.0.as_str())?
305 .result()
306 .is_true();
307 self.variables.reset_ps_item();
308 Ok(res)
309 }
310
311 fn eval_statement(&mut self, token: Pair<'a>) -> ParserResult<Val> {
312 match token.as_rule() {
313 Rule::pipeline => self.eval_pipeline(token),
314 Rule::if_statement => self.eval_if_statement(token),
315 _ => Err(ParserError::NotImplemented(format!(
316 "Not implemented: {:?}",
317 token.as_rule()
318 )))?,
319 }
320 }
321
322 fn safe_eval_sub_expr(&mut self, token: Pair<'a>) -> ParserResult<Val> {
323 match self.eval_statements(token.clone()) {
324 Ok(vals) => Ok(Val::Array(vals)),
325 Err(err) => {
326 self.errors.push(err);
327 Ok(Val::ScriptText(token.as_str().to_string()))
328 }
329 }
330 }
331
332 fn eval_statement_block(&mut self, token: Pair<'a>) -> ParserResult<Val> {
333 Ok(self
334 .safe_eval_statements(token)?
335 .iter()
336 .last()
337 .cloned()
338 .unwrap_or(Val::Null))
339 }
340
341 fn eval_statements(&mut self, token: Pair<'a>) -> ParserResult<Vec<Val>> {
342 let pairs = token.into_inner();
344 let mut statements = vec![];
345
346 for token in pairs {
347 let s = self.eval_statement(token)?;
348 statements.push(s);
349 }
350 Ok(statements)
351 }
352
353 fn safe_eval_statements(&mut self, token: Pair<'a>) -> ParserResult<Vec<Val>> {
354 let pairs = token.into_inner();
356 let mut statements = vec![];
357
358 for token in pairs {
359 match self.eval_statement(token.clone()) {
360 Ok(s) => statements.push(s),
361 Err(err) => {
362 self.errors.push(err);
363 statements.push(Val::ScriptText(token.as_str().to_string()));
364 }
365 }
366 }
367 Ok(statements)
368 }
369
370 fn parse_dq(&mut self, token: Pair<'a>) -> ParserResult<String> {
371 let mut res_str = String::new();
372 let pairs = token.into_inner();
373 for token in pairs {
374 let token = token.into_inner().next().unwrap();
375 let s = match token.as_rule() {
376 Rule::variable => self.get_variable(token)?.cast_to_string(),
377 Rule::sub_expression => self.safe_eval_sub_expr(token)?.cast_to_string(),
378 Rule::backtick_escape => token
379 .as_str()
380 .strip_prefix("`")
381 .unwrap_or_default()
382 .to_string(),
383 _ => token.as_str().to_string(),
384 };
385 res_str.push_str(s.as_str());
386 }
387 Ok(res_str)
388 }
389
390 fn eval_string_literal(&mut self, token: Pair<'a>) -> ParserResult<Val> {
391 check_rule!(token, Rule::string_literal);
392 let mut pair = token.into_inner();
393 let token = pair.next().unwrap();
394 let cloned_token = token.clone();
395
396 let mut is_expandable = false;
397 let res = match token.as_rule() {
398 Rule::doublequoted_string_literal | Rule::doublequoted_multiline_string_literal => {
399 is_expandable = true;
400 self.parse_dq(token)?
401 }
402 Rule::singlequoted_string_literal => {
403 if let Some(stripped_prefix) = token.as_str().to_string().strip_prefix("'") {
404 if let Some(stripped_suffix) = stripped_prefix.to_string().strip_suffix("'") {
405 stripped_suffix.to_string()
406 } else {
407 panic!("no suffix")
408 }
409 } else {
410 panic!("no prefix")
411 }
412 }
413 Rule::singlequoted_multiline_string_literal => {
414 let mut res_str = String::new();
415 let pairs = token.into_inner();
416 for token in pairs {
417 res_str.push_str(token.as_str());
418 }
419 res_str
420 }
421 _ => {
422 panic!("eval_string_literal - token.rule(): {:?}", token.as_rule());
423 }
424 };
425 let ps_token = if is_expandable {
426 Token::StringExpandable(cloned_token.as_str().to_string(), res.clone())
427 } else {
428 Token::String(cloned_token.as_str().to_string())
429 };
430 self.tokens.push(ps_token);
431
432 Ok(Val::String(res.into()))
433 }
434
435 fn get_variable(&mut self, token: Pair<'a>) -> ParserResult<Val> {
436 check_rule!(token, Rule::variable);
437 let var_name = Self::parse_variable(token)?;
438 let Some(var) = self.variables.get(&var_name) else {
439 return Err(ParserError::VariableError(VariableError::NotDefined(
440 var_name.name,
441 )));
442 };
443 Ok(var)
444 }
445
446 fn parse_variable(token: Pair<'a>) -> ParserResult<VarName> {
447 check_rule!(token, Rule::variable);
448 let mut pair = token.into_inner();
449 let token = pair.next().unwrap();
450
451 Ok(match token.as_rule() {
452 Rule::special_variable => VarName::new(Scope::Special, token.as_str().to_string()),
453 Rule::parenthesized_variable => {
454 Self::parse_variable(token.into_inner().next().unwrap())?
455 }
456 Rule::braced_variable => {
457 let token = token.into_inner().next().unwrap();
458 let var = token.as_str().to_ascii_lowercase();
459 let splits: Vec<&str> = var.split(":").collect();
460 if splits.len() == 2 {
461 VarName::new(Scope::from(splits[0]), splits[1].to_string())
462 } else {
463 VarName::new(Scope::Global, var)
464 }
465 }
466 Rule::scoped_variable => {
467 let mut pairs = token.into_inner();
468 let mut token = pairs.next().unwrap();
469
470 let scope = if token.as_rule() == Rule::scope_keyword {
471 let scope = token.as_str().to_ascii_lowercase();
472 token = pairs.next().unwrap();
473 check_rule!(token, Rule::var_name);
474 Scope::from(scope.as_str())
475 } else {
476 Scope::Global
477 };
478 VarName::new(scope, token.as_str().to_ascii_lowercase())
479 }
480 _ => {
481 panic!("token.rule(): {:?}", token.as_rule());
482 }
483 })
484 }
485
486 fn eval_expression_with_unary_operator(&mut self, token: Pair<'a>) -> ParserResult<Val> {
487 check_rule!(token, Rule::expression_with_unary_operator);
488 let mut pair = token.into_inner();
489 let token = pair.next().unwrap();
490
491 let res = match token.as_rule() {
492 Rule::pre_inc_expression => {
493 let variable_token = token.into_inner().next().unwrap();
494 let var_name = Self::parse_variable(variable_token)?;
495 let mut var = self.variables.get(&var_name).unwrap_or_default();
496 var.inc()?;
497
498 self.variables.set(&var_name, var.clone())?;
499 var
500 }
501 Rule::pre_dec_expression => {
502 let variable_token = token.into_inner().next().unwrap();
503 let var_name = Self::parse_variable(variable_token)?;
504 let mut var = self.variables.get(&var_name).unwrap_or_default();
505 var.dec()?;
506
507 self.variables.set(&var_name, var.clone())?;
508 var
509 }
510 Rule::cast_expression => self.eval_cast_expression(token)?,
511 Rule::negate_op => {
512 let unary_token = pair.next().unwrap();
513 let unary = self.eval_unary_exp(unary_token)?;
514 Val::Bool(!unary.cast_to_bool())
515 }
516 Rule::bitwise_negate_op => {
517 let unary_token = pair.next().unwrap();
518 let unary = self.eval_unary_exp(unary_token)?;
519 Val::Int(!unary.cast_to_int()?)
520 }
521 _ => {
522 panic!("token.rule(): {:?}", token.as_rule());
523 }
524 };
525
526 Ok(res)
527 }
528
529 fn eval_argument_list(&mut self, token: Pair<'a>) -> ParserResult<Vec<Val>> {
530 check_rule!(token, Rule::argument_list);
531 let pairs = token.into_inner();
532
533 let mut args = Vec::new();
534 for token in pairs {
535 args.push(self.eval_expression(token)?);
536 }
537
538 Ok(args)
539 }
540
541 fn eval_member_access(&mut self, token: Pair<'a>) -> ParserResult<String> {
542 let member_name_token = token.into_inner().next().unwrap();
544 let member_name = member_name_token.as_str().to_ascii_lowercase();
545
546 Ok(member_name)
547 }
548
549 fn method_is_static(&mut self, token: Pair<'a>) -> bool {
550 check_rule!(token, Rule::method_invocation);
551 let mut pairs = token.into_inner();
552
553 let access = pairs.next().unwrap();
554 match access.as_rule() {
555 Rule::member_access => false,
556 Rule::static_access => true,
557 _ => todo!(),
558 }
559 }
560
561 fn eval_method_invokation(&mut self, token: Pair<'a>) -> ParserResult<(String, Vec<Val>)> {
562 check_rule!(token, Rule::method_invocation);
563 let token_string = token.as_str().to_string();
564
565 let mut pairs = token.into_inner();
566
567 let access = pairs.next().unwrap();
568 let method_name = self.eval_member_access(access)?;
570
571 let args = if let Some(token) = pairs.next() {
572 check_rule!(token, Rule::argument_list);
573 self.eval_argument_list(token)?
574 } else {
575 Vec::new()
576 };
577
578 self.tokens.push(Token::Function(
579 token_string,
580 method_name.clone(),
581 args.clone().iter().map(|arg| arg.clone().into()).collect(),
582 ));
583 Ok((method_name, args))
584 }
585
586 fn eval_access(&mut self, token: Pair<'a>) -> ParserResult<Val> {
587 fn get_member_name(token: Pair<'_>) -> &'_ str {
588 token.into_inner().next().unwrap().as_str()
589 }
590 check_rule!(token, Rule::access);
591 let mut pairs = token.into_inner();
592 let token = pairs.next().unwrap();
593
594 let mut object = self.eval_value(token)?;
595
596 for token in pairs {
597 match token.as_rule() {
598 Rule::static_access => {
599 object = object.get_static_member(get_member_name(token))?;
600 }
601 Rule::member_access => {
602 object = object.get_member(get_member_name(token))?;
603 }
604 Rule::method_invocation => {
605 let static_method = self.method_is_static(token.clone());
606 let (function_name, args) = self.eval_method_invokation(token)?;
607 log::trace!("Method: {:?} {:?}", &function_name, &args);
608 object = if static_method {
609 let call = object.get_static_fn(function_name.as_str())?;
610 call(args)?
611 } else {
612 let call = object.get_method(function_name.as_str())?;
613 call(object, args)?
614 };
615 }
616 Rule::element_access => {
617 let mut pairs = token.into_inner();
618 let index_token = pairs.next().unwrap();
619 check_rule!(index_token, Rule::expression);
620 let index = self.eval_expression(index_token)?;
621 object = object.get_index(index)?;
622 }
623 _ => {
624 panic!("token.rule(): {:?}", token.as_rule());
625 }
626 }
627 }
628 log::debug!("Success eval_access: {:?}", object);
629 Ok(object)
630 }
631
632 fn parse_access(&mut self, token: Pair<'a>) -> ParserResult<Val> {
633 check_rule!(token, Rule::access);
634 let mut pairs = token.into_inner();
635 let token = pairs.next().unwrap();
636
637 let mut object = token.as_str().to_string();
638
639 for token in pairs {
640 match token.as_rule() {
641 Rule::static_access => {
642 object.push_str("::");
643 object.push_str(token.as_str());
644 }
645 Rule::member_access => {
646 object.push_str(token.as_str());
648 }
649 Rule::method_invocation => {
650 let static_method = self.method_is_static(token.clone());
651 let (method_name, args) = self.eval_method_invokation(token)?;
652
653 let separator = if static_method { "::" } else { "." };
654 object = format!(
655 "{}{separator}{}({:?})",
656 object,
657 method_name.to_ascii_lowercase(),
658 args
659 )
660 }
661 Rule::element_access => {
662 let mut pairs = token.into_inner();
663 let index_token = pairs.next().unwrap();
664 check_rule!(index_token, Rule::expression);
665 let index = self.eval_expression(index_token)?;
666 object = format!("{}[{}]", object, index);
667 }
668 _ => {
669 panic!("parse_access token.rule(): {:?}", token.as_rule());
670 }
671 }
672 }
673 Ok(Val::String(object.into()))
674 }
675
676 fn eval_primary_expression(&mut self, token: Pair<'a>) -> ParserResult<Val> {
677 check_rule!(token, Rule::primary_expression);
678 let mut pair = token.into_inner();
679 let token = pair.next().unwrap();
680 let res = match token.as_rule() {
681 Rule::access => match self.eval_access(token.clone()) {
682 Ok(res) => res,
683 Err(err) => {
684 log::info!("eval_access error: {:?}", err);
685 self.errors.push(err);
686 self.parse_access(token)?
687 }
688 },
689 Rule::value => self.eval_value(token)?,
690 Rule::post_inc_expression => {
691 let variable_token = token.into_inner().next().unwrap();
692 let var_name = Self::parse_variable(variable_token)?;
693 let mut var = self.variables.get(&var_name).unwrap_or_default();
694 let var_to_return = var.clone();
695
696 var.inc()?;
697 self.variables.set(&var_name, var.clone())?;
698
699 var_to_return
701 }
702 Rule::post_dec_expression => {
703 let variable_token = token.into_inner().next().unwrap();
704 let var_name = Self::parse_variable(variable_token)?;
705 let mut var = self.variables.get(&var_name).unwrap_or_default();
706 let var_to_return = var.clone();
707
708 var.dec()?;
709 self.variables.set(&var_name, var.clone())?;
710
711 var_to_return
712 }
713 _ => {
714 panic!(
715 "eval_primary_expression: rule: {:?} str: {}",
716 token.as_rule(),
717 token.as_str()
718 );
719 }
720 };
721
722 Ok(res)
723 }
724
725 fn eval_type_literal(&mut self, token: Pair<'a>) -> ParserResult<ValType> {
726 check_rule!(token, Rule::type_literal);
727
728 let token = token.into_inner().next().unwrap();
729 check_rule!(token, Rule::type_spec);
730 Ok(ValType::cast(token.as_str())?)
731 }
732
733 fn parse_script_block_expression(&mut self, token: Pair<'a>) -> ParserResult<Val> {
734 check_rule!(token, Rule::script_block_expression);
735
736 let mut pairs = token.into_inner();
737 let token = pairs.next().unwrap();
738
739 Ok(Val::ScriptBlock(ScriptBlock(token.as_str().to_string())))
740 }
741
742 fn eval_hash_key(&mut self, token: Pair<'a>) -> ParserResult<String> {
743 check_rule!(token, Rule::key_expression);
744 let mut pairs = token.into_inner();
745 let key_token = pairs.next().unwrap();
746
747 Ok(match key_token.as_rule() {
748 Rule::simple_name => key_token.as_str().to_ascii_lowercase(),
749 Rule::unary_exp => self
750 .eval_unary_exp(key_token)?
751 .cast_to_string()
752 .to_ascii_lowercase(),
753 _ => {
754 panic!("key_token.rule(): {:?}", key_token.as_rule());
755 }
756 })
757 }
758
759 fn eval_hash_entry(&mut self, token: Pair<'a>) -> ParserResult<(String, Val)> {
760 check_rule!(token, Rule::hash_entry);
761
762 let mut pairs = token.into_inner();
763 let token_key = pairs.next().unwrap();
764 let token_value = pairs.next().unwrap();
765
766 Ok((
767 self.eval_hash_key(token_key)?,
768 self.eval_statement(token_value)?,
769 ))
770 }
771
772 fn eval_hash_literal(&mut self, token: Pair<'a>) -> ParserResult<Val> {
773 check_rule!(token, Rule::hash_literal_expression);
774 let pairs = token.into_inner();
775 let mut hash = HashMap::new();
776 for token in pairs {
777 let (key, value) = self.eval_hash_entry(token)?;
778 hash.insert(key, value);
779 }
780 Ok(Val::HashTable(hash))
781 }
782
783 fn eval_value(&mut self, token: Pair<'a>) -> ParserResult<Val> {
784 check_rule!(token, Rule::value);
785 let mut pair = token.into_inner();
786 let token = pair.next().unwrap();
787
788 let res = match token.as_rule() {
789 Rule::parenthesized_expression => {
790 let token = token.into_inner().next().unwrap();
791 self.safe_eval_pipeline(token)?
792 }
793 Rule::sub_expression | Rule::array_expression => {
794 let statements = self.eval_statements(token)?;
795 if statements.len() == 1 && statements[0].ttype() == ValType::Array {
796 statements[0].clone()
797 } else {
798 Val::Array(statements)
799 }
800 }
801 Rule::script_block_expression => self.parse_script_block_expression(token)?,
802 Rule::hash_literal_expression => self.eval_hash_literal(token)?,
803 Rule::string_literal => self.eval_string_literal(token)?,
804 Rule::number_literal => self.eval_number_literal(token)?,
805 Rule::type_literal => Val::init(self.eval_type_literal(token)?)?,
806 Rule::variable => self.get_variable(token)?,
807 _ => {
808 panic!("token.rule(): {:?}", token.as_rule());
809 }
810 };
811 log::debug!("eval_value - res: {:?}", res);
812 Ok(res)
813 }
814
815 fn eval_number_literal(&mut self, token: Pair<'a>) -> ParserResult<Val> {
816 check_rule!(token, Rule::number_literal);
817 let mut negate = false;
818 let mut pairs = token.into_inner();
819 let mut token = pairs.next().unwrap();
820
821 if token.as_rule() == Rule::minus {
823 negate = true;
824 token = pairs.next().unwrap();
825 } else if token.as_rule() == Rule::plus {
826 token = pairs.next().unwrap();
827 }
828
829 let mut val = self.eval_number(token)?;
830
831 if negate {
832 val.neg()?;
833 }
834
835 if let Some(unit) = pairs.next() {
836 let unit = unit.as_str().to_ascii_lowercase();
837 let unit_int = match unit.as_str() {
838 "k" => 1024,
839 "m" => 1024 * 1024,
840 "g" => 1024 * 1024 * 1024,
841 "t" => 1024 * 1024 * 1024 * 1024,
842 "p" => 1024 * 1024 * 1024 * 1024 * 1024,
843 _ => 1,
844 };
845 val.mul(Val::Int(unit_int))?;
846 }
847 Ok(val)
848 }
849
850 fn eval_number(&mut self, token: Pair<'a>) -> ParserResult<Val> {
851 check_rule!(token, Rule::number);
852 let mut pairs = token.into_inner();
853 let token = pairs.next().unwrap();
854 let v = match token.as_rule() {
855 Rule::decimal_integer => {
856 let int_val = token.into_inner().next().unwrap();
857 Val::Int(int_val.as_str().parse::<i64>().unwrap())
858 }
859 Rule::hex_integer => {
860 let int_val = token.into_inner().next().unwrap();
861 Val::Int(i64::from_str_radix(int_val.as_str(), 16).unwrap())
862 }
863 Rule::float => {
865 let float_str = token.as_str().trim();
866
867 match float_str.parse::<f64>() {
868 Ok(float_val) => Val::Float(float_val),
869 Err(err) => {
870 println!("eval_number - invalid float: {}: asd {}", float_str, err);
871 panic!("eval_number - invalid float: {}: {}", float_str, err);
872 }
873 }
874 }
875 _ => {
876 panic!("eval_number - token.rule(): {:?}", token.as_rule());
877 }
878 };
879 Ok(v)
880 }
881
882 fn eval_unary_exp(&mut self, token: Pair<'a>) -> ParserResult<Val> {
883 check_rule!(token, Rule::unary_exp);
884 let token = token.into_inner().next().unwrap();
885 match token.as_rule() {
886 Rule::expression_with_unary_operator => self.eval_expression_with_unary_operator(token),
887 Rule::primary_expression => self.eval_primary_expression(token),
888 _ => {
889 panic!("eval_unary_exp token.rule(): {:?}", token.as_rule());
890 }
891 }
892 }
893
894 fn eval_array_literal_exp(&mut self, token: Pair<'a>) -> ParserResult<Val> {
895 check_rule!(token, Rule::array_literal_exp);
896 let mut arr = Vec::new();
897 let mut pairs = token.into_inner();
898 arr.push(self.eval_unary_exp(pairs.next().unwrap())?);
899 for token in pairs {
900 arr.push(self.eval_unary_exp(token)?);
901 }
902
903 Ok(if arr.len() == 1 {
904 arr[0].clone()
905 } else {
906 Val::Array(arr)
907 })
908 }
909
910 fn eval_range_exp(&mut self, token: Pair<'a>) -> ParserResult<Val> {
911 fn range(left: i64, right: i64) -> Vec<Val> {
912 if left < right {
913 (left..=right).collect::<Vec<i64>>()
914 } else {
915 let mut v = (right..=left).collect::<Vec<i64>>();
916 v.reverse();
917 v
918 }
919 .into_iter()
920 .map(Val::Int)
921 .collect::<Vec<Val>>()
922 }
923 check_rule!(token, Rule::range_exp);
924 let mut pairs = token.into_inner();
925 let token = pairs.next().unwrap();
926 let res = match token.as_rule() {
927 Rule::decimal_integer => {
928 let int_val = token.into_inner().next().unwrap();
929 let left = int_val.as_str().parse::<i64>().unwrap();
930 let token = pairs.next().unwrap();
931 let right = self.eval_array_literal_exp(token)?.cast_to_int()?;
932 Val::Array(range(left, right))
933 }
934 Rule::array_literal_exp => {
935 let res = self.eval_array_literal_exp(token)?;
936 if let Some(token) = pairs.next() {
937 let left = res.cast_to_int()?;
938 let right = self.eval_array_literal_exp(token)?.cast_to_int()?;
939 Val::Array(range(left, right))
940 } else {
941 res
942 }
943 }
944 _ => {
945 panic!("eval_range_exp not implemented: {:?}", token.as_rule());
946 }
947 };
948
949 Ok(res)
950 }
951
952 fn eval_format_impl(&mut self, format: Val, mut pairs: Pairs<'a>) -> ParserResult<Val> {
953 fn format_with_vec(fmt: &str, args: Vec<Val>) -> ParserResult<String> {
954 fn strange_special_case(fmt: &str, n: i64) -> String {
955 fn split_digits(n: i64) -> Vec<u8> {
956 n.abs() .to_string()
958 .chars()
959 .filter_map(|c| c.to_digit(10).map(|opt| opt as u8))
960 .collect()
961 }
962
963 let mut digits = split_digits(n);
965 digits.reverse();
966 let mut fmt_vec = fmt.as_bytes().to_vec();
967 fmt_vec.reverse();
968
969 let mut i = 0;
970 for digit in digits {
971 while i < fmt_vec.len() {
972 if fmt_vec[i] != b'0' {
973 i += 1
974 } else {
975 fmt_vec[i] = digit + b'0';
976 break;
977 }
978 }
979 }
980 fmt_vec.reverse();
981 String::from_utf8(fmt_vec).unwrap_or_default()
982 }
983
984 let mut output = String::new();
985 let mut i = 0;
986
987 while i < fmt.len() {
988 if fmt[i..].starts_with('{') {
989 if let Some(end) = fmt[i..].find('}') {
990 let token = &fmt[i + 1..i + end];
991 let formatted = if token.contains(':') {
992 let mut parts = token.split(':');
993 let index: usize = if let Some(p) = parts.next() {
994 p.parse().unwrap_or(0)
995 } else {
996 0
997 };
998
999 let spec = parts.next();
1000 match args.get(index) {
1001 Some(val) => match spec {
1002 Some(s) if s.starts_with('N') => {
1003 let precision = s[1..].parse::<usize>().unwrap_or(2);
1004 if let Ok(f) = val.cast_to_float() {
1005 format!("{:.1$}", f, precision)
1006 } else {
1007 val.cast_to_string().to_string()
1008 }
1009 }
1010 Some(s) => strange_special_case(s, val.cast_to_int()?),
1011 None => val.cast_to_string().to_string(),
1012 },
1013 None => format!("{{{}}}", token), }
1016 } else if token.contains(',') {
1017 let mut parts = token.split(',');
1018 let index: usize = parts.next().unwrap().parse().unwrap_or(0);
1019 let spec = parts.next();
1020 match args.get(index) {
1021 Some(val) => match spec {
1022 Some(s) => {
1023 let spaces = s.parse::<usize>().unwrap_or(0);
1024 let spaces_str = " ".repeat(spaces);
1025 format!("{spaces_str}{}", val.cast_to_string())
1026 }
1027 _ => val.cast_to_string().to_string(),
1028 },
1029 None => format!("{{{}}}", token), }
1032 } else {
1033 let index: usize =
1034 Val::String(token.to_string().into()).cast_to_int()? as usize;
1035 match args.get(index) {
1036 Some(val) => val.cast_to_string().to_string(),
1037 None => format!("{{{}}}", token), }
1040 };
1041
1042 output.push_str(&formatted);
1043 i += end + 1;
1044 } else {
1045 output.push('{');
1046 i += 1;
1047 }
1048 } else {
1049 output.push(fmt[i..].chars().next().unwrap());
1050 i += 1;
1051 }
1052 }
1053
1054 Ok(output)
1055 }
1056
1057 Ok(if let Some(token) = pairs.next() {
1058 let first_fmt = format.cast_to_string();
1059
1060 let second_fmt = self.eval_range_exp(token)?;
1061 let res = self.eval_format_impl(second_fmt, pairs)?;
1062 Val::String(format_with_vec(first_fmt.as_str(), res.cast_to_array())?.into())
1063 } else {
1064 format
1065 })
1066 }
1067
1068 fn eval_format_exp(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1069 check_rule!(token, Rule::format_exp);
1070 let mut pairs = token.into_inner();
1071 let format = self.eval_range_exp(pairs.next().unwrap())?;
1072 self.eval_format_impl(format, pairs)
1073 }
1074
1075 fn eval_mult(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1076 check_rule!(token, Rule::multiplicative_exp);
1077 let mut pairs = token.into_inner();
1078 let mut res = self.eval_format_exp(pairs.next().unwrap())?;
1079 while let Some(op) = pairs.next() {
1080 let Some(fun) = ArithmeticPred::get(op.as_str()) else {
1081 panic!(
1082 "can't find arithmetic function for operator: {}",
1083 op.as_str()
1084 )
1085 };
1086
1087 let postfix = pairs.next().unwrap();
1088 let right_op = self.eval_format_exp(postfix)?;
1089 res = fun(res, right_op)?;
1090 }
1091
1092 Ok(res)
1093 }
1094
1095 fn eval_additive(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1096 check_rule!(token, Rule::additive_exp);
1097
1098 let mut pairs = token.into_inner();
1099 let mut res = self.eval_mult(pairs.next().unwrap())?;
1100 while let Some(op) = pairs.next() {
1101 let Some(fun) = ArithmeticPred::get(op.as_str()) else {
1103 panic!()
1104 };
1105
1106 let mult = pairs.next().unwrap();
1107 let right_op = self.eval_mult(mult)?;
1108 res = fun(res, right_op)?;
1109 }
1110
1111 Ok(res)
1112 }
1113
1114 fn eval_split_special_case(
1115 &mut self,
1116 token: Pair<'a>,
1117 input: Val,
1118 ) -> ParserResult<Vec<String>> {
1119 let mut res_vec = vec![];
1120 let mut parts = String::new();
1121 let input_str = input.cast_to_string();
1122 let characters = input_str.chars();
1123
1124 for ch in characters {
1126 self.variables
1127 .set_ps_item(Val::String(ch.to_string().into()));
1128
1129 let b = match self.eval_script_block(
1130 &ScriptBlock(token.as_str().to_string()),
1131 &Val::String(ch.to_string().into()),
1132 ) {
1133 Err(er) => {
1134 self.errors.push(er);
1135 false
1136 }
1137 Ok(b) => b,
1138 };
1139
1140 if b {
1141 res_vec.push(parts);
1142 parts = String::new();
1143 } else {
1144 parts.push(ch);
1145 }
1146 }
1147 self.variables.reset_ps_item();
1148 Ok(res_vec)
1149 }
1150 fn eval_comparison_exp(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1151 check_rule!(token, Rule::comparison_exp);
1152 let mut pairs = token.into_inner();
1153 let token = pairs.next().unwrap();
1154
1155 let mut res = if token.as_rule() == Rule::additive_exp {
1158 self.eval_additive(token)?
1159 } else {
1160 Val::Null
1161 };
1162
1163 while let Some(op) = pairs.next() {
1164 let Some(fun) = StringPred::get(op.as_str()) else {
1165 panic!("no operator: {}", op.as_str())
1166 };
1167
1168 let token = pairs.next().unwrap();
1169 let right_op = match token.as_rule() {
1170 Rule::script_block_expression => {
1171 let mut pairs = token.into_inner();
1172 let token = pairs.next().unwrap();
1173 check_rule!(token, Rule::script_block_inner);
1174
1175 let mut pairs = token.into_inner();
1176 let mut token = pairs.next().unwrap();
1177 if token.as_rule() == Rule::param_block {
1178 token = pairs.next().unwrap();
1180 }
1181 check_rule!(token, Rule::script_block);
1182 return Ok(Val::Array(
1183 self.eval_split_special_case(token, res)?
1184 .into_iter()
1185 .map(|s| Val::String(s.into()))
1186 .collect::<Vec<_>>(),
1187 ));
1188 }
1189 Rule::additive_exp => self.eval_additive(token)?,
1190 _ => {
1191 panic!("eval_comparison_exp not implemented: {:?}", token.as_rule());
1192 }
1193 };
1194 log::trace!("res: {:?}, right_op: {:?}", &res, &right_op);
1195 res = fun(res, right_op)?;
1196 log::trace!("res: {:?}", &res);
1197 }
1198
1199 Ok(res)
1200 }
1201
1202 fn eval_bitwise_exp(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1203 check_rule!(token, Rule::bitwise_exp);
1204
1205 let mut pairs = token.into_inner();
1206 let mut res = self.eval_comparison_exp(pairs.next().unwrap())?;
1207 while let Some(op) = pairs.next() {
1208 check_rule!(op, Rule::bitwise_operator);
1209 let Some(fun) = BitwisePred::get(op.as_str()) else {
1210 panic!()
1211 };
1212
1213 let mult = pairs.next().unwrap();
1214 let right_op = self.eval_comparison_exp(mult)?;
1215 res = fun(res, right_op);
1216 }
1217
1218 Ok(res)
1219 }
1220
1221 fn parse_long_command(&mut self, token: Pair<'a>) -> ParserResult<(String, Vec<CommandElem>)> {
1222 check_rule!(token, Rule::long_command);
1223
1224 let mut pairs = token.into_inner();
1225 let command_name_token = pairs.next().unwrap();
1226 let command_name = command_name_token.as_str();
1227
1228 let mut args = vec![];
1229 for command_element_token in pairs {
1230 let token_string = command_element_token.as_str().to_string();
1231 match command_element_token.as_rule() {
1232 Rule::command_argument => {
1233 let arg_token = command_element_token.into_inner().next().unwrap();
1234 let arg = match arg_token.as_rule() {
1235 Rule::array_literal_exp => self.eval_array_literal_exp(arg_token)?,
1236 Rule::parenthesized_expression => {
1237 let token = arg_token.into_inner().next().unwrap();
1238 self.eval_pipeline(token)?
1239 }
1240 _ => Val::String(arg_token.as_str().to_string().into()),
1241 };
1242 args.push(CommandElem::Argument(arg));
1243 }
1244 Rule::command_parameter => args.push(CommandElem::Parameter(token_string)),
1245 Rule::argument_list => args.push(CommandElem::ArgList(token_string)),
1246 Rule::redirection => { }
1248 Rule::stop_parsing => { }
1250 Rule::script_block_expression => args.push(CommandElem::Argument(
1251 self.parse_script_block_expression(command_element_token)?,
1252 )),
1253 _ => panic!(
1254 "eval_command not implemented: {:?}",
1255 command_element_token.as_rule()
1256 ),
1257 }
1258 }
1259 Ok((command_name.to_string(), args))
1260 }
1261
1262 fn parse_script_block_command(
1263 &mut self,
1264 token: Pair<'a>,
1265 ) -> ParserResult<(String, Vec<CommandElem>)> {
1266 check_rule!(token, Rule::script_block_command);
1267
1268 let mut pairs = token.into_inner();
1269 let command_name_token = pairs.next().unwrap();
1270 let command_name = command_name_token.as_str();
1271 let command_element_token = pairs.next().unwrap();
1272
1273 check_rule!(command_element_token, Rule::script_block_expression);
1274 let script_block = self.parse_script_block_expression(command_element_token)?;
1275 Ok((
1276 command_name.to_string(),
1277 vec![CommandElem::Argument(script_block)],
1278 ))
1279 }
1280
1281 fn eval_command(&mut self, token: Pair<'a>, input: Option<Val>) -> ParserResult<Val> {
1282 check_rule!(token, Rule::command);
1283
1284 let mut pairs = token.into_inner();
1285 let mut args = if let Some(v) = input {
1288 vec![CommandElem::Argument(v)]
1289 } else {
1290 Vec::new()
1291 };
1292
1293 let command = pairs.next().unwrap();
1294 let (command_name, mut command_args) = match command.as_rule() {
1295 Rule::script_block_command => self.parse_script_block_command(command)?,
1296 Rule::foreach_command => Err(ParserError::NotImplemented("foreach_command".into()))?,
1297 Rule::long_command => self.parse_long_command(command)?,
1298 Rule::invocation_command => {
1299 Err(ParserError::NotImplemented("invocation_command".into()))?
1300 }
1301 _ => panic!("eval_command not implemented: {:?}", command.as_rule()),
1302 };
1303 args.append(&mut command_args);
1304
1305 let CommandOutput {
1306 val,
1307 deobfuscated,
1308 stream,
1309 } = Command::execute(self, command_name.as_str(), args)?;
1310
1311 if let Some(msg) = deobfuscated {
1312 self.deobfuscated_statements.push(msg);
1313 }
1314
1315 if let Some(msg) = stream {
1316 self.output.push(msg);
1317 }
1318
1319 Ok(val.unwrap_or_default())
1320 }
1321
1322 fn eval_redirected_expression(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1323 check_rule!(token, Rule::redirected_expression);
1324
1325 let expression_token = token.into_inner().next().unwrap();
1326 self.eval_expression(expression_token)
1329 }
1330
1331 fn eval_expression(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1332 check_rule!(token, Rule::expression);
1333 let token_string = token.as_str().trim().to_string();
1334
1335 let mut pairs = token.into_inner();
1336 let mut res = self.eval_bitwise_exp(pairs.next().unwrap())?;
1337 while let Some(op) = pairs.next() {
1338 check_rule!(op, Rule::logical_operator);
1339 let Some(fun) = LogicalPred::get(op.as_str()) else {
1340 panic!()
1341 };
1342
1343 let mult = pairs.next().unwrap();
1344 let right_op = self.eval_bitwise_exp(mult)?;
1345 res = Val::Bool(fun(res, right_op));
1346 }
1347 self.tokens
1348 .push(Token::Expression(token_string, res.clone().into()));
1349
1350 Ok(res)
1351 }
1352
1353 fn eval_pipeline_tail(&mut self, token: Pair<'a>, input: Val) -> ParserResult<Val> {
1354 check_rule!(token, Rule::pipeline_tail);
1355 let mut arg = input;
1356 let mut pairs = token.into_inner();
1357
1358 while let Some(token) = pairs.next() {
1359 arg = self.eval_command(token, Some(arg))?;
1360 }
1361
1362 Ok(arg)
1363 }
1364
1365 fn eval_pipeline_with_tail(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1366 check_rule!(token, Rule::pipeline_with_tail);
1367 let mut pairs = token.into_inner();
1368 let token = pairs.next().unwrap();
1369
1370 let result: Val = match token.as_rule() {
1371 Rule::redirected_expression => self.eval_redirected_expression(token)?,
1372 Rule::command => self.eval_command(token, None)?,
1373 _ => {
1374 panic!("eval_pipeline not implemented: {:?}", token.as_rule());
1375 }
1376 };
1377
1378 if let Some(token) = pairs.next() {
1379 match token.as_rule() {
1380 Rule::pipeline_tail => Ok(self.eval_pipeline_tail(token, result)?),
1381 _ => {
1382 panic!("eval_pipeline not implemented: {:?}", token.as_rule());
1383 }
1384 }
1385 } else {
1386 Ok(result)
1387 }
1388 }
1389
1390 fn eval_pipeline(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1391 check_rule!(token, Rule::pipeline);
1392 let mut pairs = token.into_inner();
1393 let token = pairs.next().unwrap();
1394
1395 match token.as_rule() {
1396 Rule::assignment_exp => return self.eval_assigment_exp(token),
1397 Rule::pipeline_with_tail => return self.eval_pipeline_with_tail(token),
1398 _ => panic!("not possible: {:?}", token.as_rule()),
1399 }
1400 }
1401
1402 fn safe_eval_pipeline(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1403 let res = self.eval_pipeline(token.clone());
1404
1405 let v = match res {
1406 Ok(val) => val,
1407 Err(err) => {
1408 self.errors.push(err);
1409 Val::ScriptText(token.as_str().to_string())
1410 }
1411 };
1412
1413 Ok(v)
1414 }
1415
1416 fn eval_cast_expression(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1417 check_rule!(token, Rule::cast_expression);
1418
1419 let mut pairs = token.into_inner();
1420 let type_token = pairs.next().unwrap();
1421 let val_type = self.eval_type_literal(type_token)?;
1422
1423 let token = pairs.next().unwrap();
1424 let mut res = match token.as_rule() {
1425 Rule::parenthesized_expression => {
1426 let token = token.into_inner().next().unwrap();
1427 self.safe_eval_pipeline(token)?
1428 }
1429 Rule::range_exp => self.eval_range_exp(token)?,
1430 Rule::unary_exp => self.eval_unary_exp(token)?,
1431 _ => {
1432 panic!(
1433 "eval_cast_expression not implemented: {:?}",
1434 token.as_rule()
1435 );
1436 }
1437 };
1438
1439 Ok(res.cast(val_type)?)
1440 }
1441
1442 fn eval_assigment_exp(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1443 check_rule!(token, Rule::assignment_exp);
1444
1445 let mut pairs = token.into_inner();
1446 let variable_token = pairs.next().unwrap();
1447 let var_name = Self::parse_variable(variable_token)?;
1448 let var = self.variables.get(&var_name).unwrap_or_default();
1449
1450 let assignement_op = pairs.next().unwrap();
1451
1452 let op = assignement_op.into_inner().next().unwrap();
1454 let pred = ArithmeticPred::get(op.as_str());
1455
1456 let right_token = pairs.next().unwrap();
1457 let right_op = self.eval_pipeline(right_token.clone())?;
1458
1459 let Some(pred) = pred else { panic!() };
1460 let op_result = pred(var, right_op)?;
1461 self.variables.set(&var_name, op_result.clone())?;
1462
1463 self.deobfuscated_statements
1465 .push(format!("{} = {}", var_name, op_result.cast_to_script()));
1466 Ok(op_result)
1467 }
1468}
1469
1470#[cfg(test)]
1471mod tests {
1472 use pest::Parser;
1473
1474 use super::*;
1475
1476 #[test]
1477 fn comment_and_semicolon() {
1478 let input = r#"
1479# This is a single line comment
1480$a = 1; $b = 2; Write-Output $a
1481
1482Write-Output "Hello" # Another comment
1483
1484<#
1485 This is a
1486 multi-line block comment
1487#>
1488"#;
1489
1490 let _ = PowerShellSession::parse(Rule::program, input).unwrap();
1491 }
1492
1493 #[test]
1494 fn while_loop() {
1495 let input = r#"
1496while ($true) {
1497 if ($someCondition) {
1498 break
1499 }
1500 # other code
1501}
1502"#;
1503
1504 let _ = PowerShellSession::parse(Rule::program, input).unwrap();
1505 }
1506
1507 #[test]
1508 fn foreach_loop() {
1509 let input = r#"
1510foreach ($n in $numbers) {
1511 Write-Output $n
1512}
1513"#;
1514
1515 let _ = PowerShellSession::parse(Rule::program, input).unwrap();
1516 }
1517
1518 #[test]
1519 fn for_loop() {
1520 let input = r#"
1521# Comma separated assignment expressions enclosed in parentheses.
1522for (($i = 0), ($j = 0); $i -lt 10; $i++)
1523{
1524 "`$i:$i"
1525 "`$j:$j"
1526}
1527"#;
1528
1529 let _ = PowerShellSession::parse(Rule::program, input).unwrap();
1530 }
1531
1532 #[test]
1533 fn switch() {
1534 let input = r#"
1535switch ($var) {
1536 "a" { Write-Output "A" }
1537 1 { Write-Output "One" }
1538 default { Write-Output "Other" }
1539}
1540"#;
1541
1542 let _ = PowerShellSession::parse(Rule::program, input).unwrap();
1543 }
1544
1545 #[test]
1546 fn functions() {
1547 let input = r#"
1548function Get-Square {
1549 param($x)
1550 return $x * $x
1551}
1552
1553function Say-Hello {
1554 Write-Output "Hello"
1555}
1556"#;
1557
1558 let _ = PowerShellSession::parse(Rule::program, input).unwrap();
1559 }
1560
1561 #[test]
1562 fn if_expression() {
1563 let input = r#"
1564$x="hello"
1565 Write-Host $x
1566 $y = 42
1567 Start-Process "notepad.exe"
1568
1569 $x = 42
1570if ($x -eq 1) {
1571 Write-Output "One"
1572} elseif ($x -eq 2) {
1573 Write-Output "Two"
1574} else {
1575 Write-Output "Other"
1576}
1577"#;
1578
1579 let _ = PowerShellSession::parse(Rule::program, input).unwrap();
1580 }
1581
1582 #[test]
1583 fn command() {
1584 let input = r#"
1585Get-Process | Where-Object { $_.CPU -gt 100 }
1586"#;
1587
1588 let _ = PowerShellSession::parse(Rule::program, input).unwrap();
1589 }
1590
1591 #[test]
1592 fn range() {
1593 let input = r#"
1594$numbers = 1..5
1595"#;
1596
1597 let _ = PowerShellSession::parse(Rule::program, input).unwrap();
1598 }
1599
1600 #[test]
1601 fn literals() {
1602 let input = r#"
1603$hex = 0xFF
1604
1605$name = "Alice"
1606$msg = "Hello, $name. Today is $day."
1607$escaped = "She said: `"Hi`""
1608$literal = 'Hello, $name'
1609"#;
1610
1611 let _ = PowerShellSession::parse(Rule::program, input).unwrap();
1612 }
1613
1614 #[test]
1615 fn floats() {
1616 let input = r#"
1617 $pi = 3.1415
1618$half = .5
1619"#;
1620
1621 let _ = PowerShellSession::parse(Rule::program, input).unwrap();
1622 }
1623
1624 #[test]
1625 fn arrays() {
1626 let input = r#"
1627$a = 1, 2, 3
1628$b = @("one", "two", "three")
1629$c = @(1, 2, @(3, 4))
1630"#;
1631
1632 let _ = PowerShellSession::parse(Rule::program, input).unwrap();
1633 }
1634
1635 #[test]
1636 fn static_method_call() {
1637 let input = r#"
1638[Threading.Thread]::Sleep(399)
1639"#;
1640
1641 let _ = PowerShellSession::parse(Rule::program, input).unwrap();
1642 }
1643
1644 #[test]
1645 fn neg_pipeline() {
1646 let input = r#"
1647-not $input | Where-Object { $_ -gt 5 }
1648"#;
1649
1650 let _ = PowerShellSession::parse(Rule::program, input).unwrap();
1651 }
1652
1653 #[test]
1654 fn amsi_fail() {
1655 let input = r#"
1656#Matt Graebers second Reflection method
1657$VMRviwsbtehQfPtxbt=$null;
1658$ilryNQSTt="System.$([cHAR]([ByTE]0x4d)+[ChAR]([byte]0x61)+[chAr](110)+[cHar]([byTE]0x61)+[cHaR](103)+[cHar](101*64/64)+[chaR]([byTE]0x6d)+[cHAr](101)+[CHAr]([byTE]0x6e)+[Char](116*103/103)).$([Char]([ByTe]0x41)+[Char](117+70-70)+[CHAr]([ByTE]0x74)+[CHar]([bYte]0x6f)+[CHar]([bytE]0x6d)+[ChaR]([ByTe]0x61)+[CHar]([bYte]0x74)+[CHAR]([byte]0x69)+[Char](111*26/26)+[chAr]([BYTe]0x6e)).$(('Âmsí'+'Ùtìl'+'s').NORmalizE([ChAR](44+26)+[chAR](111*9/9)+[cHar](82+32)+[ChaR](109*34/34)+[cHaR](68+24-24)) -replace [ChAr](92)+[CHaR]([BYTe]0x70)+[Char]([BytE]0x7b)+[CHaR]([BYTe]0x4d)+[chAR](110)+[ChAr](15+110))"
1659
1660"#;
1661
1662 let _ = PowerShellSession::parse(Rule::program, input).unwrap();
1663 }
1664}