PowerShellで正規表現フィルタを書いてみる
Windowsにおいて標準で利用できるスクリプト環境としては古くからWindows Scripting Host(WSH)があるが、Windows 7以降ではこれに加えPowerShellと呼ばれるシェルが利用できる。 また、WSHでJScriptまたはVBScriptのもとでCOMコンポーネントを扱えたように、PowerShellでは独自のシェル構文のもとで.NET Frameworkライブラリを扱うことができ、シェルでありながら汎用プログラミング環境としても使えるものになっている。 そこで、ここではPowerShellスクリプトで正規表現フィルタを書き、コマンドプロンプトからスクリプトとして実行してみる。
環境
Windows 8.1 Pro 64 bit版、PowerShell 4.0
>systeminfo OS 名: Microsoft Windows 8.1 Pro OS バージョン: 6.3.9600 N/A ビルド 9600 OS ビルドの種類: Multiprocessor Free システムの種類: x64-based PC プロセッサ: 1 プロセッサインストール済みです。 [01]: Intel64 Family 6 Model 69 Stepping 1 GenuineIntel ~1596 Mhz >powershell -c "$PSVERSIONTABLE" Name Value ---- ----- PSVersion 4.0 WSManStackVersion 3.0 SerializationVersion 1.1.0.1 CLRVersion 4.0.30319.34014 BuildVersion 6.3.9600.17090 PSCompatibleVersions {1.0, 2.0, 3.0, 4.0} PSRemotingProtocolVersion 2.2
16進バイト列をC文字列に変換するPowerShellスクリプト
「Windowsで電卓を起動するアセンブリコードを書いてみる」では、アセンブル結果としてdumpbin /rawdata
で表示されたバイト列をC文字列に変換した。
この処理をPowerShellスクリプトで書くと、次のようになる。
# getsc.ps1 -join ( $input | Select-String " ([0-9A-F]{2})(?= )" -CaseSensitive -AllMatches | ForEach-Object { $_.Matches } | ForEach-Object { "\x" + $_.Groups[1] } )
このスクリプトは指定した正規表現にマッチした1番目のグループをすべて取り出し、C文字列としてエスケープした上で連結するものである。
なお、ForEach-Object
はforeach
あるいは%
と書くこともできる。
このことはPowerShell上で次のようにして確認できる。
PS C:\> Get-Alias | Where-Object { $_.Definition -eq "ForEach-Object" } CommandType Name ModuleName ----------- ---- ---------- Alias % -> ForEach-Object Alias foreach -> ForEach-Object
上のエントリで書いたアセンブリコードから生成した実行ファイルに対しdumpbin /rawdata
でアセンブル結果を表示し、その結果を上のスクリプトで処理してみる。
>ml execcalc.asm /link /subsystem:console Microsoft (R) Macro Assembler Version 12.00.31101.0 Copyright (C) Microsoft Corporation. All rights reserved. Assembling: execcalc.asm Microsoft (R) Incremental Linker Version 12.00.31101.0 Copyright (C) Microsoft Corporation. All rights reserved. /OUT:execcalc.exe execcalc.obj /subsystem:console >dumpbin /rawdata execcalc.exe Microsoft (R) COFF/PE Dumper Version 12.00.31101.0 Copyright (C) Microsoft Corporation. All rights reserved. Dump of file execcalc.exe File Type: EXECUTABLE IMAGE RAW DATA #1 00401000: 33 C0 50 68 63 61 6C 63 8B C4 6A 01 50 B8 27 29 3ÀPhcalc.Äj.P¸') 00401010: 80 75 FF D0 50 B8 64 7F 7E 75 FF D0 .uÿÐP¸d.~uÿÐ Summary 1000 .text >dumpbin /rawdata execcalc.exe | powershell -ex remotesigned -f getsc.ps1 \x33\xC0\x50\x68\x63\x61\x6C\x63\x8B\xC4\x6A\x01\x50\xB8\x27\x29\x80\x75\xFF\xD0\x50\xB8\x64\x7F\x7E\x75\xFF\xD0
PowerShellスクリプトの実行は、powershell
コマンドに-f
オプションでファイルパスを指定することにより行うことができる。
ただし、デフォルト状態では一切のスクリプト実行が制限されているため、ここでは-ex
オプションによりポリシーをremotesigned
、すなわちローカルスクリプトについてはデジタル署名の有無によらず実行できるよう変更している。
なお、-ex
は-executionpolicy
のエイリアスであり、-ep
と書くこともできる。