转至繁体中文版     | 网站首页 | 图文教程 | 资源下载 | 站长博客 | 图片素材 | 武汉seo | 武汉网站优化 | 
最新公告:     敏韬网|教学资源学习资料永久免费分享站!  [mintao  2008年9月2日]        
您现在的位置: 学习笔记 >> 图文教程 >> 软件开发 >> Delphi程序 >> 正文
Win32调试API学习心得(二)         ★★★★

Win32调试API学习心得(二)

作者:闵涛 文章来源:闵涛的学习笔记 点击数:631 更新时间:2009/4/23 18:37:23
  上一章讲解了如何用调试API来打开一个被调试程序,并给出了一个简单的例子,这一章将祥细
讲解调试消息包含的内容.

  类似于消息处理中的消息结构TMessage一样,调试事件也有自己特定的事件结构,那就是TDeb
ugEvent, TDebugEvent在Delphi中的定义为:
  TDebugEvent = _DEBUG_EVENT;
  _DEBUG_EVENT = record
    dwDebugEventCode: DWORD;
    dwProcessId: DWORD;
    dwThreadId: DWORD;
    case Integer of
      0: (Exception: TExceptionDebugInfo);
      1: (CreateThread: TCreateThreadDebugInfo);
      2: (CreateProcessInfo: TCreateProcessDebugInfo);
      3: (ExitThread: TExitThreadDebugInfo);
      4: (ExitProcess: TExitThreadDebugInfo);
      5: (LoadDll: TLoadDLLDebugInfo);
      6: (UnloadDll: TUnloadDLLDebugInfo);
      7: (DebugString: TOutputDebugStringInfo);
      8: (RipInfo: TRIPInfo);
  end;

  这个结构很复杂,包含了三个基本类型和一个联合类型的数据.dwProcessId和dwThreadId指明
了产生调试事件的进程和线程的ID,dwDebugEventCode指明了产生了何种调试事件,可能的取值
如下表(摘自<<Win32汇编程序设计>>):
  1.CREATE_PROCESS_DEBUG_EVENT:进程被创建.当被调试进程刚被创建(还未运行) 或我们的程
序刚以DebugActiveProcess捆绑到一个运行中的进程时该事件发生. 这是我们的程序应该获得
的第一个事件. 
  2.EXIT_PROCESS_DEBUG_EVENT:被调试进程退出时产生此消息. 
  3.CREATE_THEAD_DEBUG_EVENT:当一个新线程在被调试进程中创建或我们的程序首次捆绑到运
行中的进程时该事件发生.要注意的是当被调试进程的主线程被创建时不会收到该通知.  
  4.EXIT_THREAD_DEBUG_EVENT:被调试进程中的线程退出时事件发生.被调试进程的主线程退出
时不会收到该通知.我们可以认为被调试进程的主线程与被调试进程是同义词. 因此, 当我们
的程序看到CREATE_PROCESS_DEBUG_EVENT标志时,对主线程来说,就是CREATE_THREAD_DEBUG_E
VENT标志. 
  5.LOAD_DLL_DEBUG_EVENT:被调试进程装入一个DLL.当PE装载器第一次分解指向DLL的链接时
,我们将收到这一事件. (当调用CreateProcess装入 被调试进程时)并且当被调试进程调用Lo
adLibrary时也会发生. 
  6.UNLOAD_DLL_DEBUG_EVENT:一个DLL从被调试进程中卸载时此事件发生.  
  7.EXCEPTION_DEBUG_EVENT:在被调试进程中发生异常时事件发生.异常实际上是一个调试中断
(int 3h).如果想恢复被调试进程事,以 DBG_CONTINUE 标志调用ContinueDebugEvent 函数. 
不要使用DBG_EXCEPTION_NOT_HANDLED 标志否则被调试进程会在NT下拒绝运行(Win98下运行得
很好). 
  8.OUTPUT_DEBUG_STRING_EVENT:当被调试进程调用DebugOutputString函数向我们的程序发送
消息字符串时该事件发生.  
  9.RIP_EVENT:系统调试发生错误.


  根据dwDebugEventCode的不同,应调用联合中相应的结构来获得相关的调试信息.例如我们有
个名为Debug的TDebguEvent的结构,在调用WaitForDebugEvent(Debug, INFINITE)后接收到调
试信息时,并且dwDebugEventCode的值为CREATE_PROCESS_DEBUG_EVENT,我们就可以通过仿问D
ebug.CreateProcessInfo.hProcess来获得刚创建的被调试进程的进程句柄.

  下面将祥细讲解TDebugEvent结构中可能包括的每个结构的含义.因为没有相关的祥细资料,大
部分结果是靠测试所得,如有错漏敬请指正.

  一.CreateProcessInfo结构: 对应的调试消息CREATE_PROCESS_DEBUG_EVENT.
CreateProcessInfo.hFile:被调试进程的EXE文件被映射到内存中的内存文件映射句柄,可以
通过打开这个句柄(用OpenFileMapping和MapViewOfFile)来读取此EXE文件的相关信息.如引入
引出表等.
CreateProcessInfo.hProcess:被调试进程的进程句柄,如果要使用ReadProcessMemory和Wri
teProcessMemory等函数来修改被调试进程,就需要用到这个句柄,可以用一个变量保存起来供
以后使用.
CreateProcessInfo.hThread:主线程句柄.
CreateProcessInfo.lpBaseOfImage:可执行文件被装载到虚似地址空间中的基址.
CreateProcessInfo.dwDebugInfoFileOffset:调试信息在可执行文件中的偏移地址(一般为0
,即没有调试信息).
CreateProcessInfo.nDebugInfoSize:调试信息的长度.
CreateProcessInfo.lpThreadLocalBase:主线程基址.
CreateProcessInfo.lpStartAddress:主线程的线程函数地址.
CreateProcessInfo.lpImageName:文件映像名,注意这是一个RVA地址(相对虚拟地址).
CreateProcessInfo.fUnicode:如果此值大于0,则lpImageName指向的文件名为UNICODE码.

  二.ExitProcess结构: 对应的调试消息EXIT_PROCESS_DEBUG_EVENT.
