[Win32] Implementation of a debugger (ii) handling of debug events

Source: Internet
Author: User

[Win32] Implementation of a debugger (ii) handling of debug events

Zplutor
Source: http://www.cnblogs.com/zplutor/
This article copyright belongs to the author and the blog Garden altogether, welcome reprint. However, without the author's consent, this statement must be retained, and in the article page obvious location to the original link, otherwise reserves the right to pursue legal responsibility.

The previous article talked about debugging loops, which is how the debugger should handle various debug events.

Rip_event

There is very little documentation on this debug event, even if it is referred to as a "system error" or "Internal error". That being the case, we don't need to do anything about it, just output a piece of information or simply ignore it.

Output_debug_string_event

This class of debug events is raised when OutputDebugString is called by the debug process, and the Output_debug_string_info struct describes the details about the event. In MSDN, the explanation for each field of the struct is that the Lpdebugstringdata field is the address of the string within the process space of the process being debugged; the Ndebugstringlength field is the length of the string in characters ; Funicode indicates whether the string is Unicode-encoded. According to my own experimental observations, only the first field is interpreted to be right. In fact, the strings are represented in ANSI encoding, whether they are called Outputdebugstringa or OutputDebugStringW. If you call OutputDebugStringW, the string is converted to ANSI encoding before calling Outputdebugstringa (this process is described in MSDN). So the value of Funicode is always 0, and ndebugstringlength is the length of the string in bytes, not in characters.

Since the string is within the address space of the debugged process, we will 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,
Ten pbuffer,
Pinfo->ndebugstringlength,
(&bytesread);
13
int Requirelen = MultiByteToWideChar (
CP_ACP,
Mb_precomposed,
(LPCSTR) pbuffer,
Pinfo->ndebugstringlength,
NULL,
20 0);
21st
tchar* pwidestr = (tchar*) malloc (Requirelen * sizeof (TCHAR));
23
MultiByteToWideChar (
CP_ACP,
Mb_precomposed,
(LPCSTR) pbuffer,
Pinfo->ndebugstringlength,
PWIDESTR,
(Requirelen);
31
Std::wcout << TEXT ("debuggee Debug String:") << pwidestr << Std::endl;
33
(PWIDESTR);
(pbuffer);
36}

G_hprocess is a global variable of type handle. After the debugging process is started, it is assigned a handle to g_hprocess.

Load_dll_debug_event

This class of debug events is raised after a DLL module is loaded, and the LOAD_DLL_DEBUG_INFO structure describes its details. Lpimagename This field may make it possible for you to output the DLL's file name in the debugger, but this does not work. The explanation on MSDN is that the value of Lpimagename is the address of the file name string within the process space of the debugged process, but this value may be null, even if it is not NULL, the content read through readprocessmemory may also be null. Therefore, it is not reliable to get the DLL's file name through this field.

So, what about getting the file name through the hfile field? No Windows API can get filenames directly through file handles, if you want to do so, you must go around a large circle, detailed methods please refer to: http://blog.csdn.net/bodybo/archive/2006/08/28/1131346.aspx.

In fact, hfile is used with Dwdebuginfofileoffset and ndebuginfosize to get debug information for DLL files. In general, we don't need to do this, so just call CloseHandle to close the handle. Remember! It is important to close this handle, which would cause a resource leak if you do not do so.

My idea is to enumerate the modules of the debugged process first through enumprocessmodules, and then get the base address of the module through Getmoduleinformation, and place this base site with Load_dll_debug_ The Lpbaseofdll field of the info struct is compared, and if it is equal, the file name of the DLL is obtained by Getmodulefilenameex. But when I was experimenting with this method, EnumProcessModules always returned false,getlasterror return 299, what is the reason?

This may be because when the debugger is handling such debug events, the debug process has not been started yet, and the required modules are not fully loaded, so the module information for it cannot be obtained.

Unload_dll_debug_event

This type of debug event is thrown when a DLL module is unloaded. In general, just output a piece of information or ignore it.

Create_process_debug_event

The first debug event after the process is created, and the Create_process_debug_info struct describes the details of the debug event for that class. The struct has three fields that are handles, hfile,hprocess and Hthread, and also remember to use CloseHandle to close them!

Exit_process_debug_event

This type of debug event is raised at the end of the debugging process, and the Exit_process_debug_info struct describes its details. Maybe all you can do is output dwexitcode the value of this field.

Create_thread_debug_event

This type of debug event is raised after a thread is created, and the Create_thread_debug_info struct describes its details. Also remember to close the Hthread field with CloseHandle!

Exit_thread_debug_event

This type of debug event is raised after a thread has ended, and the Exit_thread_debug_info struct describes its details. The same can only output the value of Dwexitcode.

Exception_debug_event

This type of debug event is raised when an exception occurs, and the Exception_debug_info struct describes its details. Handling this kind of debug event is the most troublesome, because there are so many kinds of exceptions, and the processing of each exception is not the same. In addition, such debug events are key to implementing breakpoints and stepping.

Because there is too much space for this type of debug event, it is explained in the next article.

Sample code

This time the sample code is basically the same as the last example code, just add the content described in this article, the changes are very limited, so if you feel that you do not need to download.

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

[Win32] Implementation of a debugger (ii) handling of debug events

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.