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::{Param, RuntimeObject, ScriptBlock, ValResult};
16use variables::{Scope, SessionScope};
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! unexpected_token {
37 ($pair:expr) => {
38 panic!("Unexpected token: {:?}", $pair.as_rule())
39 };
40}
41
42macro_rules! check_rule {
43 ($pair:expr, $rule:pat) => {
44 if !matches!($pair.as_rule(), $rule) {
45 panic!(
46 "Unexpected token: {:?}, instead of {}",
47 $pair.as_rule(),
48 stringify!($rule)
49 );
50 }
51 };
52}
53
54macro_rules! not_implemented {
55 ($token:expr) => {
56 Err(ParserError::NotImplemented(format!(
57 "Not implemented: {:?}",
58 $token.as_rule()
59 )))
60 };
61}
62
63#[derive(Default)]
64pub(crate) struct Results {
65 output: Vec<StreamMessage>,
66 deobfuscated: Vec<String>,
67}
68
69impl Results {
70 fn new() -> Self {
71 Self {
72 output: Vec::new(),
73 deobfuscated: Vec::new(),
74 }
75 }
76}
77
78#[derive(Parser)]
79#[grammar = "powershell.pest"]
80pub struct PowerShellSession {
81 variables: Variables,
82 tokens: Tokens,
83 errors: Vec<ParserError>,
84 results: Vec<Results>,
85}
86
87impl Default for PowerShellSession {
88 fn default() -> Self {
89 Self::new()
90 }
91}
92
93impl<'a> PowerShellSession {
94 pub fn new() -> Self {
114 Self {
115 variables: Variables::new(),
116 tokens: Tokens::new(),
117 errors: Vec::new(),
118 results: Vec::new(),
119 }
120 }
121
122 pub fn with_variables(mut self, variables: Variables) -> Self {
147 self.variables = variables;
148 self
149 }
150
151 pub fn safe_eval(&mut self, script: &str) -> Result<String, ParserError> {
183 let script_res = self.parse_input(script)?;
184 Ok(script_res.result().to_string())
185 }
186
187 pub fn deobfuscate_script(&mut self, script: &str) -> Result<String, ParserError> {
188 self.push_scope_session();
189 let script_res = self.parse_input(script)?;
190 self.pop_scope_session();
191 Ok(script_res.deobfuscated().to_string())
192 }
193
194 pub fn env_variables(&self) -> HashMap<String, PsValue> {
195 self.variables
196 .get_env()
197 .into_iter()
198 .map(|(k, v)| (k, v.into()))
199 .collect()
200 }
201
202 pub fn session_variables(&self) -> HashMap<String, PsValue> {
203 self.variables
204 .get_global()
205 .into_iter()
206 .map(|(k, v)| (k, v.into()))
207 .collect()
208 }
209
210 pub fn parse_input(&mut self, input: &str) -> Result<ScriptResult, ParserError> {
242 self.variables.init();
243 let (script_last_output, mut result) = self.parse_subscript(input)?;
244 self.variables.clear_script_functions();
245 Ok(ScriptResult::new(
246 script_last_output,
247 std::mem::take(&mut result.output),
248 std::mem::take(&mut result.deobfuscated),
249 std::mem::take(&mut self.tokens),
250 std::mem::take(&mut self.errors),
251 self.variables
252 .script_scope()
253 .into_iter()
254 .map(|(k, v)| (k, v.into()))
255 .collect(),
256 ))
257 }
258
259 pub(crate) fn parse_subscript(&mut self, input: &str) -> Result<(Val, Results), ParserError> {
260 let mut pairs = PowerShellSession::parse(Rule::program, input)?;
261 self.results.push(Results::new());
263
264 let program_token = pairs.next().expect("");
265
266 let mut script_last_output = Val::default();
267
268 if let Rule::program = program_token.as_rule() {
269 let pairs = program_token.into_inner();
270
271 for token in pairs {
272 let token_str = token.as_str();
273 match token.as_rule() {
274 Rule::statement_terminator => continue,
275 Rule::EOI => break,
276 _ => {}
277 };
278
279 let result = self.eval_statement(token.clone());
280 self.variables.set_status(result.is_ok());
281
282 if let Ok(Val::NonDisplayed(_)) = &result {
283 continue;
284 }
285
286 script_last_output = match result {
287 Ok(val) => {
288 if val != Val::Null {
289 self.add_output_statement(val.display().into());
290 self.add_deobfuscated_statement(val.cast_to_script());
291 }
292
293 val
294 }
295 Err(e) => {
296 self.errors.push(e);
297 self.add_deobfuscated_statement(token_str.into());
298 Val::Null
299 }
300 };
301 }
302 }
303
304 Ok((script_last_output, self.results.pop().unwrap_or_default()))
305 }
306
307 fn add_function(
308 &mut self,
309 name: String,
310 func: ScriptBlock,
311 scope: Option<Scope>,
312 ) -> ParserResult<Val> {
313 if let Some(Scope::Global) = &scope {
317 self.variables.add_global_function(name.clone(), func);
318 } else {
319 self.variables.add_script_function(name.clone(), func);
320 }
321
322 Err(ParserError::Skip)
323 }
324
325 pub(crate) fn parse_function_statement(&mut self, token: Pair<'a>) -> ParserResult<Val> {
326 check_rule!(token, Rule::function_statement);
327
328 let mut pair = token.into_inner();
329
330 let function_keyword_token = pair.next().unwrap();
331 check_rule!(function_keyword_token, Rule::function_keyword);
332
333 let mut next_token = pair.next().unwrap();
334 let scope = if next_token.as_rule() == Rule::scope_keyword {
335 let scope = Scope::from(next_token.as_str());
336 next_token = pair.next().unwrap();
337 Some(scope)
338 } else {
339 None
340 };
341
342 let function_name_token = next_token;
343 check_rule!(function_name_token, Rule::function_name);
344 let fname = function_name_token.as_str().to_ascii_lowercase();
345
346 let Some(mut next_token) = pair.next() else {
347 return self.add_function(fname, ScriptBlock::empty(), scope);
349 };
350
351 let params = if next_token.as_rule() == Rule::parameter_list {
352 let param_list = self.parse_parameter_list(next_token)?;
353 if let Some(token) = pair.next() {
354 next_token = token;
355 } else {
356 return self.add_function(fname, ScriptBlock::empty(), scope);
357 }
358
359 param_list
360 } else {
361 Vec::new()
362 };
363 check_rule!(next_token, Rule::script_block);
364
365 let mut script_block = self.parse_script_block(next_token)?;
366
367 if script_block.params.0.is_empty() {
368 script_block = script_block.with_params(params);
369 }
370
371 self.add_function(fname, script_block, scope)
372 }
373
374 pub(crate) fn eval_if_statement(&mut self, token: Pair<'a>) -> ParserResult<Val> {
375 check_rule!(token, Rule::if_statement);
376 let mut pair = token.into_inner();
377 let condition_token = pair.next().unwrap();
378 let true_token = pair.next().unwrap();
379 let condition_val = self.eval_pipeline(condition_token.clone())?;
380 let res = if condition_val.cast_to_bool() {
381 self.eval_statement_block(true_token)?
382 } else if let Some(mut token) = pair.next() {
383 if token.as_rule() == Rule::elseif_clauses {
384 for else_if in token.into_inner() {
385 let mut pairs = else_if.into_inner();
386 let condition_token = pairs.next().unwrap();
387 let statement_token = pairs.next().unwrap();
388 let condition_val = self.eval_pipeline(condition_token)?;
389 if condition_val.cast_to_bool() {
390 return self.eval_statement_block(statement_token);
391 }
392 }
393 let Some(token2) = pair.next() else {
394 return Ok(Val::Null);
395 };
396 token = token2;
397 }
398 if token.as_rule() == Rule::else_condition {
399 let statement_token = token.into_inner().next().unwrap();
400 self.eval_statement_block(statement_token)?
401 } else {
402 Val::Null
403 }
404 } else {
405 Val::Null
406 };
407
408 Ok(res)
409 }
410
411 fn eval_flow_control_statement(&mut self, token: Pair<'a>) -> ParserResult<Val> {
412 check_rule!(token, Rule::flow_control_statement);
413 let token = token.into_inner().next().unwrap();
414
415 Ok(match token.as_rule() {
416 Rule::flow_control_label_statement => Val::Null, Rule::flow_control_pipeline_statement => {
418 let token = token.into_inner().next().unwrap();
419 if let Some(pipeline_token) = token.into_inner().next() {
421 self.eval_pipeline(pipeline_token)?
422 } else {
423 Val::Null
424 }
425 }
426 _ => unexpected_token!(token),
427 })
428 }
429
430 fn eval_statement(&mut self, token: Pair<'a>) -> ParserResult<Val> {
431 match token.as_rule() {
432 Rule::pipeline => self.eval_pipeline(token),
433 Rule::if_statement => self.eval_if_statement(token),
434 Rule::flow_control_statement => self.eval_flow_control_statement(token),
435 Rule::function_statement => self.parse_function_statement(token),
436 Rule::statement_terminator => Ok(Val::Null),
437 Rule::EOI => Ok(Val::Null),
438 _ => {
439 not_implemented!(token)
440 }
441 }
442 }
443
444 fn safe_eval_sub_expr(&mut self, token: Pair<'a>) -> ParserResult<Val> {
445 check_rule!(token, Rule::sub_expression);
453 let Some(inner_token) = token.into_inner().next() else {
454 return Ok(Val::Null);
455 };
456 let mut inner_val = self.eval_pipeline(inner_token)?;
457 if let Val::ScriptText(script) = &mut inner_val {
458 *script = format!("$({})", script);
459 }
461 Ok(inner_val)
462 }
463
464 fn eval_statement_block(&mut self, token: Pair<'a>) -> ParserResult<Val> {
465 Ok(self
466 .safe_eval_statements(token)?
467 .iter()
468 .last()
469 .cloned()
470 .unwrap_or(Val::Null))
471 }
472
473 fn eval_statements(&mut self, token: Pair<'a>) -> ParserResult<Vec<Val>> {
474 let pairs = token.into_inner();
476 let mut statements = vec![];
477
478 for token in pairs {
479 let s = self.eval_statement(token)?;
480 statements.push(s);
481 }
482 Ok(statements)
483 }
484
485 fn safe_eval_statements(&mut self, token: Pair<'a>) -> ParserResult<Vec<Val>> {
486 let pairs = token.into_inner();
488 let mut statements = vec![];
489
490 for token in pairs {
491 match self.eval_statement(token.clone()) {
492 Ok(s) => statements.push(s),
493 Err(err) => {
494 self.errors.push(err);
495 statements.push(Val::ScriptText(token.as_str().to_string()));
496 }
497 }
498 }
499 Ok(statements)
500 }
501
502 fn parse_dq(&mut self, token: Pair<'a>) -> ParserResult<String> {
503 let mut res_str = String::new();
504 let pairs = token.into_inner();
505 for token in pairs {
506 let token = token.into_inner().next().unwrap();
507 let s = match token.as_rule() {
508 Rule::variable => self.get_variable(token)?.cast_to_string(),
509 Rule::sub_expression => self.safe_eval_sub_expr(token)?.cast_to_string(),
510 Rule::backtick_escape => token
511 .as_str()
512 .strip_prefix("`")
513 .unwrap_or_default()
514 .to_string(),
515 _ => token.as_str().to_string(),
516 };
517 res_str.push_str(s.as_str());
518 }
519 Ok(res_str)
520 }
521
522 fn eval_string_literal(&mut self, token: Pair<'a>) -> ParserResult<Val> {
523 check_rule!(token, Rule::string_literal);
524 let mut pair = token.into_inner();
525 let token = pair.next().unwrap();
526 let cloned_token = token.clone();
527
528 let mut is_expandable = false;
529 let res = match token.as_rule() {
530 Rule::doublequoted_string_literal | Rule::doublequoted_multiline_string_literal => {
531 is_expandable = true;
532 self.parse_dq(token)?
533 }
534 Rule::singlequoted_string_literal => {
535 let token_string = token.as_str().to_string();
536 let stripped_prefix = token_string
537 .strip_prefix("'")
538 .unwrap_or(token_string.as_str());
539 let stripped_suffix = stripped_prefix.strip_suffix("'").unwrap_or(stripped_prefix);
540 stripped_suffix.to_string()
541 }
542 Rule::singlequoted_multiline_string_literal => {
543 let mut res_str = String::new();
544 let pairs = token.into_inner();
545 for token in pairs {
546 res_str.push_str(token.as_str());
547 }
548 res_str
549 }
550 _ => unexpected_token!(token),
551 };
552 let ps_token = if is_expandable {
553 Token::StringExpandable(cloned_token.as_str().to_string(), res.clone())
554 } else {
555 Token::String(cloned_token.as_str().to_string())
556 };
557 self.tokens.push(ps_token);
558
559 Ok(Val::String(res.into()))
560 }
561
562 fn get_variable(&mut self, token: Pair<'a>) -> ParserResult<Val> {
563 check_rule!(token, Rule::variable);
564 let var_name = Self::parse_variable(token)?;
565 let Some(var) = self.variables.get(&var_name) else {
566 return Err(ParserError::VariableError(VariableError::NotDefined(
567 var_name.name,
568 )));
569 };
570 Ok(var)
571 }
572
573 fn parse_variable(token: Pair<'a>) -> ParserResult<VarName> {
574 check_rule!(token, Rule::variable);
575 let mut pair = token.into_inner();
576 let token = pair.next().unwrap();
577
578 Ok(match token.as_rule() {
579 Rule::special_variable => {
580 VarName::new_with_scope(Scope::Special, token.as_str().to_string())
581 }
582 Rule::parenthesized_variable => {
583 Self::parse_variable(token.into_inner().next().unwrap())?
584 }
585 Rule::braced_variable => {
586 let token = token.into_inner().next().unwrap();
587 let var = token.as_str().to_ascii_lowercase();
588 let splits: Vec<&str> = var.split(":").collect();
589 if splits.len() == 2 {
590 VarName::new_with_scope(Scope::from(splits[0]), splits[1].to_string())
591 } else {
592 VarName::new(None, var)
593 }
594 }
595 Rule::scoped_variable => {
596 let mut pairs = token.into_inner();
597 let mut token = pairs.next().unwrap();
598
599 let scope = if token.as_rule() == Rule::scope_keyword {
600 let scope = token.as_str().to_ascii_lowercase();
601 token = pairs.next().unwrap();
602 check_rule!(token, Rule::var_name);
603 Some(Scope::from(scope.as_str()))
604 } else {
605 None
606 };
607 VarName::new(scope, token.as_str().to_ascii_lowercase())
608 }
609 _ => unexpected_token!(token),
610 })
611 }
612
613 fn eval_expression_with_unary_operator(&mut self, token: Pair<'a>) -> ParserResult<Val> {
614 check_rule!(token, Rule::expression_with_unary_operator);
615 let mut pair = token.into_inner();
616 let token = pair.next().unwrap();
617
618 let res = match token.as_rule() {
619 Rule::pre_inc_expression => {
620 let variable_token = token.into_inner().next().unwrap();
621 let var_name = Self::parse_variable(variable_token)?;
622 let mut var = self.variables.get(&var_name).unwrap_or_default();
623 var.inc()?;
624
625 self.variables.set(&var_name, var.clone())?;
626 var
627 }
628 Rule::pre_dec_expression => {
629 let variable_token = token.into_inner().next().unwrap();
630 let var_name = Self::parse_variable(variable_token)?;
631 let mut var = self.variables.get(&var_name).unwrap_or_default();
632 var.dec()?;
633
634 self.variables.set(&var_name, var.clone())?;
635 var
636 }
637 Rule::cast_expression => self.eval_cast_expression(token)?,
638 Rule::negate_op => {
639 let unary_token = pair.next().unwrap();
640 let unary = self.eval_unary_exp(unary_token)?;
641 Val::Bool(!unary.cast_to_bool())
642 }
643 Rule::bitwise_negate_op => {
644 let unary_token = pair.next().unwrap();
645 let unary = self.eval_unary_exp(unary_token)?;
646 Val::Int(!unary.cast_to_int()?)
647 }
648 _ => unexpected_token!(token),
649 };
650
651 Ok(res)
652 }
653
654 fn eval_argument_list(&mut self, token: Pair<'a>) -> ParserResult<Vec<Val>> {
655 check_rule!(token, Rule::argument_list);
656 let pairs = token.into_inner();
657
658 let mut args = Vec::new();
659 for token in pairs {
660 args.push(self.eval_expression(token)?);
661 }
662
663 Ok(args)
664 }
665
666 fn eval_member_access(&mut self, token: Pair<'a>) -> ParserResult<String> {
667 let member_name_token = token.into_inner().next().unwrap();
669 let member_name = member_name_token.as_str().to_ascii_lowercase();
670
671 Ok(member_name)
672 }
673
674 fn method_is_static(&mut self, token: Pair<'a>) -> bool {
675 check_rule!(token, Rule::method_invocation);
676 let mut pairs = token.into_inner();
677
678 let access = pairs.next().unwrap();
679 match access.as_rule() {
680 Rule::member_access => false,
681 Rule::static_access => true,
682 _ => todo!(),
683 }
684 }
685
686 fn eval_method_invokation(&mut self, token: Pair<'a>) -> ParserResult<(String, Vec<Val>)> {
687 check_rule!(token, Rule::method_invocation);
688 let token_string = token.as_str().to_string();
689
690 let mut pairs = token.into_inner();
691
692 let access = pairs.next().unwrap();
693 let method_name = self.eval_member_access(access)?;
695
696 let args = if let Some(token) = pairs.next() {
697 check_rule!(token, Rule::argument_list);
698 self.eval_argument_list(token)?
699 } else {
700 Vec::new()
701 };
702
703 self.tokens.push(Token::Function(
704 token_string,
705 method_name.clone(),
706 args.clone().iter().map(|arg| arg.clone().into()).collect(),
707 ));
708 Ok((method_name, args))
709 }
710
711 fn eval_access(&mut self, token: Pair<'a>) -> ParserResult<Val> {
712 fn get_member_name(token: Pair<'_>) -> &'_ str {
713 token.into_inner().next().unwrap().as_str()
714 }
715 check_rule!(token, Rule::access);
716 let mut pairs = token.into_inner();
717 let token = pairs.next().unwrap();
718
719 let mut object = self.eval_value(token)?;
720
721 for token in pairs {
722 match token.as_rule() {
723 Rule::static_access => {
724 object = object.get_static_member(get_member_name(token))?;
725 }
726 Rule::member_access => {
727 object = object.get_member(get_member_name(token))?;
728 }
729 Rule::method_invocation => {
730 let static_method = self.method_is_static(token.clone());
731 let (function_name, args) = self.eval_method_invokation(token)?;
732 log::trace!("Method: {:?} {:?}", &function_name, &args);
733 object = if static_method {
734 let call = object.get_static_fn(function_name.as_str())?;
735 call(args)?
736 } else {
737 let call = object.get_method(function_name.as_str())?;
738 call(object, args)?
739 };
740 }
741 Rule::element_access => {
742 let mut pairs = token.into_inner();
743 let index_token = pairs.next().unwrap();
744 check_rule!(index_token, Rule::expression);
745 let index = self.eval_expression(index_token)?;
746 object = object.get_index(index)?;
747 }
748 _ => unexpected_token!(token),
749 }
750 }
751 log::debug!("Success eval_access: {:?}", object);
752 Ok(object)
753 }
754
755 fn parse_access(&mut self, token: Pair<'a>) -> ParserResult<Val> {
756 check_rule!(token, Rule::access);
757 let mut pairs = token.into_inner();
758 let token = pairs.next().unwrap();
759
760 let mut object = token.as_str().to_string();
761
762 for token in pairs {
763 match token.as_rule() {
764 Rule::static_access => {
765 object.push_str("::");
766 object.push_str(token.as_str());
767 }
768 Rule::member_access => {
769 object.push_str(token.as_str());
771 }
772 Rule::method_invocation => {
773 let static_method = self.method_is_static(token.clone());
774 let (method_name, args) = self.eval_method_invokation(token)?;
775
776 let separator = if static_method { "::" } else { "." };
777 object = format!(
778 "{}{separator}{}({:?})",
779 object,
780 method_name.to_ascii_lowercase(),
781 args
782 )
783 }
784 Rule::element_access => {
785 let mut pairs = token.into_inner();
786 let index_token = pairs.next().unwrap();
787 check_rule!(index_token, Rule::expression);
788 let index = self.eval_expression(index_token)?;
789 object = format!("{}[{}]", object, index);
790 }
791 _ => unexpected_token!(token),
792 }
793 }
794 Ok(Val::String(object.into()))
795 }
796
797 fn eval_primary_expression(&mut self, token: Pair<'a>) -> ParserResult<Val> {
798 check_rule!(token, Rule::primary_expression);
799 let mut pair = token.into_inner();
800 let token = pair.next().unwrap();
801 let res = match token.as_rule() {
802 Rule::access => match self.eval_access(token.clone()) {
803 Ok(res) => res,
804 Err(err) => {
805 log::info!("eval_access error: {:?}", err);
806 self.errors.push(err);
807 self.parse_access(token)?
808 }
809 },
810 Rule::value => self.eval_value(token)?,
811 Rule::post_inc_expression => {
812 let variable_token = token.into_inner().next().unwrap();
813 let var_name = Self::parse_variable(variable_token)?;
814 let mut var = self.variables.get(&var_name).unwrap_or_default();
815 let var_to_return = var.clone();
816
817 var.inc()?;
818 self.variables.set(&var_name, var.clone())?;
819
820 var_to_return
822 }
823 Rule::post_dec_expression => {
824 let variable_token = token.into_inner().next().unwrap();
825 let var_name = Self::parse_variable(variable_token)?;
826 let mut var = self.variables.get(&var_name).unwrap_or_default();
827 let var_to_return = var.clone();
828
829 var.dec()?;
830 self.variables.set(&var_name, var.clone())?;
831
832 var_to_return
833 }
834 _ => unexpected_token!(token),
835 };
836
837 Ok(res)
838 }
839
840 fn eval_type_literal(&mut self, token: Pair<'a>) -> ParserResult<ValType> {
841 check_rule!(token, Rule::type_literal);
842
843 let token = token.into_inner().next().unwrap();
844 check_rule!(token, Rule::type_spec);
845 Ok(ValType::cast(token.as_str())?)
846 }
847
848 fn parse_script_block(&mut self, token: Pair<'a>) -> ParserResult<ScriptBlock> {
849 check_rule!(token, Rule::script_block);
850
851 let raw_text = token.as_str().to_string();
852
853 let mut pairs = token.into_inner();
854 let Some(mut token) = pairs.next() else {
855 return Ok(ScriptBlock::new(vec![], String::new(), raw_text));
856 };
857 let (params, _params_str) = if token.as_rule() == Rule::param_block {
860 let params = self.parse_param_block(token.clone())?;
861 let params_str = token.as_str().to_string();
862 token = pairs.next().unwrap();
863 (params, params_str)
864 } else {
865 (vec![], String::new())
866 };
867
868 check_rule!(token, Rule::script_block_body);
869 let script_body = token.as_str().to_string();
870
871 Ok(ScriptBlock::new(params, script_body, raw_text))
872
873 }
881
882 fn parse_script_block_expression(&mut self, token: Pair<'a>) -> ParserResult<ScriptBlock> {
883 check_rule!(token, Rule::script_block_expression);
884 let mut pairs = token.into_inner();
885 self.parse_script_block(pairs.next().unwrap())
886 }
887
888 fn eval_hash_key(&mut self, token: Pair<'a>) -> ParserResult<String> {
889 check_rule!(token, Rule::key_expression);
890 let mut pairs = token.into_inner();
891 let key_token = pairs.next().unwrap();
892
893 Ok(match key_token.as_rule() {
894 Rule::simple_name => key_token.as_str().to_ascii_lowercase(),
895 Rule::unary_exp => self
896 .eval_unary_exp(key_token)?
897 .cast_to_string()
898 .to_ascii_lowercase(),
899 _ => unexpected_token!(key_token),
900 })
901 }
902
903 fn eval_hash_entry(&mut self, token: Pair<'a>) -> ParserResult<(String, Val)> {
904 check_rule!(token, Rule::hash_entry);
905
906 let mut pairs = token.into_inner();
907 let token_key = pairs.next().unwrap();
908 let token_value = pairs.next().unwrap();
909
910 Ok((
911 self.eval_hash_key(token_key)?,
912 self.eval_statement(token_value)?,
913 ))
914 }
915
916 fn eval_hash_literal(&mut self, token: Pair<'a>) -> ParserResult<Val> {
917 check_rule!(token, Rule::hash_literal_expression);
918 let pairs = token.into_inner();
919 let mut hash = HashMap::new();
920 for token in pairs {
921 let (key, value) = self.eval_hash_entry(token)?;
922 hash.insert(key, value);
923 }
924 Ok(Val::HashTable(hash))
925 }
926
927 fn eval_value(&mut self, token: Pair<'a>) -> ParserResult<Val> {
928 check_rule!(token, Rule::value);
929 let mut pair = token.into_inner();
930 let token = pair.next().unwrap();
931
932 let res = match token.as_rule() {
933 Rule::parenthesized_expression => {
934 let token = token.into_inner().next().unwrap();
935 self.safe_eval_pipeline(token)?
936 }
937 Rule::sub_expression | Rule::array_expression => {
938 let statements = self.eval_statements(token)?;
939 if statements.len() == 1 && statements[0].ttype() == ValType::Array {
940 statements[0].clone()
941 } else {
942 Val::Array(statements)
943 }
944 }
945 Rule::script_block_expression => {
946 Val::ScriptBlock(self.parse_script_block_expression(token)?)
947 }
948 Rule::hash_literal_expression => self.eval_hash_literal(token)?,
949 Rule::string_literal => self.eval_string_literal(token)?,
950 Rule::number_literal => self.eval_number_literal(token)?,
951 Rule::type_literal => Val::init(self.eval_type_literal(token)?)?,
952 Rule::variable => self.get_variable(token)?,
953 _ => unexpected_token!(token),
954 };
955 log::debug!("eval_value - res: {:?}", res);
956 Ok(res)
957 }
958
959 fn eval_number_literal(&mut self, token: Pair<'a>) -> ParserResult<Val> {
960 check_rule!(token, Rule::number_literal);
961 let mut negate = false;
962 let mut pairs = token.into_inner();
963 let mut token = pairs.next().unwrap();
964
965 if token.as_rule() == Rule::minus {
967 negate = true;
968 token = pairs.next().unwrap();
969 } else if token.as_rule() == Rule::plus {
970 token = pairs.next().unwrap();
971 }
972
973 let mut val = self.eval_number(token)?;
974
975 if negate {
976 val.neg()?;
977 }
978
979 if let Some(unit) = pairs.next() {
980 let unit = unit.as_str().to_ascii_lowercase();
981 let unit_int = match unit.as_str() {
982 "k" => 1024,
983 "m" => 1024 * 1024,
984 "g" => 1024 * 1024 * 1024,
985 "t" => 1024 * 1024 * 1024 * 1024,
986 "p" => 1024 * 1024 * 1024 * 1024 * 1024,
987 _ => 1,
988 };
989 val.mul(Val::Int(unit_int))?;
990 }
991 Ok(val)
992 }
993
994 fn eval_number(&mut self, token: Pair<'a>) -> ParserResult<Val> {
995 check_rule!(token, Rule::number);
996 let mut pairs = token.into_inner();
997 let token = pairs.next().unwrap();
998 let v = match token.as_rule() {
999 Rule::decimal_integer => {
1000 let int_val = token.into_inner().next().unwrap();
1001 Val::Int(int_val.as_str().parse::<i64>().unwrap())
1002 }
1003 Rule::hex_integer => {
1004 let int_val = token.into_inner().next().unwrap();
1005 Val::Int(i64::from_str_radix(int_val.as_str(), 16).unwrap())
1006 }
1007 Rule::float => {
1008 let float_str = token.as_str().trim();
1009 Val::Float(float_str.parse::<f64>()?)
1010 }
1012 _ => unexpected_token!(token),
1013 };
1014 Ok(v)
1015 }
1016
1017 fn eval_unary_exp(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1018 check_rule!(token, Rule::unary_exp);
1019 let token = token.into_inner().next().unwrap();
1020 match token.as_rule() {
1021 Rule::expression_with_unary_operator => self.eval_expression_with_unary_operator(token),
1022 Rule::primary_expression => self.eval_primary_expression(token),
1023 _ => unexpected_token!(token),
1024 }
1025 }
1026
1027 fn eval_array_literal_exp(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1028 check_rule!(token, Rule::array_literal_exp);
1029 let mut arr = Vec::new();
1030 let mut pairs = token.into_inner();
1031 arr.push(self.eval_unary_exp(pairs.next().unwrap())?);
1032 for token in pairs {
1033 arr.push(self.eval_unary_exp(token)?);
1034 }
1035
1036 Ok(if arr.len() == 1 {
1037 arr[0].clone()
1038 } else {
1039 Val::Array(arr)
1040 })
1041 }
1042
1043 fn eval_range_exp(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1044 fn range(mut left: i64, right: i64) -> Vec<Val> {
1045 let mut v = Vec::new();
1046 if left <= right {
1047 loop {
1048 v.push(left);
1049 if left == right {
1050 break;
1051 }
1052 left += 1;
1053 }
1054 } else {
1055 loop {
1056 v.push(left);
1057 if left == right {
1058 break;
1059 }
1060 left -= 1;
1061 }
1062 }
1063 v.into_iter().map(Val::Int).collect()
1064 }
1065 check_rule!(token, Rule::range_exp);
1066 let mut pairs = token.into_inner();
1067 let token = pairs.next().unwrap();
1068 let res = match token.as_rule() {
1069 Rule::decimal_integer => {
1070 let int_val = token.into_inner().next().unwrap();
1071 let left = int_val.as_str().parse::<i64>().unwrap();
1072 let token = pairs.next().unwrap();
1073 let right = self.eval_array_literal_exp(token)?.cast_to_int()?;
1074 Val::Array(range(left, right))
1075 }
1076 Rule::array_literal_exp => {
1077 let res = self.eval_array_literal_exp(token)?;
1078 if let Some(token) = pairs.next() {
1079 let left = res.cast_to_int()?;
1080 let right = self.eval_array_literal_exp(token)?.cast_to_int()?;
1081 Val::Array(range(left, right))
1082 } else {
1083 res
1084 }
1085 }
1086 _ => unexpected_token!(token),
1087 };
1088
1089 Ok(res)
1090 }
1091
1092 fn eval_format_impl(&mut self, format: Val, mut pairs: Pairs<'a>) -> ParserResult<Val> {
1093 fn format_with_vec(fmt: &str, args: Vec<Val>) -> ParserResult<String> {
1094 fn strange_special_case(fmt: &str, n: i64) -> String {
1095 fn split_digits(n: i64) -> Vec<u8> {
1096 n.abs() .to_string()
1098 .chars()
1099 .filter_map(|c| c.to_digit(10).map(|opt| opt as u8))
1100 .collect()
1101 }
1102
1103 let mut digits = split_digits(n);
1105 digits.reverse();
1106 let mut fmt_vec = fmt.as_bytes().to_vec();
1107 fmt_vec.reverse();
1108
1109 let mut i = 0;
1110 for digit in digits {
1111 while i < fmt_vec.len() {
1112 if fmt_vec[i] != b'0' {
1113 i += 1
1114 } else {
1115 fmt_vec[i] = digit + b'0';
1116 break;
1117 }
1118 }
1119 }
1120 fmt_vec.reverse();
1121 String::from_utf8(fmt_vec).unwrap_or_default()
1122 }
1123
1124 let mut output = String::new();
1125 let mut i = 0;
1126
1127 while i < fmt.len() {
1128 if fmt[i..].starts_with('{') {
1129 if let Some(end) = fmt[i..].find('}') {
1130 let token = &fmt[i + 1..i + end];
1131 let formatted = if token.contains(':') {
1132 let mut parts = token.split(':');
1133 let index: usize = if let Some(p) = parts.next() {
1134 p.parse().unwrap_or(0)
1135 } else {
1136 0
1137 };
1138
1139 let spec = parts.next();
1140 match args.get(index) {
1141 Some(val) => match spec {
1142 Some(s) if s.starts_with('N') => {
1143 let precision = s[1..].parse::<usize>().unwrap_or(2);
1144 if let Ok(f) = val.cast_to_float() {
1145 format!("{:.1$}", f, precision)
1146 } else {
1147 val.cast_to_string().to_string()
1148 }
1149 }
1150 Some(s) => strange_special_case(s, val.cast_to_int()?),
1151 None => val.cast_to_string().to_string(),
1152 },
1153 None => format!("{{{}}}", token), }
1156 } else if token.contains(',') {
1157 let mut parts = token.split(',');
1158 let index: usize = parts.next().unwrap().parse().unwrap_or(0);
1159 let spec = parts.next();
1160 match args.get(index) {
1161 Some(val) => match spec {
1162 Some(s) => {
1163 let spaces = s.parse::<usize>().unwrap_or(0);
1164 let spaces_str = " ".repeat(spaces);
1165 format!("{spaces_str}{}", val.cast_to_string())
1166 }
1167 _ => val.cast_to_string().to_string(),
1168 },
1169 None => format!("{{{}}}", token), }
1172 } else {
1173 let index: usize =
1174 Val::String(token.to_string().into()).cast_to_int()? as usize;
1175 match args.get(index) {
1176 Some(val) => val.cast_to_string().to_string(),
1177 None => format!("{{{}}}", token), }
1180 };
1181
1182 output.push_str(&formatted);
1183 i += end + 1;
1184 } else {
1185 output.push('{');
1186 i += 1;
1187 }
1188 } else {
1189 output.push(fmt[i..].chars().next().unwrap());
1190 i += 1;
1191 }
1192 }
1193
1194 Ok(output)
1195 }
1196
1197 Ok(if let Some(token) = pairs.next() {
1198 let first_fmt = format.cast_to_string();
1199
1200 let second_fmt = self.eval_range_exp(token)?;
1201 let res = self.eval_format_impl(second_fmt, pairs)?;
1202 Val::String(format_with_vec(first_fmt.as_str(), res.cast_to_array())?.into())
1203 } else {
1204 format
1205 })
1206 }
1207
1208 fn eval_format_exp(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1209 check_rule!(token, Rule::format_exp);
1210 let mut pairs = token.into_inner();
1211 let format = self.eval_range_exp(pairs.next().unwrap())?;
1212 self.eval_format_impl(format, pairs)
1213 }
1214
1215 fn eval_mult(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1216 check_rule!(token, Rule::multiplicative_exp);
1217 let mut pairs = token.into_inner();
1218 let mut res = self.eval_format_exp(pairs.next().unwrap())?;
1219 while let Some(op) = pairs.next() {
1220 let Some(fun) = ArithmeticPred::get(op.as_str()) else {
1221 log::error!("No arithmetic function for operator: {}", op.as_str());
1222 return Err(ParserError::NotImplemented(format!(
1223 "No arithmetic function for operator: {}",
1224 op.as_str()
1225 )));
1226 };
1227
1228 let postfix = pairs.next().unwrap();
1229 let right_op = self.eval_format_exp(postfix)?;
1230 res = fun(res, right_op)?;
1231 }
1232
1233 Ok(res)
1234 }
1235
1236 fn eval_additive(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1237 check_rule!(token, Rule::additive_exp);
1238
1239 let mut pairs = token.into_inner();
1240 let mut res = self.eval_mult(pairs.next().unwrap())?;
1241 while let Some(op) = pairs.next() {
1242 let Some(fun) = ArithmeticPred::get(op.as_str()) else {
1244 log::error!("No arithmetic function for operator: {}", op.as_str());
1245 return Err(ParserError::NotImplemented(format!(
1246 "No arithmetic function for operator: {}",
1247 op.as_str()
1248 )));
1249 };
1250
1251 let mult = pairs.next().unwrap();
1252 let right_op = self.eval_mult(mult)?;
1253 res = fun(res, right_op)?;
1254 }
1255
1256 Ok(res)
1257 }
1258
1259 fn eval_split_special_case(
1260 &mut self,
1261 script_block: ScriptBlock,
1262 input: Val,
1263 ) -> ParserResult<Vec<String>> {
1264 let mut res_vec = vec![];
1265 let mut parts = String::new();
1266 let input_str = input.cast_to_string();
1267 let characters = input_str.chars();
1268
1269 for ch in characters {
1271 let b = match script_block.run(vec![], self, Some(Val::String(ch.to_string().into()))) {
1272 Err(er) => {
1273 self.errors.push(er);
1274 false
1275 }
1276 Ok(res) => res.val.cast_to_bool(),
1277 };
1278
1279 if b {
1280 res_vec.push(parts);
1281 parts = String::new();
1282 } else {
1283 parts.push(ch);
1284 }
1285 }
1286 self.variables.reset_ps_item();
1287 Ok(res_vec)
1288 }
1289
1290 fn eval_comparison_exp(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1291 check_rule!(token, Rule::comparison_exp);
1292 let mut pairs = token.into_inner();
1293 let token = pairs.next().unwrap();
1294
1295 let mut res = if token.as_rule() == Rule::additive_exp {
1298 self.eval_additive(token)?
1299 } else {
1300 Val::Null
1301 };
1302
1303 while let Some(op) = pairs.next() {
1304 let Some(fun) = StringPred::get(op.as_str()) else {
1305 log::error!("No string predicate for operator: {}", op.as_str());
1306 return Err(ParserError::NotImplemented(format!(
1307 "No string predicate for operator: {}",
1308 op.as_str()
1309 )));
1310 };
1311
1312 let token = pairs.next().unwrap();
1313 let right_op = match token.as_rule() {
1314 Rule::script_block_expression => {
1315 let script_block = self.parse_script_block_expression(token)?;
1316
1317 return Ok(Val::Array(
1318 self.eval_split_special_case(script_block, res)?
1319 .into_iter()
1320 .map(|s| Val::String(s.into()))
1321 .collect::<Vec<_>>(),
1322 ));
1323 }
1324 Rule::additive_exp => self.eval_additive(token)?,
1325 _ => unexpected_token!(token),
1326 };
1327 log::trace!("res: {:?}, right_op: {:?}", &res, &right_op);
1328 res = fun(res, right_op)?;
1329 log::trace!("res: {:?}", &res);
1330 }
1331
1332 Ok(res)
1333 }
1334
1335 fn parse_param_block(&mut self, token: Pair<'a>) -> ParserResult<Vec<Param>> {
1336 check_rule!(token, Rule::param_block);
1337 let mut pairs = token.into_inner();
1338 let Some(token) = pairs.next() else {
1339 return Ok(vec![]);
1340 };
1341
1342 self.parse_parameter_list(token)
1343 }
1344
1345 fn parse_parameter_list(&mut self, token: Pair<'a>) -> ParserResult<Vec<Param>> {
1346 check_rule!(token, Rule::parameter_list);
1347 let mut params = vec![];
1348 let param_list_pairs = token.into_inner();
1349 for script_parameter_token in param_list_pairs {
1350 check_rule!(script_parameter_token, Rule::script_parameter);
1351 params.push(self.parse_script_parameter(script_parameter_token)?);
1352 }
1353 Ok(params)
1354 }
1355
1356 fn parse_attribute_list(&mut self, token: Pair<'a>) -> ParserResult<Option<ValType>> {
1357 check_rule!(token, Rule::attribute_list);
1358 let attribute_list_pairs = token.into_inner();
1359 for attribute_token in attribute_list_pairs {
1360 check_rule!(attribute_token, Rule::attribute);
1361 let attribute_type_token = attribute_token.into_inner().next().unwrap();
1362 match attribute_type_token.as_rule() {
1363 Rule::attribute_info => {
1364 continue;
1366 }
1367 Rule::type_literal => {
1368 return Ok(Some(self.eval_type_literal(attribute_type_token)?));
1369 }
1370 _ => unexpected_token!(attribute_type_token),
1371 }
1372 }
1373 Ok(None)
1374 }
1375 fn parse_script_parameter(&mut self, token: Pair<'a>) -> ParserResult<Param> {
1376 check_rule!(token, Rule::script_parameter);
1377 let mut pairs = token.into_inner();
1378 let mut token = pairs.next().unwrap();
1379
1380 let type_literal = if token.as_rule() == Rule::attribute_list {
1381 let type_literal = self.parse_attribute_list(token)?;
1382 token = pairs.next().unwrap();
1383 type_literal
1384 } else {
1385 None
1386 };
1387
1388 check_rule!(token, Rule::variable);
1389 let var_name = Self::parse_variable(token)?;
1390
1391 let default_value = if let Some(default_value_token) = pairs.next() {
1392 check_rule!(default_value_token, Rule::script_parameter_default);
1393 let default_value_expr = default_value_token.into_inner().next().unwrap();
1394 let default_value = self.eval_value(default_value_expr)?;
1395 Some(default_value)
1396 } else {
1397 None
1398 };
1399 Ok(Param::new(type_literal, var_name.name, default_value))
1400 }
1401
1402 fn eval_bitwise_exp(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1403 check_rule!(token, Rule::bitwise_exp);
1404
1405 let mut pairs = token.into_inner();
1406 let mut res = self.eval_comparison_exp(pairs.next().unwrap())?;
1407 while let Some(op) = pairs.next() {
1408 check_rule!(op, Rule::bitwise_operator);
1409 let Some(fun) = BitwisePred::get(op.as_str()) else {
1410 log::error!("No bitwise predicate for operator: {}", op.as_str());
1411 return Err(ParserError::NotImplemented(format!(
1412 "No bitwise predicate for operator: {}",
1413 op.as_str()
1414 )));
1415 };
1416
1417 let mult = pairs.next().unwrap();
1418 let right_op = self.eval_comparison_exp(mult)?;
1419 res = fun(res, right_op);
1420 }
1421
1422 Ok(res)
1423 }
1424
1425 fn parse_cmdlet_command_name(&mut self, token: Pair<'a>) -> ParserResult<Command> {
1426 check_rule!(token, Rule::cmdlet_command);
1427
1428 let mut pairs = token.into_inner();
1429 let token = pairs.next().unwrap();
1430 let command_name = match token.as_rule() {
1431 Rule::command_name => token.as_str(),
1432 Rule::where_command_name => "where-object",
1433 Rule::foreach_command_name => "foreach-object",
1434 _ => unexpected_token!(token),
1435 };
1436
1437 let mut command = Command::cmdlet(command_name);
1438 if Rule::command_name == token.as_rule() {
1439 command.set_session_scope(SessionScope::New);
1440 }
1441 Ok(command)
1442 }
1443
1444 fn parse_command_args(&mut self, pairs: Pairs<'a>) -> ParserResult<Vec<CommandElem>> {
1445 let mut args = vec![];
1446 for command_element_token in pairs {
1447 let token_string = command_element_token.as_str().to_string();
1448 match command_element_token.as_rule() {
1449 Rule::command_argument => {
1450 let arg_token = command_element_token.into_inner().next().unwrap();
1451 let arg = match arg_token.as_rule() {
1452 Rule::array_literal_exp => self.eval_array_literal_exp(arg_token)?,
1453 Rule::script_block_expression => {
1454 Val::ScriptBlock(self.parse_script_block_expression(arg_token)?)
1455 }
1456 Rule::parenthesized_expression => {
1457 let token = arg_token.into_inner().next().unwrap();
1458 self.eval_pipeline(token)?
1459 }
1460 _ => Val::ScriptText(arg_token.as_str().to_string()),
1461 };
1462 args.push(CommandElem::Argument(arg));
1463 }
1464 Rule::command_parameter => {
1465 args.push(CommandElem::Parameter(token_string.to_ascii_lowercase()))
1466 }
1467 Rule::argument_list => args.push(CommandElem::ArgList(token_string)),
1468 Rule::redirection => { }
1470 Rule::stop_parsing => { }
1472 _ => unexpected_token!(command_element_token),
1473 }
1474 }
1475 Ok(args)
1476 }
1477
1478 fn eval_command(&mut self, token: Pair<'a>, piped_arg: Option<Val>) -> ParserResult<Val> {
1479 check_rule!(token, Rule::command);
1480 let mut pairs = token.into_inner();
1481
1482 let command_token = pairs.next().unwrap();
1483 let mut command = match command_token.as_rule() {
1484 Rule::cmdlet_command => self.parse_cmdlet_command_name(command_token)?,
1485 Rule::invocation_command => self.parse_invocation_command(command_token)?,
1486 _ => unexpected_token!(command_token),
1487 };
1488
1489 let mut args = self.parse_command_args(pairs)?;
1490 if let Some(arg) = piped_arg {
1491 args.insert(0, CommandElem::Argument(arg));
1492 }
1493
1494 command.with_args(args);
1495 match command.execute(self) {
1496 Ok(CommandOutput {
1497 val,
1498 deobfuscated: _deobfuscated,
1499 }) => Ok(val),
1500 Err(e) => {
1501 self.errors.push(e);
1502 Ok(Val::ScriptText(command.to_string()))
1503 }
1504 }
1505
1506 }
1510
1511 fn add_deobfuscated_statement(&mut self, msg: String) {
1512 if let Some(last) = self.results.last_mut() {
1513 last.deobfuscated.push(msg);
1514 }
1515 }
1516
1517 fn add_output_statement(&mut self, msg: StreamMessage) {
1518 if let Some(last) = self.results.last_mut() {
1519 last.output.push(msg);
1520 }
1521 }
1522
1523 fn parse_invocation_command(&mut self, token: Pair<'a>) -> ParserResult<Command> {
1524 check_rule!(token, Rule::invocation_command);
1525
1526 let invocation_command_token = token.into_inner().next().unwrap();
1527
1528 let mut session_scope = match invocation_command_token.as_rule() {
1529 Rule::current_scope_invocation_command => SessionScope::Current,
1530 Rule::new_scope_invocation_command => SessionScope::New,
1531 _ => unexpected_token!(invocation_command_token),
1532 };
1533
1534 let token_inner = invocation_command_token.into_inner().next().unwrap();
1535
1536 let mut command = match token_inner.as_rule() {
1537 Rule::cmdlet_command => {
1538 session_scope = SessionScope::New;
1539 self.parse_cmdlet_command_name(token_inner)?
1540 }
1541 Rule::primary_expression => {
1542 let primary = self.eval_primary_expression(token_inner)?;
1543 let script_block = if let Val::ScriptBlock(script_block) = primary {
1544 script_block
1545 } else {
1546 ScriptBlock::new(vec![], primary.cast_to_script(), primary.cast_to_script())
1547 };
1548 Command::script_block(script_block)
1549 }
1550 Rule::path_command_name => Command::path(token_inner.as_str()),
1551 _ => unexpected_token!(token_inner),
1552 };
1553
1554 command.set_session_scope(session_scope);
1555 Ok(command)
1556 }
1557
1558 fn eval_redirected_expression(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1559 check_rule!(token, Rule::redirected_expression);
1560
1561 let expression_token = token.into_inner().next().unwrap();
1562 self.eval_expression(expression_token)
1565 }
1566
1567 fn eval_expression(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1568 check_rule!(token, Rule::expression);
1569 let token_string = token.as_str().trim().to_string();
1570
1571 let mut pairs = token.into_inner();
1572 let mut res = self.eval_bitwise_exp(pairs.next().unwrap())?;
1573 while let Some(op) = pairs.next() {
1574 check_rule!(op, Rule::logical_operator);
1575 let Some(fun) = LogicalPred::get(op.as_str()) else {
1576 log::error!("No logical predicate for operator: {}", op.as_str());
1577 return Err(ParserError::NotImplemented(format!(
1578 "No logical predicate for operator: {}",
1579 op.as_str()
1580 )));
1581 };
1582
1583 let mult = pairs.next().unwrap();
1584 let right_op = self.eval_bitwise_exp(mult)?;
1585 res = Val::Bool(fun(res, right_op));
1586 }
1587 self.tokens
1588 .push(Token::Expression(token_string, res.clone().into()));
1589
1590 Ok(res)
1591 }
1592
1593 fn eval_pipeline_tail(&mut self, token: Pair<'a>, mut piped_arg: Val) -> ParserResult<Val> {
1594 check_rule!(token, Rule::pipeline_tail);
1595 let pairs = token.into_inner();
1596
1597 for token in pairs {
1598 piped_arg = self.eval_command(token, Some(piped_arg))?;
1600 }
1601
1602 Ok(piped_arg)
1603 }
1604
1605 fn eval_pipeline_with_tail(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1606 check_rule!(token, Rule::pipeline_with_tail);
1607 let mut pairs = token.into_inner();
1608 let token = pairs.next().unwrap();
1609
1610 let result: Val = match token.as_rule() {
1611 Rule::redirected_expression => self.eval_redirected_expression(token)?,
1612 Rule::command => self.eval_command(token, None)?,
1613 _ => unexpected_token!(token),
1614 };
1615
1616 if let Some(token) = pairs.next() {
1617 match token.as_rule() {
1618 Rule::pipeline_tail => Ok(self.eval_pipeline_tail(token, result)?),
1619 _ => unexpected_token!(token),
1620 }
1621 } else {
1622 Ok(result)
1623 }
1624 }
1625
1626 fn eval_pipeline(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1627 check_rule!(token, Rule::pipeline);
1628 let mut pairs = token.into_inner();
1629 let token = pairs.next().unwrap();
1630
1631 match token.as_rule() {
1632 Rule::assignment_exp => self.eval_assigment_exp(token),
1633 Rule::pipeline_with_tail => self.eval_pipeline_with_tail(token),
1634 _ => unexpected_token!(token),
1635 }
1636 }
1637
1638 fn safe_eval_pipeline(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1639 let res = self.eval_pipeline(token.clone());
1640
1641 let v = match res {
1642 Ok(val) => val,
1643 Err(err) => {
1644 self.errors.push(err);
1645 Val::ScriptText(token.as_str().to_string())
1646 }
1647 };
1648
1649 Ok(v)
1650 }
1651
1652 fn eval_cast_expression(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1653 check_rule!(token, Rule::cast_expression);
1654
1655 let mut pairs = token.into_inner();
1656 let type_token = pairs.next().unwrap();
1657 check_rule!(type_token, Rule::type_literal);
1658 let val_type = self.eval_type_literal(type_token)?;
1659
1660 let token = pairs.next().unwrap();
1661 let res = match token.as_rule() {
1662 Rule::parenthesized_expression => {
1663 let token = token.into_inner().next().unwrap();
1664 self.safe_eval_pipeline(token)?
1665 }
1666 Rule::range_exp => self.eval_range_exp(token)?,
1667 Rule::unary_exp => self.eval_unary_exp(token)?,
1668 _ => unexpected_token!(token),
1669 };
1670
1671 Ok(res.cast(val_type)?)
1672 }
1673
1674 fn eval_assigment_exp(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1675 check_rule!(token, Rule::assignment_exp);
1676
1677 let mut pairs = token.into_inner();
1678 let variable_token = pairs.next().unwrap();
1679 let var_name = Self::parse_variable(variable_token)?;
1680 let var = self.variables.get(&var_name).unwrap_or_default();
1681
1682 let assignement_op = pairs.next().unwrap();
1683
1684 let op = assignement_op.into_inner().next().unwrap();
1686 let pred = ArithmeticPred::get(op.as_str());
1687
1688 let right_token = pairs.next().unwrap();
1689 let right_op = self.eval_statement(right_token.clone())?;
1690
1691 let Some(pred) = pred else {
1692 log::error!("No arithmetic function for operator: {}", op.as_str());
1693 return Err(ParserError::NotImplemented(format!(
1694 "No arithmetic function for operator: {}",
1695 op.as_str()
1696 )));
1697 };
1698 let op_result = pred(var, right_op)?;
1699 self.variables.set(&var_name, op_result.clone())?;
1700
1701 self.add_deobfuscated_statement(format!("{} = {}", var_name, op_result.cast_to_script()));
1703
1704 Ok(Val::NonDisplayed(Box::new(op_result)))
1705 }
1706
1707 fn push_scope_session(&mut self) {
1708 self.variables.push_scope_session();
1709 }
1710
1711 fn pop_scope_session(&mut self) {
1712 self.variables.pop_scope_session();
1713 }
1714}
1715
1716#[cfg(test)]
1717mod tests {
1718 use pest::Parser;
1719
1720 use super::*;
1721
1722 #[test]
1723 fn comment_and_semicolon() {
1724 let input = r#"
1725# This is a single line comment
1726$a = 1; $b = 2; Write-Output $a
1727
1728Write-Output "Hello" # Another comment
1729
1730<#
1731 This is a
1732 multi-line block comment
1733#>
1734"#;
1735
1736 let _ = PowerShellSession::parse(Rule::program, input).unwrap();
1737 }
1738
1739 #[test]
1740 fn while_loop() {
1741 let input = r#"
1742while ($true) {
1743 if ($someCondition) {
1744 break
1745 }
1746 # other code
1747}
1748"#;
1749
1750 let _ = PowerShellSession::parse(Rule::program, input).unwrap();
1751 }
1752
1753 #[test]
1754 fn foreach_loop() {
1755 let input = r#"
1756foreach ($n in $numbers) {
1757 Write-Output $n
1758}
1759"#;
1760
1761 let _ = PowerShellSession::parse(Rule::program, input).unwrap();
1762 }
1763
1764 #[test]
1765 fn for_loop() {
1766 let input = r#"
1767# Comma separated assignment expressions enclosed in parentheses.
1768for (($i = 0), ($j = 0); $i -lt 10; $i++)
1769{
1770 "`$i:$i"
1771 "`$j:$j"
1772}
1773"#;
1774
1775 let _ = PowerShellSession::parse(Rule::program, input).unwrap();
1776 }
1777
1778 #[test]
1779 fn switch() {
1780 let input = r#"
1781switch ($var) {
1782 "a" { Write-Output "A" }
1783 1 { Write-Output "One" }
1784 default { Write-Output "Other" }
1785}
1786"#;
1787
1788 let _ = PowerShellSession::parse(Rule::program, input).unwrap();
1789 }
1790
1791 #[test]
1792 fn functions() {
1793 let input = r#"
1794function Get-Square {
1795 param($x)
1796 return $x * $x
1797}
1798
1799function Say-Hello {
1800 Write-Output "Hello"
1801}
1802"#;
1803
1804 let _ = PowerShellSession::parse(Rule::program, input).unwrap();
1805 }
1806
1807 #[test]
1808 fn if_expression() {
1809 let input = r#"
1810$x="hello"
1811 Write-Host $x
1812 $y = 42
1813 Start-Process "notepad.exe"
1814
1815 $x = 42
1816if ($x -eq 1) {
1817 Write-Output "One"
1818} elseif ($x -eq 2) {
1819 Write-Output "Two"
1820} else {
1821 Write-Output "Other"
1822}
1823"#;
1824
1825 let _ = PowerShellSession::parse(Rule::program, input).unwrap();
1826 }
1827
1828 #[test]
1829 fn command() {
1830 let input = r#"
1831Get-Process | Where-Object { $_.CPU -gt 100 }
1832"#;
1833
1834 let _ = PowerShellSession::parse(Rule::program, input).unwrap();
1835 }
1836
1837 #[test]
1838 fn range() {
1839 let input = r#"
1840$numbers = 1..5
1841"#;
1842
1843 let _ = PowerShellSession::parse(Rule::program, input).unwrap();
1844 }
1845
1846 #[test]
1847 fn literals() {
1848 let input = r#"
1849$hex = 0xFF
1850
1851$name = "Alice"
1852$msg = "Hello, $name. Today is $day."
1853$escaped = "She said: `"Hi`""
1854$literal = 'Hello, $name'
1855"#;
1856
1857 let _ = PowerShellSession::parse(Rule::program, input).unwrap();
1858 }
1859
1860 #[test]
1861 fn floats() {
1862 let input = r#"
1863 $pi = 3.1415
1864$half = .5
1865"#;
1866
1867 let _ = PowerShellSession::parse(Rule::program, input).unwrap();
1868 }
1869
1870 #[test]
1871 fn arrays() {
1872 let input = r#"
1873$a = 1, 2, 3
1874$b = @("one", "two", "three")
1875$c = @(1, 2, @(3, 4))
1876"#;
1877
1878 let _ = PowerShellSession::parse(Rule::program, input).unwrap();
1879 }
1880
1881 #[test]
1882 fn static_method_call() {
1883 let input = r#"
1884[Threading.Thread]::Sleep(399)
1885"#;
1886
1887 let _ = PowerShellSession::parse(Rule::program, input).unwrap();
1888 }
1889
1890 #[test]
1891 fn neg_pipeline() {
1892 let input = r#"
1893-not $input | Where-Object { $_ -gt 5 }
1894"#;
1895
1896 let _ = PowerShellSession::parse(Rule::program, input).unwrap();
1897 }
1898
1899 #[test]
1900 fn amsi_fail() {
1901 let input = r#"
1902#Matt Graebers second Reflection method
1903$VMRviwsbtehQfPtxbt=$null;
1904$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))"
1905
1906"#;
1907
1908 let _ = PowerShellSession::parse(Rule::program, input).unwrap();
1909 }
1910}