win32-调试API

0x00  调试函数

DebugActiveProcess()                      //使调试器能够附加到活动进程并对其进行调试

DebugActiveProcessStop()              //阻止调试器调试指定的进程

ContinueDebugEvent()                    //使调试器能够继续以前报告调试事件的线程

DebugBreak()                                     //导致当前进程中出现断点异常

DebugBreakProcess()                       //导致指定进程中发生断点异常。这允许调用线程向调试器发出信号以处理异常。

FatalExit()                                            //将执行控制传输到调试器。此后调试器的行为是特定于所使用的调试器类型的。

FlushInstructionCache()                   //将指令缓存刷新为指定的进程。

GetThreadContext()                         //检索指定线程的上下文。

GetThreadSelectorEntry()               //检索指定选择器和线程的描述符表项。

IsDebuggerPresent()                        //确定调用进程是否由用户模式调试器调试.

OutputDebugString()                        //将字符串发送到调试器以供显示。

ReadProcessMemory()                    //读取指定进程某区域的数据

SetThreadContext()                                   //设置指定线程的上下文。

WaitForDebugEvent()                      //等待正在调试的进程中发生调试事件。

WriteProcessMemory()                   //将数据写入指定进程中的内存区域。要写入的整个区域必须是可访问的,否则操作失败。

 

0x01 BOOL WaitForDebugEvent( LPDEBUG_EVENT lpDebugEvent, DWORD dwMilliseconds )

参数1   指向DEBUG_EVENT结构的指针,该结构接收有关调试事件的信息

参数2   等待调试事件的毫秒数。如果此参数为零,则函数将测试调试事件并立即返回。如果参数是无限的,则在调试事件发生之前,函数不会返回

返回值   如果函数成功,则返回值为非零。如果函数失败,则返回值为零。要获得扩展错误信息,请调用GetLastError

 

目标进程中发生一个调试事件后,系统将通知调试器来处理,调试器通过WaitForDebugEvent函数获取目标进程的相关环境信息

DEBUG_EVENT –> 描述调试事件。其成员dwDebugEventCode描述了事件类型

https://docs.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-debug_event

 

0x02 进程调试方式

1调用CreateProcess函数创建进程

如果将dwCreationFlags标志字段设置为DEBUG_PROCESS或DEBUG_ONLY_THIS_PROCESS

则创建一个用于调试的进程

         DEBUG_PROCESS -> 调用线程启动并调试新进程和由新进程创建的所有子进程。它可以使用WaitForDebugEvent函数接收所有相关的调试事件。使用DEBUG_Process的进程将成为调试链的根。这种情况一直持续到使用DEBUG_Process创建链中的另一个进程为止。

如果此标志与DEBUG_ONLY_THIS_PROCESS相结合,则调用方只调试新进程,而不是任何子进程

         DEBUG_ONLY_THIS_PROCESS –> 调用线程启动并调试新进程。它可以使用WaitForDebugEvent函数接收所有相关的调试事件

 

2 调用DebugActiveProcesss函数可以将调试器捆绑到另一个正在运行的进程上

         NT -> 试图通过DebugActiveProcesss函数将调试器绑定到一个创建时带有安全描述符的进程上时,将会失败

         Windows 9.x -> 当指定了一个无效的进程标识符时,调用失败

 

 

0x03 代码

#include <windows.h>

#include <stdio.h>

#include <tchar.h>

 

BOOL ProcessExist = FALSE; //标识进程是否退出

 

DWORD WINAPI ProcessWatch(_In_ LPVOID lpParameter)

{

    printf("ProcessWatch -> start\n");

 

    WaitForSingleObject(lpParameter, INFINITE);    //等待进程退出

 

    printf("ProcessWatch -> end\n");

 

    ProcessExist = FALSE;

 

    return 0;

}

 

int _tmain(int argc, TCHAR* argv[])

{

    STARTUPINFO si;

    PROCESS_INFORMATION pi;

    DEBUG_EVENT debugEvent = { 0 };

 

    ZeroMemory(&si, sizeof(si));

    si.cb = sizeof(si);

    ZeroMemory(&pi, sizeof(pi));

 

    if (argc != 2)

    {

        printf("Usage: %ws [cmdline]\n", argv[0]);

        return 0;

    }

 

    //创建进程

    if (CreateProcess(NULL, argv[1], NULL, NULL, FALSE, DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS, NULL, NULL, &si, &pi))

    {

        printf("CreateProcess success\n");

 

        //创建监听线程,监听进程退出

        if (CreateThread(0, 0, ProcessWatch, pi.hProcess, 0, 0))

        {

 

            ProcessExist = TRUE;

 

            printf("Debug Process Start\n");

 

            //进程创建后监听

            while (ProcessExist)

            {

                if (WaitForDebugEvent(&debugEvent, 150))

                {

                   printf("WaitForDebugEvent Success\n");

 

                   switch (debugEvent.dwDebugEventCode)

                   {

                       //创建进程调试事件

                   case CREATE_PROCESS_DEBUG_EVENT:

 

                       printf("CREATE_PROCESS_DEBUG_EVENT\n");

 

                       break;

 

                       //退出进程调试事件

                   case EXIT_PROCESS_DEBUG_EVENT:

 

                       printf("EXIT_PROCESS_DEBUG_EVENT\n");

 

                       break;

 

                       //异常调试事件

                   case EXCEPTION_DEBUG_EVENT:

 

                       printf("EXCEPTION_DEBUG_EVENT\n");

                       printf("ExceptionCode: %x ExceptionAddress: %p \n", debugEvent.u.Exception.ExceptionRecord.ExceptionCode, debugEvent.u.Exception.ExceptionRecord.ExceptionAddress);

 

                       if (debugEvent.u.Exception.ExceptionRecord.ExceptionCode != EXCEPTION_BREAKPOINT)

                       {

                           ContinueDebugEvent(debugEvent.dwProcessId, debugEvent.dwThreadId, DBG_EXCEPTION_NOT_HANDLED);

                           continue;

                       }

                       break;

 

                       //other

                   default:

 

                       printf("default: %x \n", debugEvent.dwDebugEventCode);

 

                       break;

                   }

 

                   Sleep(1000);

 

                   //恢复线程

                  ContinueDebugEvent(debugEvent.dwProcessId, debugEvent.dwThreadId, DBG_CONTINUE);

                }

                else

                {

                   //等待超时

                   printf("WaitForDebugEvent Failed\n");

                }

            }

 

            printf("Debug Process End\n");

 

        }

 

       

        //关闭创建进程的句柄

        CloseHandle(pi.hProcess);

        CloseHandle(pi.hThread);

    }

    else

    {

        printf("CreateProcess failed (%d).\n", GetLastError());

    }

 

    return 0;

}

 

0x04 备注

1发生一个EXCEPTION_NONCONTINUEABLE异常后,如果使徒继续执行,会产生一个EXCEPTION_NONCONTINUABLE_EXCEPTION异常

2 当以调试的方式创建进程时,在进入进程前,系统会执行一次DebugBreak函数,此时会产生一个EXCEPTION_BREAKPOIN异常

3  ContinueDebugEvent函数

参数2 为DBG_CONTINUE时,表示被操作进程本身不进行异常处理,由ContinueDebugEvent调用方处理异常.

参数2为DBG_EXCEPTION_NOT_HANDLE时,表示由操作进程本身进行异常处理

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值