Windows Serviceのデバッグ
概略
Windows Serviceのデバッグを行いたい場合のためのメモ
自己責任で(VM推奨)
デバッグした後は元の環境に戻す(重要)
環境
手法 その1
サービスの初期状態からデバッグできるようにする
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Optionにプログラム名のレジストリキーを作成する.
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution
String Value
Value name : Debugger
Value data : <debugger path> -server npipe:pipe=<Session Name>
今回の場合は以下のようにした.
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution
String Value
Value name : Debugger
Value data : C:\Debuggers\x86\ntsd.exe -server npipe:pipe=hoge
セッション分離
Windows Vista以降はセッションが分離されているため上記の方法をとる.
それより前のOSだと直接WinDbgを指定してやれば良いらしい(未確認).
Let's Debug!
WinDbg → Connect to Remote Session(Ctrl+R)
npipe:server=localhost,pipe=hoge
タイムアウト時間の調整
サービスのタイムアウト時間を伸ばさないとすぐ終了してしまう. デフォルトで30000ミリ秒(30秒).
C:\Windows\System32>sc start MySrv
[SC] StartService FAILED 1053:
The service did not respond to the start or control request in a timely fashion.
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Controlでデフォルトのタイムアウト時間を伸ばす. → 再起動
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control
DWORD
Value Name : ServicesPipeTimeout
Value data : 86400000(Decimal)
※ 86400000(Decimal) = 24hours
※ 全てのサービスに影響するためデバッグ後は修正する
手法 その2(svchostと依存関係がある場合)
svchost.exeと依存関係がある場合, 孤立させる必要がある.
今回はBITS(Background Intelligent Transfer Service)を対象にする.
C:\Windows\System32>sc qc bits
[SC] QueryServiceConfig SUCCESS
SERVICE_NAME: bits
TYPE : 20 WIN32_SHARE_PROCESS
START_TYPE : 2 AUTO_START (DELAYED)
ERROR_CONTROL : 1 NORMAL
BINARY_PATH_NAME : C:\Windows\System32\svchost.exe -k netsvcs
LOAD_ORDER_GROUP :
TAG : 0
DISPLAY_NAME : Background Intelligent Transfer Service
DEPENDENCIES : RpcSs
: EventSystem
SERVICE_START_NAME : LocalSystem
見る箇所はBINARY_PATH_NAMEのグループ名(netsvcs). ちなみにsvchost -k (group).
新しいグループ(TempGrp)を作成する.
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsNT\CurrentVersion\SvcHost
REG_MULTI_SZ
Value Name : TempGrp
Value data : 孤立させたいサービスのValue data
※ 作成したグループのValue dataにnetsvcsのValue dataを指定する.
元々のグループのsub keyを作成したグループにコピーする.
今回の場合はnetsvcsなのでAuthenticationCapabilities, CoInitializeSecurityParamを新しいグループにコピーすれば良い.
サービスのパスを修正する.
C:\Windows\System32>sc config BITS binPath= "C:\Windows\system32\svchost.exe -k TempGrp"
[SC] ChangeServiceConfig SUCCESS
※ 細かい所だけどbinPathはクオーテーションで囲む, binPath=の後のスペースは必要. ハマりやすい所なので注意.
必要に応じてサービスの再起動を行う. あとは手法 その1と同じ.
手法 その3(非推奨)
MSDNによると非推奨.
svchostを複製する.
%SystemRoot%\System32にsvchost.exeをコピーしてsvchost2.exeを作成する.
C:\Windows\System32>sc config BITS binPath= "C:\Windows\System32\svchost2.exe -k netsvcs"
[SC] ChangeServiceConfig SUCCESS
必要に応じてサービスの再起動を行う. あとは手法 その1と同じ.
所感
個人的には手法1と3(適当)