1.我的电脑感染了病毒,用瑞星查说文件名叫acpidisk.sys,病毒名叫Rootkit.win32.Mie.a,请问怎么杀?
2.C语言调试的作用C语言调试器是如何工作的
我的电脑感染了病毒,用瑞星查说文件名叫acpidisk.sys,病毒名叫Rootkit.win32.Mie.a,请问怎么杀?
Rootkit是一种奇特的程序,它具有隐身功能:无论静止时(作为文件存在),还是活动时,(作为进程存在),指标源码常用符号都不会被察觉。换句话说,这种程序可能一直存在于我们的计算机中,但我们却浑然不知,这一功能正是许多人梦寐以求的——不论是计算机黑客,还是计算机取证人员。黑客可以在入侵后置入 Rootkit,秘密地窥探敏感信息,或等待时机,伺机而动;取证人员也可以利用Rootkit实时监控嫌疑人员的不法行为,它不仅能搜集证据,还有利于及时采取行动。!
一、背景知识
我们通常所说的智能机器,大至超级计算机,中到个人PC,小至智能手机,通常都有两部分组成:硬件和软件。并且,设备的智能是通过软件来实现的。所有软件中,有一种是必不可少的,那就是操作系统。操作系统可以简单理解为一组高度复用的核心程序,一方面,它要管理低层的硬件设备,另一方面,为上层其它程序提供一个良好的运行环境。真是同人不同命,同为软件,操作系统却享有至高无上的特权:它不仅管理硬件,而且其他所有软件也都受制于它。
因为在应用程序和硬件之间隔着操作系统,所以应用程序不能直接访问硬件,而是通过调用操作系统提供的接口来使用硬件。也就是说,对应用程序而言,硬件是不可见的。当然,凡事是没有绝对的,应用程序绕过操作系统来直接访问硬件也不是不可能的,但这样做会付出高昂的代价。设想一个软件开发商在开发一款功能丰富的软件,功能本身就够他头痛得了,现在他还得操心某个数据在某个磁道的某个簇上,某个字符在某品牌显示器上的颜色的二进制代码等等繁琐的事情,不用说财力和物力,源码说明社区单说开发周期就是无法容忍的。所以,现在的应用程序都是使用操作系统提供的简单明了的服务来访问系统的,因为毕竟没有谁愿意自讨苦吃。
二、内核的主要功能
从上文中我们已经了解,内核在系统中处于核心枢纽的地位,下面我们具体介绍内核中与Rootkit紧密相关的几个主要功能,更重要的是这些功能对Rootkit的意义所在:
进程管理。进程可以简单理解为运行中的程序,它需要占用内存、CPU时间等系统资源。现在的操作系统大多支持多用户多任务,也就是说系统要并行运行多个程序。为此,内核不仅要有专门代码来负责为进程或线程分配CPU时间,另一方面还要开辟一段内存区域存放用来记录这些进程详细情况的数据结构。内核是怎么知道系统中有多少进程、各进程的状态等信息的?就是通过这些数据结构,换句话说它们就是内核感知进程存在的依据。因此,只要修改这些数据结构,就能达到隐藏进程的目的。
文件访问。文件系统是操作系统提供的最为重要的功能之一。内核中的驱动程序把设备的柱面、扇区等原始结构抽象成为更加易用的文件系统,并提供一个一致的接口供上层程序调用。也就是说,这部分代码完全控制着对硬盘的访问,通过修改内核的这部分代码,攻击者能够隐藏文件和目录。
安全控制。对大部分操作系统来说,因为系统中同时存在多个进程,为了避免各进程之间发生冲突,内核必须对各进程实施有效的隔离措施。比如,在MS- Windows系统中,每个进程都被强制规定了具体的权限和单独的内存范围。因此,对攻击者而言,只要对内核中负责安全事务的代码稍事修改,整个安全机制就会全线崩溃。
内存管理。现在的硬件平台(比如英特尔的奔腾系列处理器)的内存管理机制已经复杂到可以将一个内存地址转换成多个物理地址的地步。举例来说,进程A按照地址 0x读取内存,它得到值的是“飞机”;然而,进程B也是按照同样的地址0x来读取内存,但它取得的值却是“大炮”。像上面这样,同一个地址指向截然不同的dsst跟踪源码两个物理内存位置,并且每个位置存放不同的数据这种现象并不足以为怪——只不过是两个进程对虚拟地址到物理地址进行了不同的映射而已。如果这一点利用好了,我们可以让Rootkit躲避调试程序和取证软件的追踪。
上面介绍了内核的主要功能,以及它们对 Rootkit的重大意义。说到这里,我们就要切入正题了,即:只要我们颠覆(即修改)了操作系统的核心服务(即内核),那么整个系统包括各种应用就完全处于我们的掌控之下了。要想颠覆内核,前提条件是能把我们的代码导入内核。
其中针对SunOS和Linux两种操作系统的rootkit最多(树大招风:P)。所有的rootkit基本上都是由几个独立的程序组成的,一个典型rootkit包括:
1 以太网嗅探器程程序,用于获得网络上传输的用户名和密码等信息。
2 特洛伊木马程序,例如:inetd或者login,为攻击者提供后门。
3 隐藏攻击者的目录和进程的程序,例如:ps、netstat、rshd和ls等。
4 可能还包括一些日志清理工具,例如:zap、zap2或者z2,攻击者使用这些清理工具删除wtmp、utmp和lastlog等日志文件中有关自己行踪的条目。
一些复杂的rootkit还可以向攻击者提供telnet、shell和finger等服务。
还包括一些用来清理/var/log和/var/adm目录中其它文件的一些脚本。
攻击者使用rootkit中的相关程序替代系统原来的ps、ls、netstat和df等程序,使系统管理员无法通过这些工具发现自己的踪迹。接着使用日志清理工具清理系统日志,消除自己的踪迹。然后,攻击者会经常地通过安装的后门进入系统查看嗅探器的日志,以发起其它的攻击。如果攻击者能够正确地安装 rootkit并合理地清理了日志文件,系统管理员就会很难察觉系统已经被侵入,直到某一天其它系统的管理员和他联系或者嗅探器的日志把磁盘全部填满,他才会察觉已经大祸临头了。但是,大多数攻击者在清理系统日志时不是非常小心或者干脆把系统日志全部删除了事,警觉的系统管理员可以根据这些异常情况判断出系统被侵入。不过,在系统恢复和清理过程中,大多数常用的命令例如ps、df和ls已经不可信了。许多rootkit中有一个叫做FIX的程序,在安装 rootkit之前,攻击者可以首先使用这个程序做一个系统二进制代码的仿1769源码快照,然后再安装替代程序。FIX能够根据原来的程序伪造替代程序的三个时间戳 (atime、ctime、mtime)、date、permission、所属用户和所属用户组。如果攻击者能够准确地使用这些优秀的应用程序,并且在安装rootkit时行为谨慎,就会让系统管理员很难发现。
LINUX ROOTKIT IV
前面说过,大部分rootkit是针对Linux和SunOS的,下面我们介绍一个非常典型的针对Linux系统的rootkit--Linux Rootkit IV。Linux Rootkit IV是一个开放源码的rootkit,是Lord Somer编写的,于年月发布。不过,它不是第一个Linux Rootkit,在它之前有lrk、lnrk、lrk2和lrk3等Linux Rootkit。这些rootkit包括常用的rootkit组件,例如嗅探器、日志编辑/删除工具、和后门程序的。
经过这么多年的发展,Linux Rootkit IV功能变的越来越完善,具有的特征也越来越多。不过,虽然它的代码非常庞大,却非常易于安装和使用,只要执行make install就可以成功安装。如果你还要安装一个shadow工具,只要执行make shadow install就可以了。注意:Linux Rootkit IV只能用于Linux 2.x的内核。下面我们简单地介绍一下Linux Rootkit IV包含的各种工具,详细的介绍请参考其发布包的README文件。
隐藏入侵者行踪的程序
为了隐藏入侵者的行踪,Linux Rootkit IV的作者可谓煞费心机,编写了许多系统命令的替代程序,使用这些程序代替原由的系统命令,来隐藏入侵者的行踪。这些程序包括:
ls、find、du
这些程序会阻止显示入侵者的文件以及计算入侵者文件占用的空间。在编译之前,入侵者可以通过ROOTKIT_FILES_FILE设置自己的文件所处的位置,默认是/dev/ptyr。注意如果在编译时使用了SHOWFLAG选项,就可以使用ls -/命令列出所有的文件。这几个程序还能够自动隐藏所有名字为:ptyr、hack.dir和W4r3z的文件。
ps、源码加减溢出top、pidof
这几个程序用来隐藏所有和入侵者相关的进程。
netstat
隐藏出/入指定IP地址或者端口的网络数据流量。
killall
不会杀死被入侵者隐藏的进程。
ifconfig
如果入侵者启动了嗅探器,这个程序就阻止PROMISC标记的显示,使系统管理员难以发现网络接口已经处于混杂模式下。
crontab
隐藏有关攻击者的crontab条目。
tcpd
阻止向日志中记录某些连接
syslogd
过滤掉日志中的某些连接信息
木马程序
为本地用户提供后门,包括:
chfn
提升本地普通用户权限的程序。运行chfn,在它提示输入新的用户名时,如果用户输入rookit密码,他的权限就被提升为root。默认的rootkit密码是satori。
chsh
也是一个提升本地用户权限的程序。运行chsh,在它提示输入新的shell时,如果用户输入rootkit密码,他的权限就被提升为root。
passwd
和上面两个程序的作用相同。在提示你输入新密码时,如果输入rookit密码,权限就可以变成root。
login
允许使用任何帐户通过rootkit密码登录。如果使用root帐户登录被拒绝,可以尝试一下rewt。当使用后门时,这个程序还能够禁止记录命令的历史记录。
木马网络监控程序
这些程序为远程用户提供后门,可以向远程用户提供inetd、rsh、ssh等服务,具体因版本而异。随着版本的升级,Linux Rootkit IV的功能也越来越强大,特征也越来越丰富。一般包括如下网络服务程序:
inetd
特洛伊inetd程序,为攻击者提供远程访问服务。
rshd
为攻击者提供远程shell服务。攻击者使用rsh -l rootkitpassword host command命令就可以启动一个远程root shell。
sshd
为攻击者提供ssh服务的后门程序。
工具程序
所有不属于以上类型的程序都可以归如这个类型,它们实现一些诸如:日志清理、报文嗅探以及远程shell的端口绑定等功能,包括:
fix
文件属性伪造程序
linsniffer
报文嗅探器程序。
sniffchk
一个简单的bash shell脚本,检查系统中是否正有一个嗅探器在运行。
wted
wtmp/utmp日志编辑程序。你可以使用这个工具编辑所有wtmp或者utmp类型的文件。
z2
utmp/wtmp/lastlog日志清理工具。可以删除utmp/wtmp/lastlog日志文件中有关某个用户名的所有条目。不过,如果用于Linux系统需要手工修改其源代码,设置日志文件的位置。
bindshell rootkit
在某个端口上绑定shell服务,默认端口是。为远程攻击者提供shell服务。
如何发现rootkit
很显然,只有使你的网络非常安装让攻击者无隙可乘,才能是自己的网络免受rootkit的影响。不过,恐怕没有人能够提供这个保证,但是在日常的网络管理维护中保持一些良好的习惯,能够在一定程度上减小由rootkit造成的损失,并及时发现rootkit的存在。
首先,不要在网络上使用明文传输密码,或者使用一次性密码。这样,即使你的系统已经被安装了rootkit,攻击者也无法通过网络监听,获得更多用户名和密码,从而避免入侵的蔓延。
使用Tripwire和aide等检测工具能够及时地帮助你发现攻击者的入侵,它们能够很好地提供系统完整性的检查。这类工具不同于其它的入侵检测工具,它们不是通过所谓的攻击特征码来检测入侵行为,而是监视和检查系统发生的变化。Tripwire首先使用特定的特征码函数为需要监视的系统文件和目录建立一个特征数据库,所谓特征码函数就是使用任意的文件作为输入,产生一个固定大小的数据(特征码)的函数。入侵者如果对文件进行了修改,即使文件大小不变,也会破坏文件的特征码。利用这个数据库,Tripwire可以很容易地发现系统的变化。而且文件的特征码几乎是不可能伪造的,系统的任何变化都逃不过 Tripwire的监视(当然,前提是你已经针对自己的系统做了准确的配置:P,关于Tripwire和aide的使用请参考本站的相关文章)。最后,需要能够把这个特征码数据库放到安全的地方。
rootkit类病毒是极难处理的,采用rootkit技术的病毒可以很好的隐藏自身,资源管理器甚至查不到这个路径,就算你打开查看所有文件也是这样。
按杀毒软件提供的路径,记下来 (这种类型的病毒,杀软查杀时一般会报Windows/system/drivers文件夹下的一个****.sys文件是病毒文件的)
1.下载一个软件:冰刃(/website///.html)
这是一个绿色软件,下载解压缩后即可使用。
2.在冰刃左侧的栏里通过“文件”直接定位到这个文件所在的文件夹下,找到这个文件。
3.通过按钮“创建时间”对这个文件夹下的文件进行排序,仔细查看与这个文件在创建时间是同一天的所有文件(但是不是都是与它一样是病毒文件,需要你判断)。右击它们一一删除。用同样的方法排查下system文件夹,看看有没有同名的.dll文件存在,有的话,一并删除。
4.搜索注册表里这个文件的键值,删除搜索到的--如果有的话。
5.重启电脑,这个东西应该清除干净了。
另外,你如果嫌上面的方法比较麻烦的话,你可以下载一个超级巡警来扫描查杀这一类的病毒,安装好这个软件后,点击:设置,选择扫描选设置下的特殊模块,勾选这个选项里的2个选项。然后重启这个软件,一般就可以将这一类的病毒清除了。
6、直接下载个AVG Anti-spyware7.5在安全模式下查杀就ok了!!
7.下载一个解锁软件,在找到sys病毒文件后将他解锁再将他删除就可以了,这个苦头兄弟我也是吃过呢,郁闷啊,祝好运呢
unlocker下载地址:/soft/.htm
C语言调试的作用C语言调试器是如何工作的
C语言调试的作用,C语言调试器是如何工作的很多人还不知道,现在让我们一起来看看吧!
C语言调试器是如何工作的
当你用GDB 的时候,可以看到它完全控制了应用程序进程。当你在程序运行的时候用 Ctrl + C,程序的运行就能够终止,而GDB能展示它的当前地址、堆栈跟踪信息之类的内容。你知道C语言调试器是如何工作的吗?下面是小编为大家带来的关于C语言调试器是如何工作的的知识,欢迎阅读。
但是它们怎么不工作呢?
开始,让我们先研究它怎样才会不工作。它不能通过阅读和分析程序的二进制信息来模拟程序的运行。它其实能做,而那应该能起作用(Valgrind 内存调试器就是这样工作的),但是这样的话会很慢。Valgrind会让程序慢倍,但是GDB不会。它的工作机制与Qemu虚拟机一样。
所以到底是怎么回事?黑魔法?……不,如果那样的话就太简单了。
另一种猜想?……?破解!是的,这里正是这样的。操作系统内核也提供了一些帮助。
首先,关于Linux的进程机制需要了解一件事:父进程可以获得子进程的附加信息,也能够ptrace它们。并且你可以猜到的是,调试器是被调试的进程的父进程(或者它会变成父进程,在Linux中进程可以将一个进程变为自己子进程:-))
Linux Ptrace API
Linux Ptrace API 允许一个(调试器)进程来获取低等级的其他(被调试的)进程的信息。特别的,这个调试器可以:
读写被调试进程的内存 :PTRACE_PEEKTEXT、PTRACE_PEEKUSER、PTRACE_POKE……
读写被调试进程的CPU寄存器 PTRACE_GETREGSET、PTRACE_SETREGS
因系统活动而被提醒:PTRACE_O_TRACEEXEC, PTRACE_O_TRACECLONE, PTRACE_O_EXITKILL, PTRACE_SYSCALL(你可以通过这些标识区分exec syscall、clone、exit以及其他系统调用)
控制它的执行:PTRACE_SINGLESTEP、PTRACE_KILL、PTRACE_INTERRUPT、PTRACE_CONT (注意,CPU在这里是单步执行)
修改它的信号处理:PTRACE_GETSIGINFO、PTRACE_SETSIGINFO
Ptrace是如何实现的?
Ptrace的实现不在本文讨论的范围内,所以我不想进一步讨论,只是简单地解释它是如何工作的(我不是内核专家,如果我说错了请一定指出来,并原谅我过分简化:-))
Ptrace 是Linux内核的一部分,所以它能够获取进程所有内核级信息:
读写数据?Linux有copy_to/from_user。
获取CPU寄存器?用copy_regset_to/from_user很轻松(这里没有什么复杂的,因为CPU寄存器在进程未被调度时保存在Linux的struct task_struct *调度结构中)。
修改信号处理?更新域last_siginfo
单步执行?在处理器出发执行前,设置进程task结构的right flag(ARM、x)
Ptrace是在很多计划的操作中被Hooked(搜索 ptrace_event函数),所以它可以在被询问时(PTRACE_O_TRACEEXEC选项和与它相关的),向调试器发出一个SIGTRAP信号。
没有Ptrace的系统会怎么样呢?
这个解释超出了特定的Linux本地调试,但是对于大部分其他环境是合理的。要了解GDB在不同目标平台请求的内容,你可以看一下它在目标栈里面的操作。
在这个目标接口里,你可以看到所有C调试需要的高级操作:
struct target_ops
{
struct target_ops *beneath;
/* To the target under this one. */
const char *to_shortname;
/* Name this target type */
const char *to_longname;
/* Name for printing */
const char *to_doc;
/* Documentation. Does not include trailing
newline, and starts with a one-line descrip-
tion (probably similar to to_longname). */
void (*to_attach) (struct target_ops *ops, const char *, int);
void (*to_fetch_registers) (struct target_ops *, struct regcache *, int);
void (*to_store_registers) (struct target_ops *, struct regcache *, int);
int (*to__breakpoint) (struct target_ops *, struct gdbarch *,
struct bp_target_info *);
int (*to__watchpoint) (struct target_ops *,
CORE_ADDR, int, int, struct expression *);
}
普通的GDB调用这些函数,然后目标相关的组件再实现它们。(概念上)这是一个栈,或者一个金字塔:栈顶的是非常通用的,比如:
系统特定的Linux
本地或远程调试
调试方式特定的(ptrace、ttrace)
指令集特定的(Linux ARM、Linux x)
那个远程目标很有趣,因为它通过一个连接协议(TCP/IP、串行端口)把两台“电脑”间的执行栈分离开来。
那个远程的部分可以是运行在另一台Linux机器上的'gdbserver。但是它也可以是一个硬件调试端口的界面(JTAG) 或者一个虚拟的机器管理程序(比如 Qemu),并能够代替内核和ptrace的功能。那个远程根调试器会查询管理程序的结构,或者直接地查询处理器硬件寄存器来代替对OS内核结构的查询。
想要深层次学习这个远程协议,Embecosm 写了一篇一个关于不同信息的详细指南。Gdbserver的事件处理循环在这,而也可以在这里找到Qemu gdb-server stub 。
总结一下
我们能看到ptrace的API提供了这里所有底层机制被要求实现的调试器:
获取exec系统调用并从调用的地方阻止它执行
查询CPU的寄存器来获得处理器当前指令以及栈的地址
获取clone或fork事件来检测新线程
查看并改变数据地址读取并改变内存的变量
但是这就是一个调试器的全部工作吗?不,这只是那些非常低级的部分……它还会处理符号。这是,链接源程序和二进制文件。被忽视可能也是最重要的的一件事:断点!我会首先解释一下断点是如何工作的,因为这部分内容非常有趣且需要技巧,然后回到符号处理。
断点不是Ptrace API的一部分
就像我们之前看到的那样,断点不是ptrace API的一部分。但是我们可以改动内存并获取被调试的程序信号。你看不到其中的相关之处?这是因为断点的实现比较需要技巧并且还要一点hack!让我们来检验一下如何在一个指定的地址设置一个断点。
1、这个调试器读取(ptrace追踪)存在地址里的二进制指令,并保存在它自己的数据结构中。
2、它在这个位置写入一个不合法的指令。不管这个指令是啥,只要它是不合法的。
3、当被调试的程序运行到这个不合法的指令时(或者更准确地说,处理器将内存中的内容设置好时)它不会继续运行(因为它是不合法的)。
4、在现代多任务系统中,一个不合法的指令不会使整个系统崩溃掉,但是会通过引发一个中断(或错误)把控制权交回给系统内核。
5、这个中断被Linux翻译成一个SIGTRAP信号,然后被发送到处理器……或者发给它的父进程,就像调试器希望的那样。
6、调试器获得信号并查看被调试的程序指令指针的值(换言之,是陷入 trap发生的地方)。如果这个IP地址是在断点列表中,那么就是一个调试器的断点(否则就是一个进程中的错误,只需要传过信号并让它崩溃)。
7、现在,那个被调试的程序已经停在了断点,调试器可以让用户来做任何他/她想要做的事,等待时机合适继续执行。
8、为了要继续执行,这个调试器需要 1、写入正确的指令来回到被调试的程序的内存; 2、单步执行(继续执行单个CPU指令,伴随着ptrace 单步执行); 3、把非法指令写回去(使得这个执行过程下一次可以再次停止) ;4、让这个执行正常运行
很整洁,是不是?作为一个旁观的评论,你可以注意到,如果不是所有线程同时停止的话这个算法是不会工作的(因为运行的线程可能会在合法的指令出现时传出断点)。我不会详细讨论GDB是如何解决这个问题的,但在这篇论文里已经说得很详细了:使用GDB不间断调试多线程程序。简要地说,他们把指令写到内存中的其他地方,然后把那个指令的指针指向那个地址并单步执行处理器。但是问题在于一些指令是和地址相关的,比如跳转和条件跳转……
处理符号和调试信息
现在,让我们回到信号和调试信息处理。我没有详细地学习这部分,所以只是大体地说一说。
首先,我们是否可以不使用调试信息和信号地址来调试呢?答案是可以。因为正如我们看到过的那样,所有的低级指令是对CPU寄存器和内存地址来操作的,不是源程序层面的信息。因此,这个到源程序的链接只是为了方便用户。没有调试信息的时候,你看程序的方式就像是处理器(和内核)看到的一样:二进制(汇编)指令和内存字节。GDB不需要进一步的信息来把二进制信息翻译成CPU指令:
(gdb) x/x $pc # heXadecimal representation
0xc: 0x 0x 0xf 0xfd
0xc: 0xa8ec 0x8b 0x8be 0x
0xc: 0x 0x
(gdb) x/i $pc # Instruction representation
=> 0xc: push %r
0xc: push %r
0xc: push %r
0xc: push %r
0xc: mov %rsi,%r
0xc6b: push %rbp
0xc6c: mov %edi,%ebp
0xc6e: push %rbx
0xc6f: sub $0x3a8,%rsp
0xc: mov (%rsi),%rdi
现在,如果我们加上调试信息,GDB能够把符号名称和地址配对:
(gdb) $pc
$1 = (void (*)()) 0xc
你可以通过 nm -a $file 来获取ELF二进制的符号列表:
nm -a /usr/lib/debug/usr/bin/ls.debug | grep " main"
c T main
GDB还会能够展示堆栈跟踪信息(稍后会详细说),但是只有感兴趣的那部分:
(gdb) where
#0 write ()
#1 0xde3 in _IO_new_file_write ()
#2 0xde4c in new_do_write ()
#3 _IO_new_do_write ()
#4 0xd in _IO_new_file_overflow ()
#5 0xbb in print_current_files ()
#6 0xb in main ()
我们现在有了PC地址和相应的函数,就是这样。在一个函数中,你将需要对着汇编来调试!
现在让我们加入调试信息:就是DWARF规范下的gcc -g选项。我不是特别熟悉这个规范,但我知道它提供的:
地址到代码行和行到地址的配对
数据类型的定义,包括typedef和structure
本地变量和函数参数以及它们的类型
$ dwarfdump /usr/lib/debug/usr/bin/ls.debug | grep ce4
0xce4 [, 0] NS
$ addr2line -e /usr/lib/debug/usr/bin/ls.debug 0xce4
/usr/src/debug/coreutils-8./src/ls.c:
试一试dwarfdump来查看二进制文件里嵌入的信息。addr2line也能用到这些信息:
很多源代码层的调试命令会依赖于这些信息,比如next命令,这会在下一行的地址设置一个断点,那个print命令会依赖于变量的类型来输出(char、int、float,而不是二进制或十六进制)。
最后总结
我们已经见过调试器内部的好多方面了,所以我只会最后说几点:
这个堆栈跟踪信息也是通过当前的帧是向上“解开(unwinded)”的($sp和$bp/#fp),每个堆栈帧处理一次。函数的名称和参数以及本地变量名可以在调试信息中找到。
监视点(<code>watchpoints)是通过处理器的帮助(如果有)实现的:在寄存器里标记哪些地址应该被监控,然后它会在那内存被读写的时候引发一个异常。如果不支持这项功能,或者你请求的断点超过了处理器所支持的……那么调试器就会回到“手动”监视:一个指令一个指令地执行这个程序,并检查是否当前的操作到达了一个监视点的地址。是的,这很慢!
反向调试也可以这样进行,记录每个操作的效果,并反向执行。
条件断点是正常的断点,除非在内部,调试器在将控制权交给用户前检查当前的情况。如果当前的情况不满足,程序将会默默地继续运行。
还可以玩gdb gdb,或者更好的(好多了)gdb --pid $(pid of gdb),因为把两个调试器放到同一个终端里是疯狂的:-)。还可以调试系统:
qemu-system-i -gdb tcp::
gdb --pid $(pidof qemu-system-i)
gdb /boot/vmlinuz --exec "target remote localhost:"