win32调试api学习心得.docx

上传人:b****5 文档编号:2775237 上传时间:2022-11-15 格式:DOCX 页数:12 大小:25.96KB
下载 相关 举报
win32调试api学习心得.docx_第1页
第1页 / 共12页
win32调试api学习心得.docx_第2页
第2页 / 共12页
win32调试api学习心得.docx_第3页
第3页 / 共12页
win32调试api学习心得.docx_第4页
第4页 / 共12页
win32调试api学习心得.docx_第5页
第5页 / 共12页
点击查看更多>>
下载资源
资源描述

win32调试api学习心得.docx

《win32调试api学习心得.docx》由会员分享,可在线阅读,更多相关《win32调试api学习心得.docx(12页珍藏版)》请在冰豆网上搜索。

win32调试api学习心得.docx

win32调试api学习心得

《加密解密技术内幕》3.24Win32调试API学习心得

(一)

最近学习了一下WIN32的调试API,并做了一个简单的调试器,略有心得,特写出来希望对需要的朋友有所帮助. 

参考资料:

lczlion:

<

        彭春华:

<<用Debug函数实现API函数的跟踪>> 

概述:

 

  Windows提供了一组供程序员使用的API,使用这些API,我们能够建立或捆绑到已运行的程序上来对他们进行调试,能获得程序的底层信息和调试信息.如果你原意的话,甚至可以对被调试程序进行任意的修改(用WriteProcessMemory). 

  先让我们从一个有趣的小例子开始吧:

打开DELPHI,新建工程,然后双击主窗体,在主窗体的Create事件中写下如下代码. 

procedureTForm1.FormCreate(Sender:

TObject); 

var 

 isDebuggerPresent:

function:

Boolean; 

 DllModule:

THandle; 

begin 

 DllModule:

=LoadLibrary(’kernel32.dll’); 

 isDebuggerPresent:

=GetProcAddress(DllModule,’IsDebuggerPresent’); 

 ifisDebuggerPresentthen 

 begin 

  MessageBox(self.Handle,’请不要调试我!

’,’抗议’,MB_OKorMB_ICONASTERISK); 

  Application.Terminate; 

 end; 

end; 

   按F9运行,程序执行得并不顺利,在弹出来一个抱怨你调试了它的窗口后就中止了.然后我们再在DELPHI的Projecs目录下找到刚刚编释出来的程序,双击执行它,这次窗口就老老实实的出来了,这是怎么回事呢?

 

  原来上面的isDebuggerPresent就是Win32调试API中的一员,它的作用是判断调用它的进程是否在调试描述表下运行(也就是是否处于被调试状态),另一方面也说明了DELPHI的调试器也是用Win32调试API实现的.这下对调试API有兴趣了吧?

那让我们来继续深入调试API的世界!

 

得到一个供调试的程序:

 

  由于我们的程序要扮演调试器的角色,我们还必需要有一个供调试的程序.这个程序可以通过二种方法获得:

 

  1:

使用DebugActiveProcess函数. 

   这个函数的定义是DebugActiveProcess(dwProcessID:

DWORD):

Bool;stdcall,dwProcessID用于指定被调试的进程的标识符,如果函数调用成功返回TRUE,失败返回FALSE.注意,如果是在NT/2000/XP上,如果目标进程是由一个安全描述器创建的,而该安全描述符使调试器没有充分的访问权,那么此函数的调用可能失败.  

  2:

使用CreateProcess函数. 

  这个函数的定义是CreateProcess(lpApplicationName:

PChar;lpCommandLine:

  PChar;lpProcessAttributes,lpThreadAttributes:

PSecurityAttributes; 

 bInheritHandles:

BOOL;dwCreationFlags:

DWORD;lpEnvironment:

Pointer; 

 lpCurrentDirectory:

PChar;constlpStartupInfo:

TStartupInfo; 

 varlpProcessInformation:

TProcessInformation):

BOOL;stdcall 

  由于篇幅原因,这儿就不详解CreateProcess的每个参数的含义,具体请参考API大全,我们这儿只谈如何创建一个被调试的进程.即设置dwCreationFlags参数,你可以指定DEBUG_PROCESS标志来建立一个被调试进程,同时被调试进程的子进程的调试信息也将通知我们的调试器.还可以指定DEBUG_PROCESSorDEBUG_ONLY_THIS_PROCESS标志来表示只调试当前过程. 

处理调试信息:

 

  当我们用上面的方法之一打开了被调试的程序后,我们的程序应调用WaitForDebugEvent等待处理调试事件.它阻塞调用线程直到调试的事件发生.此函数的定义是:

 

 WaitForDebugEvent(varlpDebugEvent:

TDebugEvent;dwMilliseconds:

DWORD):

