📄 tut28.html
字号:
db
"All Files",0,"*.*",0,0 <br>
ExitProc db "The debuggee exits",0 <br>
NewThread db "A new thread is created",0 <br>
EndThread db "A thread is destroyed",0 <br>
ProcessInfo db "File Handle: %lx ",0dh,0Ah <br>
db "Process
Handle: %lx",0Dh,0Ah <br>
db "Thread
Handle: %lx",0Dh,0Ah <br>
db "Image
Base: %lx",0Dh,0Ah <br>
db "Start
Address: %lx",0 <br>
.data? <br>
buffer db 512 dup(?) <br>
startinfo STARTUPINFO <> <br>
pi PROCESS_INFORMATION <> <br>
DBEvent DEBUG_EVENT <> <br>
.code <br>
start: <br>
mov ofn.lStructSize,sizeof ofn <br>
mov ofn.lpstrFilter, offset FilterString <br>
mov ofn.lpstrFile, offset buffer <br>
mov ofn.nMaxFile,512 <br>
mov ofn.Flags, OFN_FILEMUSTEXIST or OFN_PATHMUSTEXIST or OFN_LONGNAMES or OFN_EXPLORER
or OFN_HIDEREADONLY <br>
invoke GetOpenFileName, ADDR ofn <br>
.if eax==TRUE <br>
invoke GetStartupInfo,addr startinfo <br>
invoke CreateProcess, addr buffer, NULL, NULL, NULL, FALSE, DEBUG_PROCESS+ DEBUG_ONLY_THIS_PROCESS,
NULL, NULL, addr startinfo, addr pi <br>
.while TRUE <br>
invoke WaitForDebugEvent, addr DBEvent, INFINITE <br>
.if DBEvent.dwDebugEventCode==EXIT_PROCESS_DEBUG_EVENT <br>
invoke MessageBox, 0, addr ExitProc, addr
AppName, MB_OK+MB_ICONINFORMATION <br>
.break <br>
.elseif DBEvent.dwDebugEventCode==CREATE_PROCESS_DEBUG_EVENT <br>
invoke wsprintf, addr buffer, addr ProcessInfo,
DBEvent.u.CreateProcessInfo.hFile, DBEvent.u.CreateProcessInfo.hProcess, DBEvent.u.CreateProcessInfo.hThread,
DBEvent.u.CreateProcessInfo.lpBaseOfImage, DBEvent.u.CreateProcessInfo.lpStartAddress
<br>
invoke MessageBox,0, addr buffer, addr
AppName, MB_OK+MB_ICONINFORMATION <br>
.elseif DBEvent.dwDebugEventCode==EXCEPTION_DEBUG_EVENT <br>
.if DBEvent.u.Exception.pExceptionRecord.ExceptionCode==EXCEPTION_BREAKPOINT
<br>
invoke ContinueDebugEvent,
DBEvent.dwProcessId, DBEvent.dwThreadId, DBG_CONTINUE <br>
.continue <br>
.endif <br>
.elseif DBEvent.dwDebugEventCode==CREATE_THREAD_DEBUG_EVENT <br>
invoke MessageBox,0, addr NewThread, addr
AppName, MB_OK+MB_ICONINFORMATION <br>
.elseif DBEvent.dwDebugEventCode==EXIT_THREAD_DEBUG_EVENT <br>
invoke MessageBox,0, addr EndThread, addr
AppName, MB_OK+MB_ICONINFORMATION <br>
.endif <br>
invoke ContinueDebugEvent, DBEvent.dwProcessId, DBEvent.dwThreadId,
DBG_EXCEPTION_NOT_HANDLED <br>
.endw <br>
invoke CloseHandle,pi.hProcess <br>
invoke CloseHandle,pi.hThread <br>
.endif <br>
invoke ExitProcess, 0 <br>
end start </font></p>
<h3>Analysis:</h3>
<p><font face="MS Sans Serif" size="-1">The program fills the OPENFILENAME structure
and then calls GetOpenFileName to let the user choose a program to be debugged.</font></p>
<p><font face="Fixedsys" size="-1">invoke GetStartupInfo,addr startinfo <br>
invoke CreateProcess, addr buffer, NULL, NULL, NULL, FALSE, DEBUG_PROCESS+ DEBUG_ONLY_THIS_PROCESS,
NULL, NULL, addr startinfo, addr pi </font></p>
<p><font face="MS Sans Serif" size="-1">When the user chose one, it calls <font color="#FFFFCC"><b>CreateProcess</b></font>
to load the program. It calls <font color="#FFFFCC"><b>GetStartupInfo</b></font>
to fill the <font color="#CCFFCC"><b>STARTUPINFO</b></font> structure with its
default values. Note that we use <font color="#FFCCCC"><b>DEBUG_PROCESS</b></font>
combined with <font color="#FFCCCC"><b>DEBUG_ONLY_THIS_PROCESS</b></font> flags
in order to debug only this program, not including its child processes.</font></p>
<p><font face="Fixedsys" size="-1">.while TRUE <br>
invoke WaitForDebugEvent, addr DBEvent, INFINITE </font><font face="MS Sans Serif" size="-1"><br>
</font></p>
<p><font face="MS Sans Serif" size="-1">When the debuggee is loaded, we enter
the infinite debug loop, calling <font color="#FFFFCC"><b>WaitForDebugEvent.</b></font>
<font color="#FFFFCC"><b>WaitForDebugEvent</b></font> will not return until
a debug event occurs in the debuggee because we specify <font color="#CCFFCC"><b>INFINITE</b></font>
as its second parameter. When a debug event occurred, <font color="#FFFFCC"><b>WaitForDebugEvent
</b></font>returns and DBEvent is filled with information about the debug event.</font></p>
<p><font face="Fixedsys" size="-1"> .if DBEvent.dwDebugEventCode==EXIT_PROCESS_DEBUG_EVENT
<br>
invoke MessageBox, 0, addr ExitProc, addr
AppName, MB_OK+MB_ICONINFORMATION <br>
.break </font></p>
<p><font face="MS Sans Serif" size="-1">We first check the value in <font color="#CC9900"><b>dwDebugEventCode</b></font>.
If it's<font color="#FFCCCC"><b> EXIT_PROCESS_DEBUG_EVENT,</b></font> we display
a message box saying "The debuggee exits" and then get out of the
debug loop.</font></p>
<p><font face="Fixedsys" size="-1"> .elseif DBEvent.dwDebugEventCode==CREATE_PROCESS_DEBUG_EVENT
<br>
invoke wsprintf, addr buffer, addr ProcessInfo,
DBEvent.u.CreateProcessInfo.hFile, DBEvent.u.CreateProcessInfo.hProcess, DBEvent.u.CreateProcessInfo.hThread,
DBEvent.u.CreateProcessInfo.lpBaseOfImage, DBEvent.u.CreateProcessInfo.lpStartAddress
<br>
invoke MessageBox,0, addr buffer, addr
AppName, MB_OK+MB_ICONINFORMATION </font></p>
<p><font face="MS Sans Serif" size="-1">If the value in <font color="#CC9900"><b>dwDebugEventCode</b></font>
is <font color="#FFCCCC"><b>CREATE_PROCESS_DEBUG_EVENT</b></font>, then we display
several interesting information about the debuggee in a message box. We obtain
those information from <font color="#CCFFCC"><b>u.CreateProcessInfo</b></font>.
CreateProcessInfo is a structure of type <font color="#FFCCCC"><b>CREATE_PROCESS_DEBUG_INFO</b></font>.
You can get more info about this structure from Win32 API reference. </font></p>
<p><font face="Fixedsys" size="-1"> .elseif DBEvent.dwDebugEventCode==EXCEPTION_DEBUG_EVENT
<br>
.if DBEvent.u.Exception.pExceptionRecord.ExceptionCode==EXCEPTION_BREAKPOINT
<br>
invoke ContinueDebugEvent,
DBEvent.dwProcessId, DBEvent.dwThreadId, DBG_CONTINUE <br>
.continue <br>
.endif </font></p>
<p><font face="MS Sans Serif" size="-1">If the value in <font color="#CC9900"><b>dwDebugEventCode</b></font>
is <font color="#CCFFCC"><b>EXCEPTION_DEBUG_EVENT</b></font>, we must check
further for the exact type of exception. It's a long line of nested structure
reference but you can obtain the kind of exception from <font color="#FFCCCC"><b>ExceptionCode</b></font>
member. If the value in <font color="#FFCCCC"><b>ExceptionCode</b></font> is
<font color="#CCFFCC"><b>EXCEPTION_BREAKPOINT</b></font> and it occurs for the
first time (or if we are sure that the debuggee has no embedded int 3h), we
can safely assume that this exception occured when the debuggee was going to
execute its very first instruction. When we are done with the processing, we
must call <font color="#FFFFCC"><b>ContinueDebugEvent</b></font> with <font color="#CCFFCC"><b>DBG_CONTINUE</b></font>
flag to let the debuggee run. Then we go back to wait for the next debug event.</font></p>
<p><font face="Fixedsys" size="-1"> .elseif DBEvent.dwDebugEventCode==CREATE_THREAD_DEBUG_EVENT
<br>
invoke MessageBox,0, addr NewThread, addr
AppName, MB_OK+MB_ICONINFORMATION <br>
.elseif DBEvent.dwDebugEventCode==EXIT_THREAD_DEBUG_EVENT <br>
invoke MessageBox,0, addr EndThread, addr
AppName, MB_OK+MB_ICONINFORMATION <br>
.endif </font></p>
<p><font face="MS Sans Serif" size="-1">If the value in <font color="#CC9900"><b>dwDebugEventCode</b></font>
is <font color="#CCFFCC"><b>CREATE_THREAD_DEBUG_EVENT</b></font> or <font color="#CCFFCC"><b>EXIT_THREAD_DEBUG_EVENT</b></font>,
we display a message box saying so.</font></p>
<p><font face="Fixedsys" size="-1"> invoke ContinueDebugEvent, DBEvent.dwProcessId,
DBEvent.dwThreadId, DBG_EXCEPTION_NOT_HANDLED <br>
.endw </font></p>
<p><font face="MS Sans Serif" size="-1">Except for the<font color="#CCFFCC"><b>
EXCEPTION_DEBUG_EVENT</b></font> case above, we call <font color="#FFFFCC"><b>ContinueDebugEvent</b></font>
with <font color="#FFCCCC"><b>DBG_EXCEPTION_NOT_HANDLED</b></font> flag to resume
the debuggee.</font></p>
<p><font face="Fixedsys" size="-1">invoke CloseHandle,pi.hProcess <br>
invoke CloseHandle,pi.hThread </font></p>
<p><font face="MS Sans Serif" size="-1">When the debuggee exits, we are out of
the debug loop and must close both process and thread handles of the debuggee.
Closing the handles doesn't mean we are killing the process/thread. It just
means we don't want to use those handles to refer to the process/thread anymore.</font>
</p>
<hr>
<div align="center"><br>
<font face="MS Sans Serif" size="-1"><b>[<a href="http://win32asm.cjb.net">Iczelion's
Win32 Assembly Homepage</a>] </b></font></div>
<p> </p>
</body>
</html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -