⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tut28.html

📁 WINDOWS程序员使用指南--汇编基础
💻 HTML
📖 第 1 页 / 共 3 页
字号:
<html>
<head>
<title>Iczelion's Win32 Assembly Tutorial 28: Win32 Debug API Part 1</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
</head>

<body bgcolor="#330099" text="#FFFFFF" link="#FFFFCC" vlink="#FFCCCC" alink="#CCFFCC">
<h1 align="center"><font face="Arial, Helvetica, sans-serif" color="#FFFFCC">Tutorial 
  28: Win32 Debug API Part 1</font></h1>
<p><font face="MS Sans Serif" size="-1">In this tutorial, you'll learn what Win32 
  offers to developers regarding debugging primitives. You'll know how to debug 
  a process when you're finished with this tutorial. <br>
  Download <b><a href="files/tut28.zip" style="text-decoration:none">the example</a></b>.</font></p>
<h3><font face="MS Sans Serif" size="-1">Theory:</font></h3>
<p><font face="MS Sans Serif" size="-1">Win32 has several APIs that allow programmers 
  to use some of the powers of a debugger. They are called Win32 Debug APIs or 
  primitives. With them, you can:</font></p>
<ul>
  <li><font face="MS Sans Serif" size="-1">Load a program or attach to a running 
    program for debugging</font></li>
  <li><font face="MS Sans Serif" size="-1">Obtain low-level information about 
    the program you're debugging, such as process ID, address of entrypoint, image 
    base and so on.</font></li>
  <li><font face="MS Sans Serif" size="-1">Be notified of debugging-related events 
    such as when a process/thread starts/exits, DLLs are loaded/unloaded etc.</font></li>
  <li><font face="MS Sans Serif" size="-1">Modify the process/thread being debugged</font></li>
</ul>
<p><font face="MS Sans Serif" size="-1">In short, you can code a simple debugger 
  with those APIs. Since this subject is vast, I divide it into several managable 
  parts: this tutorial being the first part. I'll explain the basic concepts and 
  general framework for using Win32 Debug APIs in this tutorial.</font><br>
  <font face="MS Sans Serif" size="-1">The steps in using Win32 Debug APIs are:</font></p>
