服務調試

0x服務簡介

我們在進行一些程序分析時會發現有些程序會調用服務控制管理器,用服務的形式運行了一段代碼,這就是常見的創建服務程序。
它的核心原理就是首先在SCM(Service Control Manager)下創建一個子進程,讓這個子進程執行我們第三方程序提供的代碼。
其中涉及的API有三個:StartService()StartServiceCtrlDispatcher()SetServiceStatus()
1)服務控制器用StartService()函數,是用SCM創建一個SCM下的子進程,並且執行這個子進程EP
2)服務進程調用StartServiceCtrlDispatcher()函數用於註冊服務進程函數,使用這個函數前必須調用服務控制器API接口返回的控制句柄才能操作
3)服務進程調用SetServiceStatus()函數,雖然已經創建了服務進程,但尚未以服務形式運行。當前狀態仍未SERVICE_START_PENDING。在主函數SvcMain被SCM調用後,通過SvcMain()內部的SetServiceStatus()函數調用過後,這樣才能以服務進程形式運行。

0x1 強制EIP調試

對於DLL文件形式的Windows服務,服務主函數(默認爲ServiceMain)爲導出函數,SCM會調用運行導出函數,所以不需要另外調用StartServiceCtrlDispatcher
在這裏插入圖片描述
反彙編窗口跟隨,查看是否是可執行的彙編代碼
在這裏插入圖片描述
設置新EIP,這樣除了EIP外,其他寄存器都保持原值不變
在這裏插入圖片描述
然後開始調試ScvMain即可。但是這種方式由於不是SCM正常啓動的,所以在調用相關部分API可能發生異常。爲了避免這種異常可以在調試器中強制設置EIP跳過對相關API調用。也可以設置內存訪問異常忽略,如下圖。但是這種設置仍然有可能崩潰,畢竟是強制跳轉過來的。
在這裏插入圖片描述

0x2 正常附加調試

啓動服務後,SCM會在一定時間內等待服務狀態改變乘STATUS_RUNNING。若規定時間內服務狀態未改變(默認30s),SCM就會引發ERROR_SERVICE_REQUEST_TIMEOUT錯誤,然後中止相關進程。
因爲正常調試的情況下,目標服務進程是由SCM服務創建出來的子服務進程。我們需要先附加到SCM進程中,然後將要調試目標程序代碼的EP處改成死循環,讓SCM一直等待服務子進程執行,這時候我們再重新更改附加對象到目標服務進程中,恢復原來的EP代碼,讓目標服務可以正常跑下去。不這麼做,一下子目標服務就可能跑完了,還沒等附加,子進程服務就結束了。
以下是步驟:
1)首先安裝示例程序,切換到示例程序下執行安裝命令,注意這裏是DebugMe1.exe中的主函數有接收install字符串處理,當接收到這個字符串後調用InstallService()函數才能進行安裝的。如果要調試的源碼中沒有提供這個安裝方法,就需要自己寫程序安裝驅動或用強制EIP了。
在這裏插入圖片描述
打開服務管理查看是否安裝服務成功
在這裏插入圖片描述
在這裏插入圖片描述
2)增加服務啓動超時時間

啓動註冊表編輯器regedit.exe,創建ServicesPipeTimeout註冊表項。ServicesPipeTimeout會對所有服務都產生影響。[HKEY_LOCAL_MACHINE\System\CurrentControlSet\Controll] ServicesPipeTimeout新建一個DWORD值
在這裏插入圖片描述
在這裏插入圖片描述
3)覆蓋寫入循環
首先拿PE解析工具找到入口點在文件中的偏移。
在這裏插入圖片描述
用16進制編輯器修改此處機器碼爲0xEB 0xFE
在這裏插入圖片描述
在這裏插入圖片描述
4)啓動服務
在這裏插入圖片描述
啓動成功後,服務進程也就運行起來了(DebugMe1.exe)
使用Process Explorer查看SvcTest服務進程,服務被啓動
在這裏插入圖片描述
注意:這裏會彈出沒有響應啓動或控制請求,一定要重啓這就是沒重啓後導致的錯誤
在這裏插入圖片描述
附加到對應的服務上後,該程序就是
在這裏插入圖片描述
修改回原值
在這裏插入圖片描述
接着在要調試的地方下斷點就可以了,因爲是SCM下子進程DebugMe1.exe創建的,所以ScvMain會被SCM調用。
在這裏插入圖片描述
然後就可以重新設置EIP爲目標代碼起始位置了,普通調試是在SCM下的子進程創建的,所以服務控制器會調用ScvMain中的代碼。
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章