BOOL;stdcall; 

其中lpDebugEvent结构将在调试事件发生时返回发生的调试事件信息.dwMilliseconds值指定函数等待调试事件的时间,以毫秒为单位,一般设为INFINITE,表示一直等待直到调试事件发生. 

  这有点于类似于一个消息循环.我们一般都会新建一个线程,在线程中使用DebugActiveProcess或CreateProcess得到一个供调试的程序,然后用一个循环调用WaitForDebugEvent来处理随后发生的调试事件.至于为什么要在新的线程中处理呢?

你不会想你的调试器一打开被调试程序后就一动也不能动了吧;-) 

继续运行被调试程序:

 

  当调试事件发生后,被调试程序会被WINDOWS挂起,当我们处理完了调试事件后,还要让被调试程序继续运行,这就要用到ContinueDebugEvent函数,定义如下:

 

 ContinueDebugEvent(dwProcessId,dwThreadId,dwContinueStatus:

DWORD):

BOOL;stdcall; 

其中dwProcessID和dwThreadID是要被恢复的进程和线程ID,可以从lpDebugEvent结构中的dwProcessID和dwThreadID取得.dwContinueStatus是指明如何恢复线程,可能的取值有DBG_CONTINUE和DBG_EXCEPTION_NOT_HANDLED,DBG_CONTINUE指明了如果被调试程序发生了异常,由调试器来处理异常.DBG_EXCEPTION_NOT_HANDLED则表示调试器不处理被调试程序的异常,由被调试程序的默认异常处理程序来处理异常. 

下面是一个简单的例子,实现了监视被调试程序的建立和退出. 

unitUnit1; 

interface 

uses 

 Windows,Messages,SysUtils,Variants,Classes,Graphics,Controls,Forms, 

 Dialogs,StdCtrls; 

type 

 TForm1=class(TForm) 

  Button1:

TButton; 

  procedureButton1Click(Sender:

TObject); 

 private 

  {Privatedeclarations} 

 public 

  {Publicdeclarations} 

 end; 

var 

 Form1:

TForm1; 

implementation 

{$R*.dfm} 

{调试信息处理过程}  

procedureDebugPro; 

var 

 si:

_STARTUPINFOA;   {进程启动信息} 

 pi:

_PROCESS_INFORMATION;{进程信息} 

 Flage:

DWORD; 

 DebugD:

DEBUG_EVENT; {调试事件} 

 Rc:

Boolean; 

begin 

 {建立调试进程} 

 Flage:

=DEBUG_PROCESSorDEBUG_ONLY_THIS_PROCESS; 

 GetStartupInfo(si);  {初始化si结构,不然无法正常建立进程} 

 ifnotCreateProcess(nil,Pchar(’C:

\winnt\NOTEPAD.EXEC:

\Boot.ini’),nil,nil, 

  False,Flage,nil,nil,si,pi)then 

 begin 

  MessageBox(Application.Handle,’建立被调试进程失败’,’!

!

!

’,MB_OKorMB_ICONERROR); 

  exit; 

 end; 

 whileWaitForDebugEvent(DebugD,INFINITE)do 

 begin {根据事件代码进行相应处理} 

  caseDebugD.dwDebugEventCodeof 

   EXIT_PROCESS_DEBUG_EVENT:

 

   begin 

    MessageBox(Application.Handle,’被调试进程中止’,’!

!

!

’,MB_OKorMB_ICONERROR); 

    Break; 

   end; 

   CREATE_PROCESS_DEBUG_EVENT:

 

    MessageBox(Application.Handle,’被调试进程建立’,’!

!

!

’,MB_OKorMB_ICONERROR); 

   EXCEPTION_DEBUG_EVENT:

 

   begin 

    if(DebugD.Exception.ExceptionRecord.ExceptionCode<>EXCEPTION_SINGLE_STEP)and 

      (DebugD.Exception.ExceptionRecord.ExceptionCode<>EXCEPTION_BREAKPOINT)then 

     Rc:

=False  {如果被调试程序产生了异常,让它自己处理} 

    else 

     Rc:

=True; 

   end; 

  end; 

  ifRcthen 

   ContinueDebugEvent(DebugD.dwProcessId,DebugD.dwThreadId, 

     DBG_CONTINUE) 

  else 

   ContinueDebugEvent(DebugD.dwProcessId,DebugD.dwThreadId, 

     DBG_EXCEPTION_NOT_HANDLED); 

 end; 

 CloseHandle(pi.hProcess); 

 Closehandle(pi.hThread); 

end; 

procedureTForm1.Button1Click(Sender:

TObject); 

var 

 ThreadHandle,ThreadID:

THandle; 

begin 

 ThreadHandle:

=CreateThread(

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 求职职场 > 简历

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1