<ol>
  <li><font color="#CCFFCC"><b><font face="MS Sans Serif" size="-1">Create a process 
    or attach your program to a running process</font></b></font><font face="MS Sans Serif" size="-1">. 
    This is the first step in using Win32 Debug APIs. Since your program will 
    act as a debugger, you need a program to debug. The program being debugged 
    is called a debuggee. You can acquire a debuggee in two ways:</font> 
    <ul>
      <li><font face="MS Sans Serif" size="-1">You can create the debuggee process 
        yourself with <font color="#FFFFCC"><b>CreateProcess</b></font>. In order 
        to create a process for debugging, you must specify the <font color="#FFCCCC"><b>DEBUG_PROCESS</b></font> 
        flag. This flag tells Windows that we want to debug the process. Windows 
        will send notifications of important debugging-related events (debug events) 
        that occur in the debuggee to your program. The debuggee process will 
        be immediately suspended until your program is ready. If the debuggee 
        also creates child processes, Windows will also send debug events that 
        occur in all those child processes to your program as well. This behavior 
        is usually undesirable. You can disable this behavior by specifying <font color="#FFCCCC"><b>DEBUG_ONLY_THIS_PROCESS</b></font> 
        flag in combination of <font color="#FFCCCC"><b>DEBUG_PROCESS</b></font> 
        flag. </font></li>
      <li><font face="MS Sans Serif" size="-1">You can attach your program to 
        a running process with <font color="#FFFFCC"><b>DebugActiveProcess.</b></font></font></li>
    </ul>
  </li>
  <li><font color="#CCFFCC"><b><font face="MS Sans Serif" size="-1">Wait for debugging 
    events</font></b></font><font face="MS Sans Serif" size="-1">. After your 
    program acquired a debuggee, the debuggee's primary thread is suspended and 
    will continue to be suspended until your program calls <font color="#FFFFCC"><b>WaitForDebugEvent</b></font>. 
    This function works like other WaitForXXX functions, ie. it blocks the calling 
    thread until the waited-for event occurs. In this case, it waits for debug 
    events to be sent by Windows. Let's see its definition:</font> 
    <p><font face="MS Sans Serif" size="-1"><b><font color="#CCCC99">WaitForDebugEvent 
      proto lpDebugEvent:DWORD, dwMilliseconds:DWORD</font></b></font></p>
    <p><font face="MS Sans Serif" size="-1"><b><font color="#CC9900">lpDebugEvent</font></b> 
      is the address of a <font color="#33CC00"><b>DEBUG_EVENT</b></font> structure 
      that will be filled with information about the debug event that occurs within 
      the debuggee.</font></p>
    <p><font face="MS Sans Serif" size="-1"><b><font color="#CC9900">dwMilliseconds</font></b> 
      is the length of time in milliseconds this function will wait for the debug 
      event to occur. If this period elapses and no debug event occurs,<font color="#FFFFCC"><b> 
      WaitForDebugEvent</b></font> returns to the caller. On the other hand, if 
      you specify<font color="#FFCCCC"><b> INFINITE </b></font>constant in this 
      argument, the function will not return until a debug event occurs.</font></p>
    <p><font face="MS Sans Serif" size="-1">Now let's examine the DEBUG_EVENT 
      structure in more detail.</font></p>
    <p><b><font face="MS Sans Serif" size="-1" color="#33CC00">DEBUG_EVENT STRUCT 
      <br>
      &nbsp;&nbsp;&nbsp;dwDebugEventCode dd ? <br>
      &nbsp;&nbsp;&nbsp;dwProcessId dd ? <br>
      &nbsp;&nbsp;&nbsp;dwThreadId dd ? <br>
      &nbsp;&nbsp;&nbsp;u DEBUGSTRUCT <> <br>
      DEBUG_EVENT ENDS </font></b></p>
    <p><font face="MS Sans Serif" size="-1"><b><font color="#CC9900">dwDebugEventCode</font></b> 
      contains the value that specifies what type of debug event occurs. In short, 
      there can be many types of events, your program needs to check the value 
      in this field so it knows what type of event occurs and responds appropriately. 
      The possible values are:</font></p>
  </li>
  <table border="1" cellspacing="2" cellpadding="2" align="center">
    <tr bgcolor="#009999"> 
      <th><b><font face="MS Sans Serif" size="-1">Value</font></b></th>
      <th><font face="MS Sans Serif" size="-1">Meanings</font></th>
    </tr>
    <tr> 
      <td><b><font face="MS Sans Serif" size="-1">CREATE_PROCESS_DEBUG_EVENT</font></b></td>
      <td><font face="MS Sans Serif" size="-1">A process is created. This event 
        will be sent when the debuggee process is just created (and not yet running) 
        or when your program just attaches itself to a running process with <font color="#FFFFCC"><b>DebugActiveProcess</b></font>. 
        This is the first event your program will receive.</font></td>
    </tr>
    <tr> 
      <td><b><font face="MS Sans Serif" size="-1">EXIT_PROCESS_DEBUG_EVENT</font></b></td>
      <td><font face="MS Sans Serif" size="-1">A process exits.</font></td>
    </tr>
    <tr> 
      <td><b><font face="MS Sans Serif" size="-1">CREATE_THEAD_DEBUG_EVENT</font></b></td>
      <td><font face="MS Sans Serif" size="-1">A new thread is created in the 
        debuggee process or when your program first attaches itself to a running 
        process. Note that you'll not receive this notification when the primary 
        thread of the debuggee is created. </font></td>
    </tr>
    <tr> 
      <td height="131"><b><font face="MS Sans Serif" size="-1">EXIT_THREAD_DEBUG_EVENT</font></b></td>
      <td height="131"><font face="MS Sans Serif" size="-1">A thread in the debuggee 
        process exits. Your program will not receive this event for the primary 
        thread. In short, you can think of the primary thread of the debuggee 
        as the equivalent of the debuggee process itself. Thus, when your program 
        sees <font color="#FFCCCC"><b>CREATE_PROCESS_DEBUG_EVENT</b></font>, it's 
        actually the <font color="#FFCCCC"><b>CREATE_THREAD_DEBUG_EVENT</b></font> 
        for the primary thread.</font></td>
    </tr>
    <tr> 
      <td><b><font face="MS Sans Serif" size="-1">LOAD_DLL_DEBUG_EVENT</font></b></td>
      <td><font face="MS Sans Serif" size="-1">The debuggee loads a DLL. You'll 
        receive this event when the PE loader first resolves the links to DLLs 
        (you call <font color="#FFFFCC"><b>CreateProcess</b></font> to load the 
        debuggee) and when the debuggee calls LoadLibrary.</font></td>
    </tr>
    <tr> 
      <td><b><font face="MS Sans Serif" size="-1">UNLOAD_DLL_DEBUG_EVENT</font></b></td>
      <td><font face="MS Sans Serif" size="-1">A DLL is unloaded from the debuggee 
        process. </font></td>
    </tr>
    <tr> 
      <td><b><font face="MS Sans Serif" size="-1">EXCEPTION_DEBUG_EVENT</font></b></td>
      <td><font face="MS Sans Serif" size="-1">An exception occurs in the debuggee 
        process. <font color="#FF3333"><b>Important:</b></font> <font color="#33FF33">This 
        event will occur once just before the debuggee starts executing its first 
        instruction. The exception is actually a debug break (int 3h). When you 
        want to resume the debuggee, call <font color="#FFFFCC"><b>ContinueDebugEvent 
        </b></font>with<b><font color="#FFCCCC"> DBG_CONTINUE </font></b>flag. 
        Don't use <font color="#FFCCCC"><b>DBG_EXCEPTION_NOT_HANDLED</b></font> 
        flag else the debuggee will refuse to run under NT (on Win98, it works 
        fine).</font></font></td>
    </tr>
    <tr> 
      <td><b><font face="MS Sans Serif" size="-1">OUTPUT_DEBUG_STRING_EVENT</font></b></td>
      <td><font face="MS Sans Serif" size="-1">This event is generated when the 
        debuggee calls <font color="#FFFFCC"><b>DebugOutputString</b></font> function 
        to send a message string to your program. </font></td>
    </tr>
    <tr> 
      <td><b><font face="MS Sans Serif" size="-1">RIP_EVENT</font></b></td>
      <td><font face="MS Sans Serif" size="-1">System debugging error occurs</font></td>
    </tr>
  </table>
  <p><font face="MS Sans Serif" size="-1"><b><font color="#CC9900">dwProcessId</font></b> 
    and <font color="#CC9900"><b>dwThreadId</b></font> are the process and thread 
    Ids of the process that the debug event occurs. You can use these values as 
    identifiers of the process/thread you're interested in. Remember that if you 
    use <font color="#FFFFCC"><b>CreateProcess</b></font> to load the debuggee, 
    you also get the process and thread IDs of the debuggee in the <font color="#FFCCCC"><b>PROCESS_INFO</b></font> 
    structure. You can use these values to differentiate between the debug events 
    occurring in the debuggee and its child processes (in case you didn't specify 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -