生活随笔
收集整理的這篇文章主要介紹了
1.调试对象
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
將一個程序拖拽進OD中,這種方式是通過 CreateProcess() 建立聯系的。
程序正在運行中通過OD附加程序,這種方式是通過 DebugActiveProcess() 建立聯系的。
DebugActiveProcess執行流程
<1> kernel32! DbaUiConnectToDbg()
ntdll! DbgUiConnectToDbg()ntdll! ZwCreateDebugObject()ntoskrnl! NtCreateDebugObject()
<2> kerel32! DbgUiDebugActiveProcess(被調試進程句柄)
ntdll! DbgUiDebugActiveProcess(被調試進程句柄)ntdll! DebugActiveProcess(被調試進程句柄調試器進程TEB+0xF24)ntdll! DebugActiveProcess(HANDLE ProcessHandle, HANDLE DebugObjectHandle)
打開ntdll
這里開始提供操作碼開始進入0環,ZwCreateDebugObject就是進入0環創建一個調試對象。
NTSTATUS
NTAPI
ZwCreateDebugObject(_Out_ PHANDLE DebugHandle
,_In_ ACCESS_MASK DesiredAccess
,_In_ POBJECT_ATTRIBUTES ObjectAttributes
,_In_ ULONG Flags
);typedef struct _DEBUG_OBJECT
{KEVENT EventsPresent
;FAST_MUTEX Mutex
;LIST_ENTRY EventList
;union{ULONG Flags
;struct{UCHAR DebuggerInactive
:1;UCHAR KillProcessOnExit
:1;};};
} DEBUG_OBJECT
, *PDEBUG_OBJECT
;
ntdll是3環的只要是3環的一定不會存內核對象的地址而是一個句柄。
ZwCreateDebugObject 第一個參數是OUT類型返回一個句柄,返回到EAX了,這時EAX的位置是TEB+0xF24的位置。
遍歷進程中所有線程的TEB+0xF24的位置,如果這個位置有值那你的程序一定是被調試了。
打開ntdll
開始進入0環了
打開ntoskrnl
ObReferenceObjectByHandle 執行完后標黃那Handle的值變成了 “被調試進程”的PEPROCESS結構的地址。
ObReferenceObjectByHandle執行完后Handle那個參數將變成 “調試對象地址”
DbgkpSetProcessDebugObject(IN PEPROCESS Process
, IN PDEBUG_OBJECT DebugObject
,IN NTSTATUS MsgStatus
, IN PETHREAD LastThread
)
DebugActiveProcess就是像上圖那樣,將進程與調試器關鏈到一起。
防守方:
DebugPort清0(創建完調試對象后要占用被調試的DebugPort,DebugPort被清0就不能與調試器建立聯系了)遍歷當前進程所有線程_TEB+0xF24 有值就是被調試了HOOK NtCreateDebugObject() 不讓它創建調試對象
攻擊方:
NtCreateDebugObject 函數就是分配一塊內存給_DEBUG_OBJECT,然后給它的成員賦值。我們可以重寫它代碼對著IDA抄就完事了。要跟被調試進程建立聯系需要DebugPort,偏移是0xbc那我們將它改了EPROCESS的結構那么大選一個沒用的地方,把用到0xbc的都改為你選的地方的偏移。或者說來個更狠的,重寫DebugActiveProcess,偏移什么的都是自己說的算。
總結
以上是生活随笔為你收集整理的1.调试对象的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。