Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
This (and the previous post) stem from me stumbling onto this page:
https://stackoverflow.com/questions/17229866/powershell-hex-to-string-conversion/19151495
Last time, we looked at hex-decoding a string. In the above, the original poster had file of space-delimited lines, each with three fields: the username, the user’s ___domain, and the hex-encoded password. The requested solution was to only hex-decode only the third field.
Using regular expressions, targeting the last field is easy:
$line –match “\S+$”
Then, we beat on $Matches
. Now, the problem requests that the last field be replaced with the hex-decoded string, so we can do something like this:
$hex = $line –replace “.*\s”
$userData = $line –replace '”\S+$”
We can then hex-decode $hex
with the magic from yesterday and concatenate with $userData
. But wait – we can interpolate the matched string into the replacement pattern:
$line –replace “(\S+)$”, ‘*$1*’
This highlights the last field by bracketing it with asterisks. Can we toss it through our function?
$line –replace “(\S+)$”, Convert-HexToString(‘$1’)
$line –replace “(\S+)$”, “$(Convert-HexToString(`$1))”
Neither work. In fact, I can’t find a way to get it to work with the plain -replace operator
. Now, -replace
is just a PSH language element to expose the [RegEx]
class. We can do this with the class, but it’s ugly. First, we define the regular expression:
[RegEx]$regEx = ‘(\S+)$’;
Next, we need to define what we want to do with the matched string. In this case, we re-implement the Convert-HexToString function.
$delegateScriptBlock = {
param ($match);
-join ( $match.Groups[1].Value -split '(..)' | ? { $_; } | % { [Char]( [Convert]::ToInt16($_, 16) ); } );
};
Finally, we do the actual heavy lifting:
Get-Content file.txt | % { $regEx.Replace($_, $delegateScriptBlock); }
Now, in the $delegateScriptBlock, we see this snippet:
$match.Groups[1].Value
What’s happening is the RegEx is populating a variable that is similar to $Matches
, then passing it into the scriptblock as a parameter. Now, debugging a scriptblock is as fun as it usually is. We can’t save it to a $global:scope variable, nor can we Export-Clixml –path someFile. In this case:
$debugScriptBlock = { param ($parameter); $parameter; }
$myMatches = $regEx.Match($line, $debugScriptBlock);;
By running this at the prompt, having debugScriptBlock
simply return the parameter, and saving that variable, we can look at what it provides the scriptblock. Here, we can examine the $match
we’re accepting as the parameter.
Finally, why do this instead using $userData
and $hex
? For me, there’s a certain appeal in implementing Perl’s search-and-evaluate capability, even if it’s pretty involved.