ps_parser/
parser.rs

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 = "\r\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 {
62        Self {
63            variables: Variables::new(),
64            tokens: Tokens::new(),
65            errors: Vec::new(),
66            output: Vec::new(),
67            deobfuscated_statements: Vec::new(),
68        }
69    }
70
71    pub fn with_variables(mut self, variables: Variables) -> Self {
72        self.variables = variables;
73        self
74    }
75
76    // pub fn errors(self) -> Vec<ParserError> {
77    //     self.errors
78    // }
79
80    pub fn parse_input(&mut self, input: &str) -> ParserResult<ScriptResult> {
81        let mut pairs = PowerShellSession::parse(Rule::program, input)?;
82        let program_token = pairs.next().expect("");
83
84        //let mut script_statements = Vec::new();
85        let mut script_last_output = Val::default();
86
87        if let Rule::program = program_token.as_rule() {
88            let pairs = program_token.into_inner();
89
90            //println!("token: {} deobfuscated: {:?}", token.as_str(),
91            // &self.deobfuscated_statements);
92            for token in pairs {
93                let token_str = token.as_str();
94                let result = match token.as_rule() {
95                    Rule::pipeline => {
96                        //first assign to output, later create from it script line
97                        //self.eval_pipeline(token.clone())
98                        let mut pairs = token.into_inner();
99                        let token = pairs.next().unwrap();
100
101                        match token.as_rule() {
102                            Rule::assignment_exp => {
103                                let result = self.eval_assigment_exp(token);
104                                //we don't want print assignent result to deobfuscated script.
105                                // Thats why we always return null
106                                result.map(|_| Val::Null)
107                            }
108                            Rule::pipeline_with_tail => self.eval_pipeline_with_tail(token),
109                            _ => panic!("not possible: {:?}", token.as_rule()),
110                        }
111                    }
112                    Rule::statement_terminator => continue,
113                    Rule::EOI => break,
114                    _ => {
115                        log::error!("parse_input not implemented: {:?}", token.as_rule());
116                        Err(ParserError::NotImplemented(format!(
117                            "Not implemented: {:?}",
118                            token.as_rule()
119                        )))
120                    }
121                };
122
123                self.variables.set_status(result.is_ok());
124
125                script_last_output = match result {
126                    Ok(val) => {
127                        if val != Val::Null {
128                            self.output.push(val.display().into());
129                        }
130
131                        val
132                    }
133                    Err(e) => {
134                        self.errors.push(e);
135                        self.deobfuscated_statements.push(token_str.into());
136                        Val::Null
137                    }
138                };
139            }
140        }
141
142        Ok(ScriptResult::new(
143            script_last_output,
144            std::mem::take(&mut self.output),
145            std::mem::take(&mut self.deobfuscated_statements),
146            std::mem::take(&mut self.tokens),
147            std::mem::take(&mut self.errors),
148        ))
149    }
150
151    pub(crate) fn eval_script_block(
152        &mut self,
153        input: &ScriptBlock,
154        ps_item: &Val,
155    ) -> ParserResult<bool> {
156        self.variables.set_ps_item(ps_item.clone());
157        let mut new_session = PowerShellSession::new().with_variables(self.variables.clone());
158        let res = new_session
159            .parse_input(input.0.as_str())?
160            .result()
161            .is_true();
162        self.variables.reset_ps_item();
163        Ok(res)
164    }
165
166    pub fn safe_eval(&mut self, input: &str) -> ParserResult<String> {
167        Ok(self.parse_input(input)?.result().to_string())
168    }
169
170    fn eval_statement(&mut self, token: Pair<'a>) -> ParserResult<Val> {
171        match token.as_rule() {
172            Rule::pipeline => self.safe_eval_pipeline(token),
173            _ => Err(ParserError::NotImplemented(format!(
174                "Not implemented: {:?}",
175                token.as_rule()
176            )))?,
177        }
178    }
179
180    fn eval_statements(&mut self, token: Pair<'a>) -> ParserResult<Vec<Val>> {
181        //check_rule!(token, Rule::statements);
182        let pairs = token.into_inner();
183        let mut statements = vec![];
184
185        for token in pairs {
186            let s = self.eval_statement(token)?;
187            statements.push(s);
188        }
189        Ok(statements)
190    }
191
192    fn parse_dq(&mut self, token: Pair<'a>) -> ParserResult<String> {
193        let mut res_str = String::new();
194        let pairs = token.into_inner();
195        for token in pairs {
196            let token = token.into_inner().next().unwrap();
197            let s = match token.as_rule() {
198                Rule::variable => self.get_variable(token)?.cast_to_string(),
199                Rule::sub_expression => Val::Array(self.eval_statements(token)?).cast_to_string(),
200                Rule::backtick_escape => token
201                    .as_str()
202                    .strip_prefix("`")
203                    .unwrap_or_default()
204                    .to_string(),
205                _ => token.as_str().to_string(),
206            };
207            res_str.push_str(s.as_str());
208        }
209        Ok(res_str)
210    }
211
212    fn eval_string_literal(&mut self, token: Pair<'a>) -> ParserResult<Val> {
213        check_rule!(token, Rule::string_literal);
214        let mut pair = token.into_inner();
215        let token = pair.next().unwrap();
216        let cloned_token = token.clone();
217
218        let mut is_expandable = false;
219        let res = match token.as_rule() {
220            Rule::doublequoted_string_literal | Rule::doublequoted_multiline_string_literal => {
221                is_expandable = true;
222                self.parse_dq(token)?
223            }
224            Rule::singlequoted_string_literal => {
225                if let Some(stripped_prefix) = token.as_str().to_string().strip_prefix("'") {
226                    if let Some(stripped_suffix) = stripped_prefix.to_string().strip_suffix("'") {
227                        stripped_suffix.to_string()
228                    } else {
229                        panic!("no suffix")
230                    }
231                } else {
232                    panic!("no prefix")
233                }
234            }
235            Rule::singlequoted_multiline_string_literal => {
236                let mut res_str = String::new();
237                let pairs = token.into_inner();
238                for token in pairs {
239                    res_str.push_str(token.as_str());
240                }
241                res_str
242            }
243            _ => {
244                panic!("eval_string_literal - token.rule(): {:?}", token.as_rule());
245            }
246        };
247        let ps_token = if is_expandable {
248            Token::StringExpandable(cloned_token.as_str().to_string(), res.clone())
249        } else {
250            Token::String(cloned_token.as_str().to_string())
251        };
252        self.tokens.push(ps_token);
253
254        Ok(Val::String(res.into()))
255    }
256
257    fn get_variable(&mut self, token: Pair<'a>) -> ParserResult<Val> {
258        check_rule!(token, Rule::variable);
259        let var_name = Self::parse_variable(token)?;
260        let Some(var) = self.variables.get(&var_name) else {
261            return Err(ParserError::VariableError(VariableError::NotDefined(
262                var_name.name,
263            )));
264        };
265        Ok(var)
266    }
267
268    fn parse_variable(token: Pair<'a>) -> ParserResult<VarName> {
269        check_rule!(token, Rule::variable);
270        let mut pair = token.into_inner();
271        let token = pair.next().unwrap();
272
273        Ok(match token.as_rule() {
274            Rule::special_variable => VarName::new(Scope::Special, token.as_str().to_string()),
275            Rule::parenthesized_variable => {
276                Self::parse_variable(token.into_inner().next().unwrap())?
277            }
278            Rule::braced_variable => {
279                let token = token.into_inner().next().unwrap();
280                let var = token.as_str().to_ascii_lowercase();
281                let splits: Vec<&str> = var.split(":").collect();
282                if splits.len() == 2 {
283                    VarName::new(Scope::from(splits[0]), splits[1].to_string())
284                } else {
285                    VarName::new(Scope::Global, var)
286                }
287            }
288            Rule::scoped_variable => {
289                let mut pairs = token.into_inner();
290                let mut token = pairs.next().unwrap();
291
292                let scope = if token.as_rule() == Rule::scope_keyword {
293                    let scope = token.as_str().to_ascii_lowercase();
294                    token = pairs.next().unwrap();
295                    check_rule!(token, Rule::var_name);
296                    Scope::from(scope.as_str())
297                } else {
298                    Scope::Global
299                };
300                VarName::new(scope, token.as_str().to_ascii_lowercase())
301            }
302            _ => {
303                panic!("token.rule(): {:?}", token.as_rule());
304            }
305        })
306    }
307
308    fn eval_expression_with_unary_operator(&mut self, token: Pair<'a>) -> ParserResult<Val> {
309        check_rule!(token, Rule::expression_with_unary_operator);
310        let mut pair = token.into_inner();
311        let token = pair.next().unwrap();
312
313        let res = match token.as_rule() {
314            Rule::pre_inc_expression => {
315                let variable_token = token.into_inner().next().unwrap();
316                let var_name = Self::parse_variable(variable_token)?;
317                let mut var = self.variables.get(&var_name).unwrap_or_default();
318                var.inc()?;
319
320                self.variables.set(&var_name, var.clone())?;
321                var
322            }
323            Rule::pre_dec_expression => {
324                let variable_token = token.into_inner().next().unwrap();
325                let var_name = Self::parse_variable(variable_token)?;
326                let mut var = self.variables.get(&var_name).unwrap_or_default();
327                var.dec()?;
328
329                self.variables.set(&var_name, var.clone())?;
330                var
331            }
332            Rule::cast_expression => self.eval_cast_expression(token)?,
333            Rule::negate_op => {
334                let unary_token = pair.next().unwrap();
335                let unary = self.eval_unary_exp(unary_token)?;
336                Val::Bool(!unary.cast_to_bool())
337            }
338            Rule::bitwise_negate_op => {
339                let unary_token = pair.next().unwrap();
340                let unary = self.eval_unary_exp(unary_token)?;
341                Val::Int(!unary.cast_to_int()?)
342            }
343            _ => {
344                panic!("token.rule(): {:?}", token.as_rule());
345            }
346        };
347
348        Ok(res)
349    }
350
351    fn eval_argument_list(&mut self, token: Pair<'a>) -> ParserResult<Vec<Val>> {
352        check_rule!(token, Rule::argument_list);
353        let pairs = token.into_inner();
354
355        let mut args = Vec::new();
356        for token in pairs {
357            args.push(self.eval_expression(token)?);
358        }
359
360        Ok(args)
361    }
362
363    fn eval_member_access(&mut self, token: Pair<'a>) -> ParserResult<String> {
364        //check_rule!(token, Rule::member_access);
365        let member_name_token = token.into_inner().next().unwrap();
366        let member_name = member_name_token.as_str().to_ascii_lowercase();
367
368        Ok(member_name)
369    }
370
371    fn method_is_static(&mut self, token: Pair<'a>) -> bool {
372        check_rule!(token, Rule::method_invocation);
373        let mut pairs = token.into_inner();
374
375        let access = pairs.next().unwrap();
376        match access.as_rule() {
377            Rule::member_access => false,
378            Rule::static_access => true,
379            _ => todo!(),
380        }
381    }
382
383    fn eval_method_invokation(&mut self, token: Pair<'a>) -> ParserResult<(String, Vec<Val>)> {
384        check_rule!(token, Rule::method_invocation);
385        let token_string = token.as_str().to_string();
386
387        let mut pairs = token.into_inner();
388
389        let access = pairs.next().unwrap();
390        //check_rule!(member_access, Rule::member_access);
391        let method_name = self.eval_member_access(access)?;
392
393        let args = if let Some(token) = pairs.next() {
394            check_rule!(token, Rule::argument_list);
395            self.eval_argument_list(token)?
396        } else {
397            Vec::new()
398        };
399
400        self.tokens.push(Token::Function(
401            token_string,
402            method_name.clone(),
403            args.clone().iter().map(|arg| arg.clone().into()).collect(),
404        ));
405        Ok((method_name, args))
406    }
407
408    fn eval_access(&mut self, token: Pair<'a>) -> ParserResult<Val> {
409        fn get_member_name(token: Pair<'_>) -> &'_ str {
410            token.into_inner().next().unwrap().as_str()
411        }
412        check_rule!(token, Rule::access);
413        let mut pairs = token.into_inner();
414        let token = pairs.next().unwrap();
415
416        let mut object = self.eval_value(token)?;
417
418        for token in pairs {
419            match token.as_rule() {
420                Rule::static_access => {
421                    object = object.get_static_member(get_member_name(token))?;
422                }
423                Rule::member_access => {
424                    object = object.get_member(get_member_name(token))?;
425                }
426                Rule::method_invocation => {
427                    let static_method = self.method_is_static(token.clone());
428                    let (function_name, args) = self.eval_method_invokation(token)?;
429                    log::trace!("Method: {:?} {:?}", &function_name, &args);
430                    object = if static_method {
431                        let call = object.get_static_fn(function_name.as_str())?;
432                        call(args)?
433                    } else {
434                        let call = object.get_method(function_name.as_str())?;
435                        call(object, args)?
436                    };
437                }
438                Rule::element_access => {
439                    let mut pairs = token.into_inner();
440                    let index_token = pairs.next().unwrap();
441                    check_rule!(index_token, Rule::expression);
442                    let index = self.eval_expression(index_token)?;
443                    object = object.get_index(index)?;
444                }
445                _ => {
446                    panic!("token.rule(): {:?}", token.as_rule());
447                }
448            }
449        }
450        log::debug!("Success eval_access: {:?}", object);
451        Ok(object)
452    }
453
454    fn parse_access(&mut self, token: Pair<'a>) -> ParserResult<Val> {
455        check_rule!(token, Rule::access);
456        let mut pairs = token.into_inner();
457        let token = pairs.next().unwrap();
458
459        let mut object = token.as_str().to_string();
460
461        for token in pairs {
462            match token.as_rule() {
463                Rule::static_access => {
464                    object.push_str("::");
465                    object.push_str(token.as_str());
466                }
467                Rule::member_access => {
468                    //object.push('.');
469                    object.push_str(token.as_str());
470                }
471                Rule::method_invocation => {
472                    let static_method = self.method_is_static(token.clone());
473                    let (method_name, args) = self.eval_method_invokation(token)?;
474
475                    let separator = if static_method { "::" } else { "." };
476                    object = format!(
477                        "{}{separator}{}({:?})",
478                        object,
479                        method_name.to_ascii_lowercase(),
480                        args
481                    )
482                }
483                Rule::element_access => {
484                    let mut pairs = token.into_inner();
485                    let index_token = pairs.next().unwrap();
486                    check_rule!(index_token, Rule::expression);
487                    let index = self.eval_expression(index_token)?;
488                    object = format!("{}[{}]", object, index);
489                }
490                _ => {
491                    panic!("parse_access token.rule(): {:?}", token.as_rule());
492                }
493            }
494        }
495        Ok(Val::String(object.into()))
496    }
497
498    fn eval_primary_expression(&mut self, token: Pair<'a>) -> ParserResult<Val> {
499        check_rule!(token, Rule::primary_expression);
500        let mut pair = token.into_inner();
501        let token = pair.next().unwrap();
502        let res = match token.as_rule() {
503            Rule::access => match self.eval_access(token.clone()) {
504                Ok(res) => res,
505                Err(err) => {
506                    log::info!("eval_access error: {:?}", err);
507                    self.errors.push(err);
508                    self.parse_access(token)?
509                }
510            },
511            Rule::value => self.eval_value(token)?,
512            Rule::post_inc_expression => {
513                let variable_token = token.into_inner().next().unwrap();
514                let var_name = Self::parse_variable(variable_token)?;
515                let mut var = self.variables.get(&var_name).unwrap_or_default();
516                let var_to_return = var.clone();
517
518                var.inc()?;
519                self.variables.set(&var_name, var.clone())?;
520
521                //if var_to_return.ttype() ==
522                var_to_return
523            }
524            Rule::post_dec_expression => {
525                let variable_token = token.into_inner().next().unwrap();
526                let var_name = Self::parse_variable(variable_token)?;
527                let mut var = self.variables.get(&var_name).unwrap_or_default();
528                let var_to_return = var.clone();
529
530                var.dec()?;
531                self.variables.set(&var_name, var.clone())?;
532
533                var_to_return
534            }
535            _ => {
536                panic!(
537                    "eval_primary_expression: rule: {:?} str: {}",
538                    token.as_rule(),
539                    token.as_str()
540                );
541            }
542        };
543
544        Ok(res)
545    }
546
547    fn eval_type_literal(&mut self, token: Pair<'a>) -> ParserResult<ValType> {
548        check_rule!(token, Rule::type_literal);
549
550        let token = token.into_inner().next().unwrap();
551        check_rule!(token, Rule::type_spec);
552        Ok(ValType::cast(token.as_str())?)
553    }
554
555    fn parse_script_block_expression(&mut self, token: Pair<'a>) -> ParserResult<Val> {
556        check_rule!(token, Rule::script_block_expression);
557
558        let mut pairs = token.into_inner();
559        let token = pairs.next().unwrap();
560
561        Ok(Val::ScriptBlock(ScriptBlock(token.as_str().to_string())))
562    }
563
564    fn eval_hash_key(&mut self, token: Pair<'a>) -> ParserResult<String> {
565        check_rule!(token, Rule::key_expression);
566        let mut pairs = token.into_inner();
567        let key_token = pairs.next().unwrap();
568
569        Ok(match key_token.as_rule() {
570            Rule::simple_name => key_token.as_str().to_ascii_lowercase(),
571            Rule::unary_exp => self
572                .eval_unary_exp(key_token)?
573                .cast_to_string()
574                .to_ascii_lowercase(),
575            _ => {
576                panic!("key_token.rule(): {:?}", key_token.as_rule());
577            }
578        })
579    }
580
581    fn eval_hash_entry(&mut self, token: Pair<'a>) -> ParserResult<(String, Val)> {
582        check_rule!(token, Rule::hash_entry);
583
584        let mut pairs = token.into_inner();
585        let token_key = pairs.next().unwrap();
586        let token_value = pairs.next().unwrap();
587
588        Ok((
589            self.eval_hash_key(token_key)?,
590            self.eval_statement(token_value)?,
591        ))
592    }
593
594    fn eval_hash_literal(&mut self, token: Pair<'a>) -> ParserResult<Val> {
595        check_rule!(token, Rule::hash_literal_expression);
596        let pairs = token.into_inner();
597        let mut hash = HashMap::new();
598        for token in pairs {
599            let (key, value) = self.eval_hash_entry(token)?;
600            hash.insert(key, value);
601        }
602        Ok(Val::HashTable(hash))
603    }
604
605    fn eval_value(&mut self, token: Pair<'a>) -> ParserResult<Val> {
606        check_rule!(token, Rule::value);
607        let mut pair = token.into_inner();
608        let token = pair.next().unwrap();
609
610        let res = match token.as_rule() {
611            Rule::parenthesized_expression => {
612                let token = token.into_inner().next().unwrap();
613                self.safe_eval_pipeline(token)?
614            }
615            Rule::sub_expression | Rule::array_expression => {
616                let statements = self.eval_statements(token)?;
617                if statements.len() == 1 && statements[0].ttype() == ValType::Array {
618                    statements[0].clone()
619                } else {
620                    Val::Array(statements)
621                }
622            }
623            Rule::script_block_expression => self.parse_script_block_expression(token)?,
624            Rule::hash_literal_expression => self.eval_hash_literal(token)?,
625            Rule::string_literal => self.eval_string_literal(token)?,
626            Rule::number_literal => self.eval_number_literal(token)?,
627            Rule::type_literal => Val::init(self.eval_type_literal(token)?)?,
628            Rule::variable => self.get_variable(token)?,
629            _ => {
630                panic!("token.rule(): {:?}", token.as_rule());
631            }
632        };
633        log::debug!("eval_value - res: {:?}", res);
634        Ok(res)
635    }
636
637    fn eval_number_literal(&mut self, token: Pair<'a>) -> ParserResult<Val> {
638        check_rule!(token, Rule::number_literal);
639        let mut negate = false;
640        let mut pairs = token.into_inner();
641        let mut token = pairs.next().unwrap();
642
643        //first handle prefix sign: + or -
644        if token.as_rule() == Rule::minus {
645            negate = true;
646            token = pairs.next().unwrap();
647        } else if token.as_rule() == Rule::plus {
648            token = pairs.next().unwrap();
649        }
650
651        let mut val = self.eval_number(token)?;
652
653        if negate {
654            val.neg()?;
655        }
656
657        if let Some(unit) = pairs.next() {
658            let unit = unit.as_str().to_ascii_lowercase();
659            let unit_int = match unit.as_str() {
660                "k" => 1024,
661                "m" => 1024 * 1024,
662                "g" => 1024 * 1024 * 1024,
663                "t" => 1024 * 1024 * 1024 * 1024,
664                "p" => 1024 * 1024 * 1024 * 1024 * 1024,
665                _ => 1,
666            };
667            val.mul(Val::Int(unit_int))?;
668        }
669        Ok(val)
670    }
671
672    fn eval_number(&mut self, token: Pair<'a>) -> ParserResult<Val> {
673        check_rule!(token, Rule::number);
674        let mut pairs = token.into_inner();
675        let token = pairs.next().unwrap();
676        let v = match token.as_rule() {
677            Rule::decimal_integer => {
678                let int_val = token.into_inner().next().unwrap();
679                Val::Int(int_val.as_str().parse::<i64>().unwrap())
680            }
681            Rule::hex_integer => {
682                let int_val = token.into_inner().next().unwrap();
683                Val::Int(i64::from_str_radix(int_val.as_str(), 16).unwrap())
684            }
685            //todo: parse float in proper way
686            Rule::float => {
687                let float_str = token.as_str().trim();
688
689                match float_str.parse::<f64>() {
690                    Ok(float_val) => Val::Float(float_val),
691                    Err(err) => {
692                        println!("eval_number - invalid float: {}: asd {}", float_str, err);
693                        panic!("eval_number - invalid float: {}: {}", float_str, err);
694                    }
695                }
696            }
697            _ => {
698                panic!("eval_number - token.rule(): {:?}", token.as_rule());
699            }
700        };
701        Ok(v)
702    }
703
704    fn eval_unary_exp(&mut self, token: Pair<'a>) -> ParserResult<Val> {
705        check_rule!(token, Rule::unary_exp);
706        let token = token.into_inner().next().unwrap();
707        match token.as_rule() {
708            Rule::expression_with_unary_operator => self.eval_expression_with_unary_operator(token),
709            Rule::primary_expression => self.eval_primary_expression(token),
710            _ => {
711                panic!("eval_unary_exp token.rule(): {:?}", token.as_rule());
712            }
713        }
714    }
715
716    fn eval_array_literal_exp(&mut self, token: Pair<'a>) -> ParserResult<Val> {
717        check_rule!(token, Rule::array_literal_exp);
718        let mut arr = Vec::new();
719        let mut pairs = token.into_inner();
720        arr.push(self.eval_unary_exp(pairs.next().unwrap())?);
721        for token in pairs {
722            arr.push(self.eval_unary_exp(token)?);
723        }
724
725        Ok(if arr.len() == 1 {
726            arr[0].clone()
727        } else {
728            Val::Array(arr)
729        })
730    }
731
732    fn eval_range_exp(&mut self, token: Pair<'a>) -> ParserResult<Val> {
733        fn range(left: i64, right: i64) -> Vec<Val> {
734            if left < right {
735                (left..=right).collect::<Vec<i64>>()
736            } else {
737                let mut v = (right..=left).collect::<Vec<i64>>();
738                v.reverse();
739                v
740            }
741            .into_iter()
742            .map(Val::Int)
743            .collect::<Vec<Val>>()
744        }
745        check_rule!(token, Rule::range_exp);
746        let mut pairs = token.into_inner();
747        let token = pairs.next().unwrap();
748        let res = match token.as_rule() {
749            Rule::decimal_integer => {
750                let int_val = token.into_inner().next().unwrap();
751                let left = int_val.as_str().parse::<i64>().unwrap();
752                let token = pairs.next().unwrap();
753                let right = self.eval_array_literal_exp(token)?.cast_to_int()?;
754                Val::Array(range(left, right))
755            }
756            Rule::array_literal_exp => {
757                let res = self.eval_array_literal_exp(token)?;
758                if let Some(token) = pairs.next() {
759                    let left = res.cast_to_int()?;
760                    let right = self.eval_array_literal_exp(token)?.cast_to_int()?;
761                    Val::Array(range(left, right))
762                } else {
763                    res
764                }
765            }
766            _ => {
767                panic!("eval_range_exp not implemented: {:?}", token.as_rule());
768            }
769        };
770
771        Ok(res)
772    }
773
774    fn eval_format_impl(&mut self, format: Val, mut pairs: Pairs<'a>) -> ParserResult<Val> {
775        fn format_with_vec(fmt: &str, args: Vec<Val>) -> ParserResult<String> {
776            fn strange_special_case(fmt: &str, n: i64) -> String {
777                fn split_digits(n: i64) -> Vec<u8> {
778                    n.abs() // ignore sign for digit splitting
779                        .to_string()
780                        .chars()
781                        .filter_map(|c| c.to_digit(10).map(|opt| opt as u8))
782                        .collect()
783                }
784
785                //"{0:31sdfg,0100a0b00}" -f 578 evals to 310100a5b78
786                let mut digits = split_digits(n);
787                digits.reverse();
788                let mut fmt_vec = fmt.as_bytes().to_vec();
789                fmt_vec.reverse();
790
791                let mut i = 0;
792                for digit in digits {
793                    while i < fmt_vec.len() {
794                        if fmt_vec[i] != b'0' {
795                            i += 1
796                        } else {
797                            fmt_vec[i] = digit + b'0';
798                            break;
799                        }
800                    }
801                }
802                fmt_vec.reverse();
803                String::from_utf8(fmt_vec).unwrap_or_default()
804            }
805
806            let mut output = String::new();
807            let mut i = 0;
808
809            while i < fmt.len() {
810                if fmt[i..].starts_with('{') {
811                    if let Some(end) = fmt[i..].find('}') {
812                        let token = &fmt[i + 1..i + end];
813                        let formatted = if token.contains(':') {
814                            let mut parts = token.split(':');
815                            let index: usize = if let Some(p) = parts.next() {
816                                p.parse().unwrap_or(0)
817                            } else {
818                                0
819                            };
820
821                            let spec = parts.next();
822                            match args.get(index) {
823                                Some(val) => match spec {
824                                    Some(s) if s.starts_with('N') => {
825                                        let precision = s[1..].parse::<usize>().unwrap_or(2);
826                                        if let Ok(f) = val.cast_to_float() {
827                                            format!("{:.1$}", f, precision)
828                                        } else {
829                                            val.cast_to_string().to_string()
830                                        }
831                                    }
832                                    Some(s) => strange_special_case(s, val.cast_to_int()?),
833                                    None => val.cast_to_string().to_string(),
834                                },
835                                None => format!("{{{}}}", token), /* leave as-is if index out of
836                                                                   * bounds */
837                            }
838                        } else if token.contains(',') {
839                            let mut parts = token.split(',');
840                            let index: usize = parts.next().unwrap().parse().unwrap_or(0);
841                            let spec = parts.next();
842                            match args.get(index) {
843                                Some(val) => match spec {
844                                    Some(s) => {
845                                        let spaces = s.parse::<usize>().unwrap_or(0);
846                                        let spaces_str = " ".repeat(spaces);
847                                        format!("{spaces_str}{}", val.cast_to_string())
848                                    }
849                                    _ => val.cast_to_string().to_string(),
850                                },
851                                None => format!("{{{}}}", token), /* leave as-is if index out of
852                                                                   * bounds */
853                            }
854                        } else {
855                            let index: usize =
856                                Val::String(token.to_string().into()).cast_to_int()? as usize;
857                            match args.get(index) {
858                                Some(val) => val.cast_to_string().to_string(),
859                                None => format!("{{{}}}", token), /* leave as-is if index out of
860                                                                   * bounds */
861                            }
862                        };
863
864                        output.push_str(&formatted);
865                        i += end + 1;
866                    } else {
867                        output.push('{');
868                        i += 1;
869                    }
870                } else {
871                    output.push(fmt[i..].chars().next().unwrap());
872                    i += 1;
873                }
874            }
875
876            Ok(output)
877        }
878
879        Ok(if let Some(token) = pairs.next() {
880            let first_fmt = format.cast_to_string();
881
882            let second_fmt = self.eval_range_exp(token)?;
883            let res = self.eval_format_impl(second_fmt, pairs)?;
884            Val::String(format_with_vec(first_fmt.as_str(), res.cast_to_array())?.into())
885        } else {
886            format
887        })
888    }
889
890    fn eval_format_exp(&mut self, token: Pair<'a>) -> ParserResult<Val> {
891        check_rule!(token, Rule::format_exp);
892        let mut pairs = token.into_inner();
893        let format = self.eval_range_exp(pairs.next().unwrap())?;
894        self.eval_format_impl(format, pairs)
895    }
896
897    fn eval_mult(&mut self, token: Pair<'a>) -> ParserResult<Val> {
898        check_rule!(token, Rule::multiplicative_exp);
899        let mut pairs = token.into_inner();
900        let mut res = self.eval_format_exp(pairs.next().unwrap())?;
901        while let Some(op) = pairs.next() {
902            let Some(fun) = ArithmeticPred::get(op.as_str()) else {
903                panic!(
904                    "can't find arithmetic function for operator: {}",
905                    op.as_str()
906                )
907            };
908
909            let postfix = pairs.next().unwrap();
910            let right_op = self.eval_format_exp(postfix)?;
911            res = fun(res, right_op)?;
912        }
913
914        Ok(res)
915    }
916
917    fn eval_additive(&mut self, token: Pair<'a>) -> ParserResult<Val> {
918        check_rule!(token, Rule::additive_exp);
919
920        let mut pairs = token.into_inner();
921        let mut res = self.eval_mult(pairs.next().unwrap())?;
922        while let Some(op) = pairs.next() {
923            //check_rule!(op, Rule::additive_op); plus or minus
924            let Some(fun) = ArithmeticPred::get(op.as_str()) else {
925                panic!()
926            };
927
928            let mult = pairs.next().unwrap();
929            let right_op = self.eval_mult(mult)?;
930            res = fun(res, right_op)?;
931        }
932
933        Ok(res)
934    }
935
936    fn eval_split_special_case(
937        &mut self,
938        token: Pair<'a>,
939        input: Val,
940    ) -> ParserResult<Vec<String>> {
941        let mut res_vec = vec![];
942        let mut parts = String::new();
943        let input_str = input.cast_to_string();
944        let characters = input_str.chars();
945
946        // filtered_elements.join("")
947        for ch in characters {
948            self.variables
949                .set_ps_item(Val::String(ch.to_string().into()));
950
951            let b = match self.eval_script_block(
952                &ScriptBlock(token.as_str().to_string()),
953                &Val::String(ch.to_string().into()),
954            ) {
955                Err(er) => {
956                    self.errors.push(er);
957                    false
958                }
959                Ok(b) => b,
960            };
961
962            if b {
963                res_vec.push(parts);
964                parts = String::new();
965            } else {
966                parts.push(ch);
967            }
968        }
969        self.variables.reset_ps_item();
970        Ok(res_vec)
971    }
972    fn eval_comparison_exp(&mut self, token: Pair<'a>) -> ParserResult<Val> {
973        check_rule!(token, Rule::comparison_exp);
974        let mut pairs = token.into_inner();
975        let token = pairs.next().unwrap();
976
977        // we need to handle strange case. -split and -join can be invoke without
978        // previous expression, eg. "-join 'some'"
979        let mut res = if token.as_rule() == Rule::additive_exp {
980            self.eval_additive(token)?
981        } else {
982            Val::Null
983        };
984
985        while let Some(op) = pairs.next() {
986            let Some(fun) = StringPred::get(op.as_str()) else {
987                panic!("no operator: {}", op.as_str())
988            };
989
990            let token = pairs.next().unwrap();
991            let right_op = match token.as_rule() {
992                Rule::script_block_expression => {
993                    let mut pairs = token.into_inner();
994                    let token = pairs.next().unwrap();
995                    check_rule!(token, Rule::script_block_inner);
996
997                    let mut pairs = token.into_inner();
998                    let mut token = pairs.next().unwrap();
999                    if token.as_rule() == Rule::param_block {
1000                        //skip for now
1001                        token = pairs.next().unwrap();
1002                    }
1003                    check_rule!(token, Rule::script_block);
1004                    return Ok(Val::Array(
1005                        self.eval_split_special_case(token, res)?
1006                            .into_iter()
1007                            .map(|s| Val::String(s.into()))
1008                            .collect::<Vec<_>>(),
1009                    ));
1010                }
1011                Rule::additive_exp => self.eval_additive(token)?,
1012                _ => {
1013                    panic!("eval_comparison_exp not implemented: {:?}", token.as_rule());
1014                }
1015            };
1016            log::trace!("res: {:?}, right_op: {:?}", &res, &right_op);
1017            res = fun(res, right_op)?;
1018            log::trace!("res: {:?}", &res);
1019        }
1020
1021        Ok(res)
1022    }
1023
1024    fn eval_bitwise_exp(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1025        check_rule!(token, Rule::bitwise_exp);
1026
1027        let mut pairs = token.into_inner();
1028        let mut res = self.eval_comparison_exp(pairs.next().unwrap())?;
1029        while let Some(op) = pairs.next() {
1030            check_rule!(op, Rule::bitwise_operator);
1031            let Some(fun) = BitwisePred::get(op.as_str()) else {
1032                panic!()
1033            };
1034
1035            let mult = pairs.next().unwrap();
1036            let right_op = self.eval_comparison_exp(mult)?;
1037            res = fun(res, right_op);
1038        }
1039
1040        Ok(res)
1041    }
1042
1043    fn parse_long_command(&mut self, token: Pair<'a>) -> ParserResult<(String, Vec<CommandElem>)> {
1044        check_rule!(token, Rule::long_command);
1045
1046        let mut pairs = token.into_inner();
1047        let command_name_token = pairs.next().unwrap();
1048        let command_name = command_name_token.as_str();
1049
1050        let mut args = vec![];
1051        for command_element_token in pairs {
1052            let token_string = command_element_token.as_str().to_string();
1053            match command_element_token.as_rule() {
1054                Rule::command_argument => {
1055                    let arg_token = command_element_token.into_inner().next().unwrap();
1056                    let arg = match arg_token.as_rule() {
1057                        Rule::array_literal_exp => self.eval_array_literal_exp(arg_token)?,
1058                        Rule::parenthesized_expression => {
1059                            let token = arg_token.into_inner().next().unwrap();
1060                            self.eval_pipeline(token)?
1061                        }
1062                        _ => Val::String(arg_token.as_str().to_string().into()),
1063                    };
1064                    args.push(CommandElem::Argument(arg));
1065                }
1066                Rule::command_parameter => args.push(CommandElem::Parameter(token_string)),
1067                Rule::argument_list => args.push(CommandElem::ArgList(token_string)),
1068                Rule::redirection => { //todo: implement redirection
1069                }
1070                Rule::stop_parsing => { //todo: stop parsing
1071                }
1072                Rule::script_block_expression => args.push(CommandElem::Argument(
1073                    self.parse_script_block_expression(command_element_token)?,
1074                )),
1075                _ => panic!(
1076                    "eval_command not implemented: {:?}",
1077                    command_element_token.as_rule()
1078                ),
1079            }
1080        }
1081        Ok((command_name.to_string(), args))
1082    }
1083
1084    fn parse_script_block_command(
1085        &mut self,
1086        token: Pair<'a>,
1087    ) -> ParserResult<(String, Vec<CommandElem>)> {
1088        check_rule!(token, Rule::script_block_command);
1089
1090        let mut pairs = token.into_inner();
1091        let command_name_token = pairs.next().unwrap();
1092        let command_name = command_name_token.as_str();
1093        let command_element_token = pairs.next().unwrap();
1094
1095        check_rule!(command_element_token, Rule::script_block_expression);
1096        let script_block = self.parse_script_block_expression(command_element_token)?;
1097        Ok((
1098            command_name.to_string(),
1099            vec![CommandElem::Argument(script_block)],
1100        ))
1101    }
1102
1103    fn eval_command(&mut self, token: Pair<'a>, input: Option<Val>) -> ParserResult<Val> {
1104        check_rule!(token, Rule::command);
1105
1106        let mut pairs = token.into_inner();
1107        //unfortunately I can't make long_command silent
1108
1109        let mut args = if let Some(v) = input {
1110            vec![CommandElem::Argument(v)]
1111        } else {
1112            Vec::new()
1113        };
1114
1115        let command = pairs.next().unwrap();
1116        let (command_name, mut command_args) = match command.as_rule() {
1117            Rule::script_block_command => self.parse_script_block_command(command)?,
1118            Rule::foreach_command => Err(ParserError::NotImplemented("foreach_command".into()))?,
1119            Rule::long_command => self.parse_long_command(command)?,
1120            Rule::invocation_command => {
1121                Err(ParserError::NotImplemented("invocation_command".into()))?
1122            }
1123            _ => panic!("eval_command not implemented: {:?}", command.as_rule()),
1124        };
1125        args.append(&mut command_args);
1126
1127        let CommandOutput {
1128            val,
1129            deobfuscated,
1130            stream,
1131        } = Command::execute(self, command_name.as_str(), args)?;
1132
1133        if let Some(msg) = deobfuscated {
1134            self.deobfuscated_statements.push(msg);
1135        }
1136
1137        if let Some(msg) = stream {
1138            self.output.push(msg);
1139        }
1140
1141        Ok(val.unwrap_or_default())
1142    }
1143
1144    fn eval_redirected_expression(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1145        check_rule!(token, Rule::redirected_expression);
1146
1147        let expression_token = token.into_inner().next().unwrap();
1148        //todo: handle redirections
1149
1150        self.eval_expression(expression_token)
1151    }
1152
1153    fn eval_expression(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1154        check_rule!(token, Rule::expression);
1155        let token_string = token.as_str().trim().to_string();
1156
1157        let mut pairs = token.into_inner();
1158        let mut res = self.eval_bitwise_exp(pairs.next().unwrap())?;
1159        while let Some(op) = pairs.next() {
1160            check_rule!(op, Rule::logical_operator);
1161            let Some(fun) = LogicalPred::get(op.as_str()) else {
1162                panic!()
1163            };
1164
1165            let mult = pairs.next().unwrap();
1166            let right_op = self.eval_bitwise_exp(mult)?;
1167            res = Val::Bool(fun(res, right_op));
1168        }
1169        self.tokens
1170            .push(Token::Expression(token_string, res.clone().into()));
1171
1172        Ok(res)
1173    }
1174
1175    fn eval_pipeline_tail(&mut self, token: Pair<'a>, input: Val) -> ParserResult<Val> {
1176        check_rule!(token, Rule::pipeline_tail);
1177        let mut arg = input;
1178        let mut pairs = token.into_inner();
1179
1180        while let Some(token) = pairs.next() {
1181            arg = self.eval_command(token, Some(arg))?;
1182        }
1183
1184        Ok(arg)
1185    }
1186
1187    fn eval_pipeline_with_tail(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1188        check_rule!(token, Rule::pipeline_with_tail);
1189        let mut pairs = token.into_inner();
1190        let token = pairs.next().unwrap();
1191
1192        let result: Val = match token.as_rule() {
1193            Rule::redirected_expression => self.eval_redirected_expression(token)?,
1194            Rule::command => self.eval_command(token, None)?,
1195            _ => {
1196                panic!("eval_pipeline not implemented: {:?}", token.as_rule());
1197            }
1198        };
1199
1200        if let Some(token) = pairs.next() {
1201            match token.as_rule() {
1202                Rule::pipeline_tail => Ok(self.eval_pipeline_tail(token, result)?),
1203                _ => {
1204                    panic!("eval_pipeline not implemented: {:?}", token.as_rule());
1205                }
1206            }
1207        } else {
1208            Ok(result)
1209        }
1210    }
1211
1212    fn eval_pipeline(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1213        check_rule!(token, Rule::pipeline);
1214        let mut pairs = token.into_inner();
1215        let token = pairs.next().unwrap();
1216
1217        match token.as_rule() {
1218            Rule::assignment_exp => return self.eval_assigment_exp(token),
1219            Rule::pipeline_with_tail => return self.eval_pipeline_with_tail(token),
1220            _ => panic!("not possible: {:?}", token.as_rule()),
1221        }
1222    }
1223
1224    fn safe_eval_pipeline(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1225        let res = self.eval_pipeline(token);
1226
1227        let v = match res {
1228            Ok(val) => val,
1229            Err(err) => {
1230                self.errors.push(err);
1231                Val::Null
1232            }
1233        };
1234
1235        Ok(v)
1236    }
1237
1238    fn eval_cast_expression(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1239        check_rule!(token, Rule::cast_expression);
1240
1241        let mut pairs = token.into_inner();
1242        let type_token = pairs.next().unwrap();
1243        let val_type = self.eval_type_literal(type_token)?;
1244
1245        let token = pairs.next().unwrap();
1246        let mut res = match token.as_rule() {
1247            Rule::parenthesized_expression => {
1248                let token = token.into_inner().next().unwrap();
1249                self.safe_eval_pipeline(token)?
1250            }
1251            Rule::range_exp => self.eval_range_exp(token)?,
1252            Rule::unary_exp => self.eval_unary_exp(token)?,
1253            _ => {
1254                panic!(
1255                    "eval_cast_expression not implemented: {:?}",
1256                    token.as_rule()
1257                );
1258            }
1259        };
1260
1261        Ok(res.cast(val_type)?)
1262    }
1263
1264    fn eval_assigment_exp(&mut self, token: Pair<'a>) -> ParserResult<Val> {
1265        check_rule!(token, Rule::assignment_exp);
1266
1267        let mut pairs = token.into_inner();
1268        let variable_token = pairs.next().unwrap();
1269        let var_name = Self::parse_variable(variable_token)?;
1270        let var = self.variables.get(&var_name).unwrap_or_default();
1271
1272        let assignement_op = pairs.next().unwrap();
1273
1274        //get operand
1275        let op = assignement_op.into_inner().next().unwrap();
1276        let pred = ArithmeticPred::get(op.as_str());
1277
1278        let right_token = pairs.next().unwrap();
1279        let right_op = self.eval_pipeline(right_token.clone())?;
1280
1281        let Some(pred) = pred else { panic!() };
1282        let op_result = pred(var, right_op)?;
1283        self.variables.set(&var_name, op_result.clone())?;
1284
1285        //we want save each assignment statement
1286        self.deobfuscated_statements
1287            .push(format!("{} = {}", var_name, op_result.cast_to_script()));
1288        Ok(op_result)
1289    }
1290}
1291
1292#[cfg(test)]
1293mod tests {
1294    use pest::Parser;
1295
1296    use super::*;
1297
1298    #[test]
1299    fn comment_and_semicolon() {
1300        let input = r#"
1301# This is a single line comment
1302$a = 1; $b = 2; Write-Output $a
1303
1304Write-Output "Hello"  # Another comment
1305
1306<#
1307    This is a
1308    multi-line block comment
1309#>
1310"#;
1311
1312        let _ = PowerShellSession::parse(Rule::program, input).unwrap();
1313    }
1314
1315    #[test]
1316    fn while_loop() {
1317        let input = r#"
1318while ($true) {
1319    if ($someCondition) {
1320        break
1321    }
1322    # other code
1323}
1324"#;
1325
1326        let _ = PowerShellSession::parse(Rule::program, input).unwrap();
1327    }
1328
1329    #[test]
1330    fn foreach_loop() {
1331        let input = r#"
1332foreach ($n in $numbers) {
1333    Write-Output $n
1334}
1335"#;
1336
1337        let _ = PowerShellSession::parse(Rule::program, input).unwrap();
1338    }
1339
1340    #[test]
1341    fn for_loop() {
1342        let input = r#"
1343# Comma separated assignment expressions enclosed in parentheses.
1344for (($i = 0), ($j = 0); $i -lt 10; $i++)
1345{
1346    "`$i:$i"
1347    "`$j:$j"
1348}
1349"#;
1350
1351        let _ = PowerShellSession::parse(Rule::program, input).unwrap();
1352    }
1353
1354    #[test]
1355    fn switch() {
1356        let input = r#"
1357switch ($var) {
1358    "a" { Write-Output "A" }
1359    1 { Write-Output "One" }
1360    default { Write-Output "Other" }
1361}
1362"#;
1363
1364        let _ = PowerShellSession::parse(Rule::program, input).unwrap();
1365    }
1366
1367    #[test]
1368    fn functions() {
1369        let input = r#"
1370function Get-Square {
1371    param($x)
1372    return $x * $x
1373}
1374
1375function Say-Hello {
1376    Write-Output "Hello"
1377}
1378"#;
1379
1380        let _ = PowerShellSession::parse(Rule::program, input).unwrap();
1381    }
1382
1383    #[test]
1384    fn if_expression() {
1385        let input = r#"
1386$x="hello"
1387        Write-Host $x
1388        $y = 42
1389        Start-Process "notepad.exe"
1390
1391        $x = 42
1392if ($x -eq 1) {
1393    Write-Output "One"
1394} elseif ($x -eq 2) {
1395    Write-Output "Two"
1396} else {
1397    Write-Output "Other"
1398}
1399"#;
1400
1401        let _ = PowerShellSession::parse(Rule::program, input).unwrap();
1402    }
1403
1404    #[test]
1405    fn command() {
1406        let input = r#"
1407Get-Process | Where-Object { $_.CPU -gt 100 }
1408"#;
1409
1410        let _ = PowerShellSession::parse(Rule::program, input).unwrap();
1411    }
1412
1413    #[test]
1414    fn range() {
1415        let input = r#"
1416$numbers = 1..5
1417"#;
1418
1419        let _ = PowerShellSession::parse(Rule::program, input).unwrap();
1420    }
1421
1422    #[test]
1423    fn literals() {
1424        let input = r#"
1425$hex = 0xFF
1426
1427$name = "Alice"
1428$msg = "Hello, $name. Today is $day."
1429$escaped = "She said: `"Hi`""
1430$literal = 'Hello, $name'
1431"#;
1432
1433        let _ = PowerShellSession::parse(Rule::program, input).unwrap();
1434    }
1435
1436    #[test]
1437    fn floats() {
1438        let input = r#"
1439    $pi = 3.1415
1440$half = .5
1441"#;
1442
1443        let _ = PowerShellSession::parse(Rule::program, input).unwrap();
1444    }
1445
1446    #[test]
1447    fn arrays() {
1448        let input = r#"
1449$a = 1, 2, 3
1450$b = @("one", "two", "three")
1451$c = @(1, 2, @(3, 4))
1452"#;
1453
1454        let _ = PowerShellSession::parse(Rule::program, input).unwrap();
1455    }
1456
1457    #[test]
1458    fn static_method_call() {
1459        let input = r#"
1460[Threading.Thread]::Sleep(399)
1461"#;
1462
1463        let _ = PowerShellSession::parse(Rule::program, input).unwrap();
1464    }
1465
1466    #[test]
1467    fn neg_pipeline() {
1468        let input = r#"
1469-not $input | Where-Object { $_ -gt 5 }
1470"#;
1471
1472        let _ = PowerShellSession::parse(Rule::program, input).unwrap();
1473    }
1474
1475    #[test]
1476    fn amsi_fail() {
1477        let input = r#"
1478#Matt Graebers second Reflection method 
1479$VMRviwsbtehQfPtxbt=$null;
1480$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))"
1481
1482"#;
1483
1484        let _ = PowerShellSession::parse(Rule::program, input).unwrap();
1485    }
1486}