10.0 探索API调试事件原理

探索,api,调试,事件,原理 · 浏览次数 : 5

小编点评

## Dynamic Process Switching in Windows with Debug API This chapter describes how to achieve dynamic process switching functionality using the Windows Debug API, focusing on capturing and processing specific types of events. **Key Concepts:** * **DEBUG_EVENT** structure: This structure is used to inform the debugger about various events like exceptions, process creation, thread creation, and more. * **WaitForDebugEvent()**: This function waits for a specific type of debug event and stores its details in a `debugEvent` structure. * **ContinueDebugEvent()**: This function allows the debugger to continue reporting events from the same process even if it encounters other events. **Program Flow:** 1. **CreateProcess()**: A new process is created using `CreateProcess()` with appropriate flags. 2. **Attaching to the Process**: * **CreateActiveProcess()**: This method allows attaching and managing a process using its PID. * **WaitForDebugEvent()**: The program waits for a debug event to be reported, checking the type of event using `debugEvent.dwDebugEventCode`. 3. **Interpretation of Debug Events**: * Based on the event type, the program displays relevant information using `printf()`. * It ensures the debugger can continue reporting events from the same process. **Example:** ```c++ DEBUG_EVENT debugEvent = { 0 }; BOOL bRet = TRUE; // Create the process STARTUPINFO startupInfo = { 0 }; PROCESS_INFORMATION pInfo = { 0 }; GetStartupInfo(&startupInfo); // Attach to the process bRet = CreateProcess("d://lyshark.exe", NULL, NULL, NULL, TRUE, DEBUG_PROCESS || DEBUG_ONLY_THIS_PROCESS, NULL, NULL, &startupInfo, &pInfo); // Wait for event while (WaitForDebugEvent(&debugEvent, INFINITE)) { switch (debugEvent.dwDebugEventCode) { // Handle different event types case EXCEPTION_DEBUG_EVENT: printf("Exception handled \\n"); break; // ... other event cases handled here ... } // Continue reporting events bRet = ContinueDebugEvent(debugEvent.dwProcessId, debugEvent.dwThreadId, DBG_CONTINUE); } // Clean up and exit system("pause"); ``` This example shows how to capture and handle different types of debug events using `WaitForDebugEvent()` and `ContinueDebugEvent()`.

正文

本章笔者将通过Windows平台下自带的调试API接口实现对特定进程的动态转存功能,首先简单介绍一下关于调试事件的相关信息,调试事件的建立需要依赖于DEBUG_EVENT这个特有的数据结构,该结构用于向调试器报告调试事件。当一个程序发生异常事件或者被调试器附加时,就会产生对应的DEBUG_EVENT调试事件,通常DEBUG_EVENT包含了多种调试类型,包括异常事件、进程创建事件、线程创建事件、进程退出事件和线程退出事件等等,我们只需要动态捕捉这些调试事件并作相应的处理即可实现更多有用的功能。

调试事件通常可以分为如下几种类型;

  • 异常事件 (Exception Event) - 发生了异常,例如访问非法的内存、除以零或调用了无效的函数。
  • 进程创建事件 (Process Creation Event) - 当一个新进程被创建时发送此事件。
  • 进程退出事件 (Process Exit Event) - 当一个进程退出时发送此事件。
  • 线程创建事件 (Thread Creation Event) - 当一个新线程被创建时发送此事件。
  • 线程退出事件 (Thread Exit Event) - 当一个线程退出时发送此事件。
  • 调试字符串事件 (Debug String Event) - 当一个进程向其调试器发送字符串消息时发送此事件。
  • 输出字符串事件 (Output String Event) - 当输出调试字符串时发送此事件。
  • 动态链接库加载事件(LOAD_DLL_DEBUG_EVENT) - 当进程装载 DLL 时发送此事件。

当我们需要调试一个程序时有两种方式可以实现,第一种方式是通过CreateProcess()函数创建一个进程,并在调用函数时指定DEBUG_PROCESS || DEBUG_ONLY_THIS_PROCESS则当程序被运行起来后自动进入到调试状态,另一种方式则是通过DebugActiveProcess()函数,该函数接受一个正在运行的进程PID号,可动态附加到一个已运行程序上而对其进行调试。

一旦调试器通过CreateProcess()附加并运行,下一步则是通过WaitForDebugEvent()用于等待一个调试事件,当有调试事件到达后系统会将调试类型存储到debugEvent.dwDebugEventCode这个变量内,此时我们可以通过判断该变量内的参数来对特定的事件做出自定义处理操作,接着会通过ContinueDebugEvent()继续等待下一个调试事件的到来,我们以打开一个进程并创建调试为例,看一下如下代码片段;

#include <iostream>
#include <windows.h>

