能力值:
( LV2,RANK:10 )
|
-
-
2 楼
bool KillDebugHandle()
{
ULONG* pHandleInfor = NULL;
NTSTATUS ntStatus;
ZWQUERYSYSTEMINFORMATION ZwQuerySystemInformation = NULL;
ULONG ulSize = 0x4000;
HMODULE hHanlde = GetModuleHandle(L"ntdll.dll");
if(NULL == hHanlde) return false;
ZwQuerySystemInformation = (ZWQUERYSYSTEMINFORMATION)GetProcAddress(hHanlde, "ZwQuerySystemInformation");
if(NULL == ZwQuerySystemInformation) return false;
do
{
pHandleInfor = (ULONG*)malloc(ulSize);
if(NULL == pHandleInfor) return false;
ntStatus = ZwQuerySystemInformation(16,pHandleInfor,ulSize,NULL);
if(!NT_SUCCESS(ntStatus))
{
free(pHandleInfor);
ulSize = ulSize * 2;
if(ulSize > 0x4000000) return false;
}
}while(!NT_SUCCESS(ntStatus));
PSYSTEM_HANDLE_INFORMATION_EX Handles = (PSYSTEM_HANDLE_INFORMATION_EX)pHandleInfor;
if(NULL == Handles) return false;
for(ULONG i = 0; i < Handles->NumberOfHandles; i++)
{
if(Handles->Information[i].ObjectTypeNumber == 0x8) // Handle Type "DebugObject"
{
// Handles->Information[i].ProcessId == 调试器进程ID
break;
}
}
free(Handles);
return true;
}
代码是转载的
也就是枚举系统句柄,遍历,有DebugHandle的进程为调试器
|
能力值:
( LV4,RANK:40 )
|
-
-
3 楼
但是又如何知道哪个调试器正在调试我们的进程呢
|
能力值:
( LV9,RANK:380 )
|
-
-
4 楼
呵呵,这个问题学问大了。。 
|
能力值:
( LV4,RANK:40 )
|
-
-
5 楼
我知道在RING0下可以通过我们进程的EPROCESS的DebugPort的KEVENT EventsPresent;
联系到调试器进程,但是RING3如何做呢?RING3下不通过驱动或者系统漏洞可以读RING0内存吗?KEVENT类型怎么转换为RING3下的HANDLE(Event)类型等?
|
能力值:
(RANK:50 )
|
-
-
6 楼
PEB里有木有相关信息……
|
能力值:
( LV4,RANK:40 )
|
-
-
7 楼
没有样........
|
能力值:
(RANK:50 )
|
-
-
8 楼
RING3下能实现读内核内存的话算是比较高价值的漏洞了,没那么容易得到……
推荐看看张银奎的《软件调试》吧,里面比较详细地介绍了Windows的调试模型
|
能力值:
( LV4,RANK:40 )
|
-
-
9 楼
那么还是没有解决了?
|
能力值:
( LV5,RANK:70 )
|
-
-
10 楼
套个SOD 在R3下你就各种生活不能自理了....
|
能力值:
( LV2,RANK:10 )
|
-
-
11 楼
使用QuerySystemInformation遍历所有句柄,找到PID和句柄都是自己的_SYSTEM_HANDLE_TABLE_ENTRY_INFO,从而得到自己的object,在遍历对比所有含有自己object的项,列出pid不是自己的项,排除掉系统和杀毒软件,剩下的就是调试自己的的进程
|
能力值:
( LV5,RANK:70 )
|
-
-
12 楼
呼叫个驱动改个object_type是很容易的.特别是objectname.
|
能力值:
( LV2,RANK:10 )
|
-
-
13 楼
他说的是3环啊
|
能力值:
( LV4,RANK:40 )
|
-
-
14 楼
小弟出道不久 涉世未深 看得不是很懂 不是很了解 要是有示例代码 就更好了
|
能力值:
( LV5,RANK:70 )
|
-
-
15 楼
关键是人家调试的不只会用三环的东西啊....然后检查调试器只有找窗口 找OBJ,发现DEBUGOBJ 或者调试窗口直接把自己结束了.
|
能力值:
( LV2,RANK:10 )
|
-
-
16 楼
SelfID = GetCurrentProcessId();
SelfHandle = OpenProcess(PROCESS_ALL_ACCESS , FALSE , SelfID);
pHandle = (PVOID)malloc(0x1000);
status = NtQuerySystemInformation(SystemHandleInformation , pHandle , 0x1000 , &dwSize);
pHandle = (PVOID)malloc(dwSize);
status = NtQuerySystemInformation(SystemHandleInformation , pHandle , dwSize , NULL);
pSystemHandleInfo = (PSYSTEM_HANDLE_INFORMATION)pHandle;
for (i = 0 ; i < pSystemHandleInfo->NumberOfHandles ; i++)
{
if (pSystemHandleInfo->Handles[i].HandleValue == (WORD)SelfHandle &&
pSystemHandleInfo->Handles[i].UniqueProcessId == SelfID)
{
SeflObject = pSystemHandleInfo->Handles[i].Object;
}
}
for (i = 0 ; i < pSystemHandleInfo->NumberOfHandles ; i++)
{
if (pSystemHandleInfo->Handles[i].Object == SeflObject &&
pSystemHandleInfo->Handles[i].UniqueProcessId != SelfID)
{
//这里自己排除系统的和杀软的就ok了,你在这里打印下就明白了
}
}
|
能力值:
( LV2,RANK:10 )
|
-
-
17 楼
既然是知道自己的进程被调试了。那么就找自己的父进程就可以了。
获得父进程ID
#include <tlhelp32.h>
DWORD GetParaentProcessId(DWORD dwSelfProcessId)
{
DWORD dwParentProcessId = -1;
HANDLE hSnapshot = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
PROCESSENTRY32 pe32;
pe32.dwSize = sizeof( PROCESSENTRY32 );
Process32First( hSnapshot, &pe32 );
do
{
if(pe32.th32ProcessID == dwSelfProcessId)
{
dwParentProcessId = pe32.th32ParentProcessID;
break;
}
} while ( Process32Next( hSnapshot, &pe32 ) );
CloseHandle( hSnapshot );
return dwParentProcessId;
}
--------------------------------------------------------------------------------------------------------
如果是这个进程被attach有点不好弄。
1.可以通过ReadProcessMemory读每个进程的teb->DbgSsReserved
如果这个结构不为空。证明此进程是个调试器进程。
然后在通过ZwQuerySystemInformation的获得这个进程所有handle信息。如果这些handle中有我们进程的handle和我们线程的handle,那就基本可以判定这个进程是调试器了。
|
能力值:
( LV4,RANK:40 )
|
-
-
18 楼
基本懂了,谢谢各位前辈,结贴。
|
|
|