/
ps1str.py
72 lines (62 loc) · 1.9 KB
/
ps1str.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import re
from refinery.lib.decorators import unicoded
from refinery.units import Unit
class ps1str(Unit):
"""
Escapes and unescapes PowerShell strings.
"""
UNESCAPE = {
'`0': '\0',
'`a': '\a',
'`b': '\b',
'`f': '\f',
'`n': '\n',
'`r': '\r',
'`t': '\t',
'`v': '\v',
'``': '`',
"`'": '\'',
'`"': '\"',
}
ESCAPE = {
'`' : '``',
'$' : '`$',
'\0': '`0',
'\a': '`a',
'\b': '`b',
'\f': '`f',
'\n': '`n',
'\r': '`r',
'\t': '`t',
'\v': '`v',
'\'': "`'",
'\"': '""',
}
def __init__(self): pass
@unicoded
def process(self, data):
match = re.fullmatch(R'''@(['"])\s*?[\r\n](.*?)[\r\n]\1@''', data, flags=re.DOTALL)
if match:
return match.group(2)
if data[0] not in ''''"''' or data[-1] != data[0]:
raise ValueError(
'No quotes found at beginning of input. To escape a PowerShell string, the '
'quotes must be included because quote escaping depends on whether a single '
'or double quote was used.')
quote, data = data[0], data[1:-1]
def unescape(match):
string = match[0]
return self.UNESCAPE.get(string, string[1:])
if quote == '"':
if re.search(R'(?<!`)\$(?=[\w\(\{\$\?\^:])', data):
self.log_warn('Loss of information: double quoted string contains variable substitutions.')
data = re.sub('`.', unescape, data)
return data.replace(quote + quote, quote)
@unicoded
def reverse(self, data):
def escaper(match):
char = match[0]
return ps1str.ESCAPE.get(char, char)
return '"{}"'.format(re.sub(R'''[\x00\x07-\x0D`$'"]''', escaper, data))