int main(int argc, char* argv[])
{
    DEBUG_EVENT debugEvent = { 0 };
    BOOL bRet = TRUE;

    // 创建调试进程
    STARTUPINFO startupInfo = { 0 };
    PROCESS_INFORMATION pInfo = { 0 };
    GetStartupInfo(&startupInfo);

    // 创建调试进程并设置 DEBUG_PROCESS || DEBUG_ONLY_THIS_PROCESS 调试事件
    bRet = CreateProcess("d://lyshark.exe", NULL, NULL, NULL, TRUE, DEBUG_PROCESS || DEBUG_ONLY_THIS_PROCESS, NULL, NULL, &startupInfo, &pInfo);
    if (!bRet)
    {
        return 0;
    }

    // 附加调试进程
    // DebugActiveProcess(13940)

    // 无限循环等待调试事件
    while (WaitForDebugEvent(&debugEvent, INFINITE))
    {
        // 根据调试事件判断
        switch (debugEvent.dwDebugEventCode)
        {
            // 异常调试事件
        case EXCEPTION_DEBUG_EVENT:
            printf("异常处理事件 \n");
            break;

            // 线程创建调试事件
        case CREATE_THREAD_DEBUG_EVENT:
            printf("线程创建调试事件 \n");
            break;
            // 进程创建调试事件
        case CREATE_PROCESS_DEBUG_EVENT:
            printf("进程创建调试事件 \n");
            break;
            // 线程退出调试事件
        case EXIT_THREAD_DEBUG_EVENT:
            printf("线程退出调试事件 \n");
            break;
            // 进程退出调试事件
        case EXIT_PROCESS_DEBUG_EVENT:
            printf("进程退出调试事件 \n");
            break;
            // 装载DLL调试事件
        case LOAD_DLL_DEBUG_EVENT:
            printf("装载DLL调试事件 \n");
            break;
            // 卸载DLL调试事件
        case UNLOAD_DLL_DEBUG_EVENT:
            printf("卸载DLL调试事件 \n");
            break;
            // 输出调试信息事件
        case OUTPUT_DEBUG_STRING_EVENT:
            printf("输出调试信息事件 \n");
            break;
        }

        // 使调试器能够继续以前报告调试事件的线程
        bRet = ContinueDebugEvent(debugEvent.dwProcessId, debugEvent.dwThreadId, DBG_CONTINUE);
    }

    system("pause");
    return 0;
}

当编译并运行上述程序后,读者应该能看到如下图所示的输出效果,其中包括了各类调试事件被触发时的提示信息,由于在调试事件内没有做任何操作,程序在加载后就被自动运行起来了;

本文作者: 王瑞
本文链接: https://www.lyshark.com/post/b8eecce4.html
版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!

与10.0 探索API调试事件原理相似的内容:

10.0 探索API调试事件原理

本章笔者将通过`Windows`平台下自带的调试API接口实现对特定进程的动态转存功能,首先简单介绍一下关于调试事件的相关信息,调试事件的建立需要依赖于`DEBUG_EVENT`这个特有的数据结构,该结构用于向调试器报告调试事件。当一个程序发生异常事件或者被调试器附加时,就会产生对应的`DEBUG_...

[转帖]探索惊群 ⑥ - nginx - reuseport

https://wenfh2020.com/2021/10/12/thundering-herd-tcp-reuseport/ SO_REUSEPORT (reuseport) 是网络的一个选项设置,它能开启内核功能:网络链接分配 内核负载均衡。 该功能允许多个进程/线程 bind/listen 相

[转帖]探索惊群 ④ - nginx - accept_mutex

https://wenfh2020.com/2021/10/10/nginx-thundering-herd-accept-mutex/ 由主进程创建的 listen socket,要被 fork 出来的子进程共享,但是为了避免多个子进程同时争抢共享资源,nginx 采用一种策略:使得多个子进程,同

算法金 | 选择最佳机器学习模型的 10 步指南

大侠幸会,在下全网同名[算法金] 0 基础转 AI 上岸,多个算法赛 Top [日更万日,让更多人享受智能乐趣] 机器学习和数据科学领域的工作充满挑战和乐趣,在我踏上人工智能探索之路的初期,我对能够参与项目感到无比兴奋。 我满怀热情,我急切地想投身于这些项目中。但是,我尝试开展项目,却发现在寻求顺利

[转帖]【Windows 10】Prometheus监控平台安装以及配置windows Exporter探针

Prometheus 简介 Prometheus是一个开放性的监控解决方案,用户可以非常方便的安装和使用Prometheus并且能够非常方便的对其进行扩展。 在Prometheus的架构设计中,Prometheus Server并不直接服务监控特定的目标,其主要任务负责数据的收集,存储并且对外提供数

[转帖]【特写】实探26层国内最高养猪大楼:一家水泥公司能不能把猪养好?

https://www.jiemian.com/article/8327167.html 吕雅萱 2022年11月07日 10:00浏览 48.3w来源:界面新闻 记者 |吕雅萱 编辑 |任雪松 湖北境内,沿着106国道从黄石市铁山区开往鄂州市鄂城区碧石渡镇,托运山石、水泥、钢材的大卡车呼啸而过。百

AI Agent技术的最新进展与改变世界的典型项目巡礼

AI Agent技术的最新进展与改变世界的典型项目巡礼 1. AI Agent 技术发展以及典型项目 1.0 前 AI Agent 时代 在学术探索的浩瀚星空中,机器人技术领域的璀璨明珠莫过于Agent技术的深入研究,这一领域历来是创新与突破的温床。回溯至大模型浪潮兴起之前,Agent技术的辉煌篇章

antd 3.x升4.x踩坑之路~

我们是袋鼠云数栈 UED 团队,致力于打造优秀的一站式数据中台产品。我们始终保持工匠精神,探索前端道路,为社区积累并传播经验价值。 兼容性问题 第三方依赖兼容问题 React - 最低 v16.9,部分组件使用 hooks 重构 react升级相关文档 Less - 最低 v3.1.0,建议升级到

DevOps全面综述:从概念到实践

这篇文章详尽介绍了DevOps的背景、核心实践、工具和技术,探讨了团队协作、文化建设及组织变革,旨在帮助企业高效实现持续交付和创新。 关注作者,分享互联网架构、云服务技术的全维度知识。作者拥有10+年互联网服务架构、AI产品研发经验、团队管理经验,同济本复旦硕博,复旦机器人智能实验室成员,阿里云认证

[转帖]PostgreSQL 10.0 preview 功能增强 - 国际化功能增强,支持ICU(International Components for Unicode)

https://developer.aliyun.com/article/72935 标签 PostgreSQL , 10.0 , International Components for Unicode , ICU , collate , 国际化 背景 ICU是一个成熟的,被广泛使用的跨平台一致性