ExitProcess.dwExitCode:即被调试程序调用ExitProcess函数时传入的退出代码.
 
  三.CreateThread结构: 对应的调试消息CREATE_THEAD_DEBUG_EVENT.
CreateThread.hThread:新建线程的句柄.线程句柄,如果以后会涉及到对线程的操作,如挂起
线程等,则可以用一个TList来保存进程ID(TDebugEvent.dwThreadId)和相对应的句柄.再在其
它调试事件发生时,根据dwThreadId得到线程句柄.
CreateThread.lpThreadLocalBase:新线程的基址.
CreateThread.lpStartAddress:新线程的线程函数地址.

  四.ExitThread结构: 对应的调试消息EXIT_THREAD_DEBUG_EVENT.
ExitThread.dwExitCode:即退出的线程调用ExitThread函数时传入的退出代码.
 
  五.LoadDll结构: 对应的调试消息LOAD_DLL_DEBUG_EVENT.
LoadDll.hFile:被加载的DLL文件映射到内存中的内存文件映射句柄,可以通过打开这个句柄
来读取此DLL文件的相关信息.
LoadDll.lpBaseOfDll:DLL文件被装载到虚似地址空间中的基址.这个地址加上DLL文件引出的
函数的地址,就是这个函数在内存中的地址.
LoadDll.dwDebugInfoFileOffset:调试信息在DLL文件中的偏移地址.
LoadDll.nDebugInfoSize:调试信息的长度.
LoadDll.lpImageName:DLL文件名的地址,是一个RVA地.
LoadDll.fUnicode:如果此值大于0,则lpImageName指向的文件名为UNICODE码.

  六.UnLoadDll结构: 对应的调试消息UNLOAD_DLL_DEBUG_EVENT.
UnloadDll.lpBaseOfDll:卸载的DLL文件的基址,可以通过在处理LOAD_DLL_DEBUG_EVENT消息
中保存DLL信息和对应的基址的方法,来得到卸载的DLL信息.

  七.Exception结构: 对应的调试消息EXCEPTION_DEBUG_EVENT.
Exception.ExceptionRecord: 这是一个TExceptionRecord结构,里面包含了被调试程序产生
的中断或异常的代码,产生的中断或异常的地址等信息.

  八.DebugString结构: 对应的调试消息OUTPUT_DEBUG_STRING_EVENT.
DebugString.lpDebugStringData:被调试进程调用DebugOutputString函数发送的消息字符串
的地址.
DebugString.nDebugStringLength:被调试进程调用DebugOutputString函数发送的消息字符
串的长度.
DebugString.fUnicode:如果此值大于0,则消息字符串为UNICODE码.

  九.RipInfo结构: 对应的调试消息RIP_EVENT.
RipInfo.dwError:错误代码.
RipInfo.dwType:错误类型.

  了解了以上的知识,我们就可以在调试器中监视这些调试消息,并获得我们感兴趣的信息.但这
仅仅实现了对被调试调试程序的监视.下一章将讲解如何修改被调试程序.

  附:一个监视目标程序启动,加载DLL,退出的例子,并演示了如何读取RVA地址,获得加载的DLL
文件名的方法.请到下面的地址下载.
http://qxccccc.8u8.com/debug.rar


[VB.NET程序]Auto Complete combo Box(VB.NET Source Use API…  [VB.NET程序]在 VB 中使用 Unicode API
[VB.NET程序]API 更改系统菜单条目  [VB.NET程序]在VB中调用Windows API的注意事项
[VB.NET程序]vb调用winInet API接口post数据到指定的url  [VB.NET程序]如 何 用 API 播 放 CD
[VB.NET程序]VB5.0与Windows API 间的呼叫技巧  [VB.NET程序]在VB6中用WINDOWS API函数读写INI文件
[VB.NET程序]Visual Basic调用Windows API函数的应用举例  [VB.NET程序]VB + API 获取 IE 的 代理服务器 配制
教程录入:mintao    责任编辑:mintao 
  • 上一篇教程:

  • 下一篇教程:
  • 【字体: 】【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
      注:本站部分文章源于互联网,版权归原作者所有!如有侵权,请原作者与本站联系,本站将立即删除! 本站文章除特别注明外均可转载,但需注明出处! [MinTao学以致用网]
      网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)

    同类栏目
    · C语言系列  · VB.NET程序
    · JAVA开发  · Delphi程序
    · 脚本语言
    更多内容
    热门推荐 更多内容
  • 没有教程
  • 赞助链接
    更多内容
    闵涛博文 更多关于武汉SEO的内容
    500 - 内部服务器错误。

    500 - 内部服务器错误。

    您查找的资源存在问题,因而无法显示。

    | 设为首页 |加入收藏 | 联系站长 | 友情链接 | 版权申明 | 广告服务
    MinTao学以致用网

    Copyright @ 2007-2012 敏韬网(敏而好学,文韬武略--MinTao.Net)(学习笔记) Inc All Rights Reserved.
    闵涛 投放广告、内容合作请Q我! E_mail:admin@mintao.net(欢迎提供学习资源)

    站长:MinTao ICP备案号:鄂ICP备11006601号-18

    闵涛站盟:医药大全-武穴网A打造BCD……
    咸宁网络警察报警平台