elva

Ptrace及其命令

在用户模式中,虽然只有一个函数可用,即ptrace(int _request, pid_t _pid, caddr_t _addr, int _data),但是这个函数能做所有的事情!如果你愿意,也可以花费几个小时来编写自己的小调试器,以解决特定的问题。

ptrace函数的_request参数是最重要的一个参数,因为它确定你将做什么。BSDLinux的头文件使用不同的定义,这使得将ptrace应用从一个平台移植到另一个平台变得很复杂。默认地,我们使用BSD头文件中的定义。

r  PT_TRACE_MEPTRACE_TRACEME)将当前进程切换到停止状态。它通常总是与fork/exec一起使用,虽然也能遇到自我追踪的应用程序。对于每一个进程,PT_TRACE_ME只能被调用一次。追踪一个正被追踪的进程是会失败的(另一个较不重要的结果是进程不能追踪它自己。如果要这样做,应该首先从自身派生一个进程)。大量的反调试技术都是以这一事实为基础的。为了克服这类技术,必须使用绕过ptrace的调试器。一个信号被发送到正被调试的进程,并将该进程切换到停止状态,该进程可以使用从父进程上下文中调用的PT_CONTINUEPT_STEP命令从停止状态退出。wait函数会延迟父进程的执行,直到被调试的进程切换为停止状态或者终止为止(终止时,返回值为1407)。其他的所有参数都被忽略。

r  PT_ATTACHPTRACE_ATTACH将进程标志为pid的运行进程切换为停止状态,在这种情形下,调试器进程成为“父进程”。其他的所有参数都被忽略。进程必须具有与调试进程相同的用户标志(UID),并且不能是setuid/setduid进程(否则就要用root来调试)。

r  PT_DETACHPTRACE_DETACH停止进程标志为pid进程(由PT_ATTACHPT_TRACE_ME指定)的调试,并继续其常态运行。其他的所有参数都被忽略。

r  PT_CONTINUEPTRACE_CONT继续进程标志为pid的被调试进程的执行,而不中断与调试器进程的通信。如果addr == 1(在Linux中为0),从上次停止的地址继续执行;否则,从指定的地址继续执行。参数_data指定发送到被调试进程的信号数量(零说明没有信号)。

r  PT_STEPPTRACE_SINGLESTEP进行进程标志为pid的进程的单步执行,即执行下一条机器指令并切换为停止状态(在i386中,这是根据设置追踪标志来实现的,虽然有些“黑客”函数库使用硬件断点)。BSD要求将参数addr置为1,而Linux要求将该参数置为0。其他的所有参数都被忽略。

r  PT_READ_IPT_READ_DPTRACE_PEEKTEXTPTRACE_PEEKDATA)分别从代码区和正调试进程的地址空间区读取机器字。在许多当代的平台中,这两个指令是等价的。ptrace函数接收目标地址addr,并返回读到的结果。

r  PT_WRITE_IPR_READ_DPTRACE_POKETEXTPTRACE_POKEDATA将由_data传入的机器字写入addr所指定的地址。

r  PT_GETREGSPT_GETFPREGSPT_GETDBREGSPTRACE_GETREGSPTRACE_ FPREGSPT_GETFPXREGS将一般用途寄存器、段寄存器和调试寄存器的值读入到地址由_addr指针所指定的调试器进程的内存区中。只有i386平台接收这些与系统相关的命令。寄存器结构的描述放在头文件machine/reg.h文件中。

r  PT_SETREGSPT_SETFPREGSPT_SETDBREGSPTRACE_SETREGSPTRACE_ SETFPREGSPT_SETFPXREGS通过拷贝由_addr指针所指定的内存区域的内容来设置被调试进程的寄存器的值。

r  PT_KILLPTRACE_KILLsigkill发送到被调试进程,以终止其执行。

posted on 2009-07-25 17:52 叶子 阅读(2140) 评论(0)  编辑 收藏 引用 所属分类: Unix


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理