a我考网

 找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 88|回复: 1

[C语言] 用Debug函数实现API函数的监视

[复制链接]
发表于 2012-7-31 21:48:08 | 显示全部楼层 |阅读模式
  大家知道,VC可以用来调试程序,除了调试Debug程序,当然也可以调试Release程 序(调试Release程序时为汇编代码)。如果知道函数的入口地址,只需在函数入口上设置断点,当程序调用了设置断点的函数时,VC就会暂停目标程序的 运行,你就可以得到目标程序内存的所有你希望得到的东西了。一般来说,只要你有足够的耐心和毅力,以及一些汇编知识,对于监视API函数的输入输出参数还 是可以完成的。* e! z: r4 m$ X+ O" }
  不过,由于VC的调试器会在每次断点时暂停目标程序的运行,对目标程序的过多的暂停对于监视任务而言实在不能忍受。所以,不会有太多的人真的会用VC的调试器作为一个良好的API函数监视器的。& ]' x6 f' A, H# N( l
  如果VC调试器能够在你设置好断点后,在运行时自动输出断点时的堆栈值(也就是函数 的输入参数),在函数运行结束时也自动输出堆栈值(也就是函数的输出参数)和CPU寄存器的值(就是函数返回值),并且不会暂停目标程序。所有一切都是自 动的无需我们干预。你会用它来作为监视器吗?我会的。+ }3 u( F/ H) ~5 k: K- K" v
  我不知道如何让VC这样作(或许VC真的可以这样,但我不知道。有人知道的话请通 知我一声,谢谢),但我知道显然VC也是通过调用Windows API函数完成调试器的任务,而且,这些函数显然可以实现我的要求。我需要作的事情就是自己利用这些API函数,写一个简单的调试器,在目标程序断点发生 时自动输出监视结果并且自动恢复目标程序的运行。
6 @& ]: K  L! C2 i0 v  a# E9 O  显然,用VC调试器作为监视器的话无需知道目标函数的原型就可以得到简单的输入输 出参数和函数运行结果,而且,由于监视代码没有注入目标程序中,就不会出现监视目标函数和监视代码的冲突。VC调试器显然可以跟踪递归函数,也可以跟踪 DLL模块调用DLL本身的函数,以及EXE内部调用自身的函数。只要你知道目标函数的入口地址,就可以跟踪了(监视Exe自身的函数可以通过生成Exe 模块时选择输出Map文件,就可以参考Map文件得到Exe内部函数的地址)。没有听说VC不能调试多线程的,最多是说调试多线程比较麻烦证明多 线程是可以调试的。显然,VC也可以调试DllMain中的代码。这些,已经可以证明通过调试函数可以实现我们的目标了。
  |- @- ?  m9 Y' [  h  对于一个已经启动的进程而言,利用DebugActiveProcess函数就可以捕获目标进程,将目标进程进入被调试状态。! v! Y. W" \* h9 ?
  BOOL DebugActiveProcess(DWORD dwProcessId);& p. F' D8 j1 M% h
  参数dwProcessId是目标进程的进程ID。如何通过ToolHelp系列函 数或Psapi库函数获得一个运行程序的进程ID在很多文章中介绍过,这里就不再重复。对于服务器程序而言,由于没有权限无法捕获目标进程,可以通过提升 监视程序的权限得到调试权限进行捕获目标进程(用户必须拥有调试权限)。* }+ k9 r# C+ ^( H9 p# u2 G; M( y
  对于启动一个新的程序而言,通过CreateProcess函数,设置必要的参数就可以将目标程序进入被调试状态。# h" c/ y+ F: `* A
  BOOL CreateProcess(LPCTSTR lpApplicationName, LPTSTR lpCommandLine,LPSECURITY_ATTRIBUTES lpProcessAttributes,LPSECURITY_ATTRIBUTESlpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOIDlpEnvironment, LPCTSTR lpCurrentDirectory, LPSTARTUPINFO lpStartupInfo,LPPROCESS_INFORMATION lpProcessInformation );/ q2 ~- u1 [" C, r, O# I
  
回复

使用道具 举报

 楼主| 发表于 2012-7-31 21:48:09 | 显示全部楼层

用Debug函数实现API函数的监视

  该函数的具体说明请参考MSDN,在这里我仅介绍我们感兴趣的参数。这里和一般的用 法不同,作为被调试程序dwCreationFlags必须设置为DEBUG_PROCESS或DEBUG_ONLY_THIS_PROCESS。这样启 动的目标程序就会进入被调试状态。这里说明一下DEBUG_PROCESS和DEBUG_ONLY_THIS_PROCESS。 DEBUG_ONLY_THIS_PROCESS就是只调试目标进程,而DEBUG_PROCESS参数则不仅调试目标进程,而且调试由目标进程启动的所 有子进程。比如:在A.exe中启动B.exe,如果用DEBUG_ONLY_THIS_PROCESS启动,监视进程只调试A.exe不会调试 B.exe,如果是DEBUG_PROCESS就会调试A.exe和B.exe。为简单起见,本文只讨论启动参数为 DEBUG_ONLY_THIS_PROCESS的情况。
' B- V5 X' d3 ?4 ~1 I# T( |  使用方法:: Q. C, J$ m; A8 R5 l! m; I
  STARTUPINFO st = {0};PROCESS_INFORMATION pro = {0};st.cb = sizeof(st);CreateProcess(NULL, pszCmd, NULL, NULL, FALSE,DEBUG_ONLY_THIS_PROCESS,NULL, szPath, &st, &pro));// 关闭句柄-这些句柄在调试程序中不再使用,所以可以关闭CloseHandle(pro.hThread);CloseHandle(pro.hProcess);
0 e$ N; ]4 v3 F4 J8 W) K. e  目标进程进入了被调试状态,调试程序(这里调试程序就是我们的监视程序,以后不再说 明)就负责对被调试的程序进行调试操作的调度。调试程序通过WaitForDebugEvent函数获得来自被调试程序的调试消息,调试程序根据得到的调 试消息进行处理,被调试进程将暂停操作,直到调试程序通过ContinueDebugEvent函数通知被调试程序继续运行。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|Woexam.Com ( 湘ICP备18023104号 )

GMT+8, 2024-5-18 17:54 , Processed in 0.307028 second(s), 23 queries .

Powered by Discuz! X3.4 Licensed

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表