[Win32] implementation of a debugger (2) handling of debugging events

Source: Internet
Author: User

In the previous article, we talked about how the debugger handles various debugging events.

 

RIP_EVENT

There is very little documentation on such debugging events, even if it is mentioned, it is simply taken with a "system error" or "internal error. In this case, we do not need to process it, as long as a piece of information is output or simply ignore it.

 

OUTPUT_DEBUG_STRING_EVENT

This type of debugging event is triggered when the debug process calls OutputDebugString. The OUTPUT_DEBUG_STRING_INFO struct describes the details of this event. In MSDN, the fields of this struct are interpreted as: The lpDebugStringData field is the address of the string in the process space of the debugged process; The nDebugStringLength field is the length of the string in characters; fUnicode indicates whether the string is Unicode encoded. According to my experiment, I found that only the first field is correct. In fact, no matter whether you call OutputDebugStringA or OutputDebugStringW, the string is expressed in ANSI encoding. If you call OutputDebugStringW, the string is converted to ANSI encoding before calling OutputDebugStringA (this process is described in MSDN ). Therefore, the fUnicode value is always 0, while the nDebugStringLength is a String Length in bytes rather than characters.

 

Since the string is in the address space of the debugged process, we need to use the ReadProcessMemory function to read the string. The following code shows the process:

1 void OnOutputDebugString (const OUTPUT_DEBUG_STRING_INFO * pInfo ){
2
3 BYTE * pBuffer = (BYTE *) malloc (pInfo-> nDebugStringLength );
4
5 SIZE_T bytesRead;
6
7 ReadProcessMemory (
8 g_hProcess,
9 pInfo-> lpDebugStringData,
10 pBuffer,
11 pInfo-> nDebugStringLength,
12 & bytesRead );
13
14 int requireLen = MultiByteToWideChar (
15 CP_ACP,
16 MB_PRECOMPOSED,
17 (LPCSTR) pBuffer,
18 pInfo-> nDebugStringLength,
19 NULL,
20 0 );
21
22 TCHAR * pWideStr = (TCHAR *) malloc (requireLen * sizeof (TCHAR ));
23
24 MultiByteToWideChar (
25 CP_ACP,
26 MB_PRECOMPOSED,
27 (LPCSTR) pBuffer,
28 pInfo-> nDebugStringLength,
29 pWideStr,
30 requireLen );
31
32 std: wcout <TEXT ("Debuggee debug string:") <pWideStr <std: endl;
33
34 free (pWideStr );
35 free (pBuffer );
36}

 

G_hProcess is a global variable of the HANDLE type. After the debugging process is started, its handle is assigned to g_hProcess.

 

LOAD_DLL_DEBUG_EVENT

This type of debugging event is triggered after a DLL module is loaded. The LOAD_DLL_DEBUG_INFO struct describes its details. The lpImageName field may make you want to output the DLL file name in the debugger, but this does not work. The MSDN explanation is that the value of lpImageName is the address of the file name string in the process space of the debugged process, but this value may be NULL, even if it is not NULL, the read content through ReadProcessMemory may also be NULL. Therefore, it is not reliable to obtain the DLL file name through this field.

 

How can I obtain the file name through the hFile field? If you do not have a Windows API, you can directly obtain the file name through the file handle. To do this, you must go around a large circle. For details, see http://blog.csdn.net/bodybo/archive/2006/08/28/1131346.

 

In fact, hFile is used together with dwDebugInfoFileOffset and nDebugInfoSize to obtain the debugging information of the DLL file. In general, we do not need to do this, so we only need to call CloseHandle to close the handle. Remember! It is very important to close the handle. Otherwise, resource leakage may occur.

 

My idea is to first enumerate the modules of the debugging process through EnumProcessModules, then obtain the base address of the module through GetModuleInformation, and compare the base address with the lpBaseOfDll field of the LOAD_DLL_DEBUG_INFO struct, if they are equal, use GetModuleFileNameEx to get the DLL file name. However, when I tried this method, EnumProcessModules always returns FALSE, and GetLastError returns 299. Why?

 

This may be because when the debugger is processing such debugging events, the debugging process has not been started, and all required modules have not been fully loaded, so it cannot obtain its module information.

 

UNLOAD_DLL_DEBUG_EVENT

This type of debugging event is triggered when a DLL module is detached. Generally, you only need to output a message or ignore it.

 

CREATE_PROCESS_DEBUG_EVENT

The CREATE_PROCESS_DEBUG_INFO struct describes the details of the first debugging event after the process is created. This struct has three fields: handle, hFile, hProcess, and hThread. Remember to use CloseHandle to close them!

 

EXIT_PROCESS_DEBUG_EVENT

This type of debugging event is triggered when the debugging process ends. The EXIT_PROCESS_DEBUG_INFO struct describes its details. Perhaps you can only output the value of the dwExitCode field.

 

CREATE_THREAD_DEBUG_EVENT

This type of debugging event is triggered after a thread is created. The CREATE_THREAD_DEBUG_INFO struct describes its details. Remember to use CloseHandle to close the hThread field!

 

EXIT_THREAD_DEBUG_EVENT

This type of debugging event is triggered after a thread ends. The EXIT_THREAD_DEBUG_INFO struct describes its details. You can only output the value of dwExitCode.

 

Prediction_debug_event

This type of debugging event is triggered when an exception occurs. The EXCEPTION_DEBUG_INFO struct describes its details. Processing such debugging events is the most troublesome, because there are many types of exceptions, and the processing for each exception is also different. In addition, such debugging events are also the key to breakpoint and single-step execution.

 

Due to the excessive length of such debugging events, I will describe them in the next article.

 

Sample Code

The sample code is basically the same as the previous sample code. It only adds the content described in this article and the changes are very limited. Therefore, if you do not think it is necessary, do not download the sample code.

Http://files.cnblogs.com/zplutor/MiniDebugger2.rar

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.