首页
社区
课程
招聘
如何获取调试器进程
发表于: 2013-5-6 01:50 8372

如何获取调试器进程

2013-5-6 01:50
8372
就是一个程序被调试了,如何知道它被哪个进程调试的呢。在RING3,如何得到呢?谢谢。

[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

收藏
免费 0
支持
分享
最新回复 (17)
雪    币: 130
活跃值: (1005)
能力值: ( 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的进程为调试器
2013-5-6 03:54
0
雪    币: 4318
活跃值: (4833)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
3
但是又如何知道哪个调试器正在调试我们的进程呢
2013-5-6 13:22
0
雪    币: 796
活跃值: (370)
能力值: ( LV9,RANK:380 )
在线值:
发帖
回帖
粉丝
4
呵呵,这个问题学问大了。。
2013-5-6 15:08
0
雪    币: 4318
活跃值: (4833)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
5
我知道在RING0下可以通过我们进程的EPROCESS的DebugPort的KEVENT EventsPresent;
联系到调试器进程,但是RING3如何做呢?RING3下不通过驱动或者系统漏洞可以读RING0内存吗?KEVENT类型怎么转换为RING3下的HANDLE(Event)类型等?
2013-5-6 15:40
0
雪    币: 110
活跃值: (34)
能力值: (RANK:50 )
在线值:
发帖
回帖
粉丝
6
PEB里有木有相关信息……
2013-5-6 22:53
0
雪    币: 4318
活跃值: (4833)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
7
没有样........
2013-5-6 23:10
0
雪    币: 110
活跃值: (34)
能力值: (RANK:50 )
在线值:
发帖
回帖
粉丝
8
RING3下能实现读内核内存的话算是比较高价值的漏洞了,没那么容易得到……
推荐看看张银奎的《软件调试》吧,里面比较详细地介绍了Windows的调试模型
2013-5-6 23:23
0
雪    币: 4318
活跃值: (4833)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
9
那么还是没有解决了?
2013-5-7 08:54
0
雪    币: 228
活跃值: (115)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
10
套个SOD 在R3下你就各种生活不能自理了....
2013-5-7 19:22
0
雪    币: 161
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
使用QuerySystemInformation遍历所有句柄,找到PID和句柄都是自己的_SYSTEM_HANDLE_TABLE_ENTRY_INFO,从而得到自己的object,在遍历对比所有含有自己object的项,列出pid不是自己的项,排除掉系统和杀毒软件,剩下的就是调试自己的的进程
2013-5-7 21:04
0
雪    币: 228
活跃值: (115)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
12
呼叫个驱动改个object_type是很容易的.特别是objectname.
2013-5-7 21:55
0
雪    币: 161
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
他说的是3环啊
2013-5-7 23:59
0
雪    币: 4318
活跃值: (4833)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
14
小弟出道不久 涉世未深 看得不是很懂 不是很了解 要是有示例代码 就更好了
2013-5-8 00:34
0
雪    币: 228
活跃值: (115)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
15
关键是人家调试的不只会用三环的东西啊....然后检查调试器只有找窗口 找OBJ,发现DEBUGOBJ 或者调试窗口直接把自己结束了.
2013-5-8 07:45
0
雪    币: 161
活跃值: (10)
能力值: ( 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了,你在这里打印下就明白了
                }               
        }
2013-5-8 10:50
0
雪    币: 246
活跃值: (26)
能力值: ( 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,那就基本可以判定这个进程是调试器了。
2013-5-8 11:56
0
雪    币: 4318
活跃值: (4833)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
18
基本懂了,谢谢各位前辈,结贴。
2013-5-9 09:22
0
游客
登录 | 注册 方可回帖
返回
//