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と書くこともできる。