【问题标题】:ptrace in solarisSolaris 中的 ptrace
【发布时间】:2011-07-15 14:48:12
【问题描述】:

我正在尝试将使用ptrace 的程序从linux 移植到solaris,但没有运气,因为它抱怨找不到sys/ptrace.h。知道如何移植吗?

【问题讨论】:

  • 什么程序,它对ptrace有什么作用?

标签: c solaris ptrace


【解决方案1】:

至少在我可以访问的 solaris 系统上,man ptrace 说包括

#include <unistd.h>
#include <sys/types.h>

用于访问 ptrace 原型和常量。但是,有一个使用说明指出 ptrace 仅适用于 32 位 libc,并且 64 位客户端应该使用 /proc 调试接口,所以我不确定这会让你走多远。

【讨论】:

    【解决方案2】:

    有些(例如 Solaris)已将 ptrace 作为系统调用删除 完全将其保留为重新解释调用的库调用 就平台的procfs而言的ptrace

    http://en.wikipedia.org/wiki/Ptrace

    另外,strace 实用程序似乎在 Solaris 上不可用,取而代之的是一个名为 truss 的实用程序,看看你的系统上是否有它。

    【讨论】:

      【解决方案3】:

      编辑:添加和删除了有关如何联系我以及我如何将代码许可给您的陈旧信息

      我最终使用/proc/&lt;pid&gt;/ctrl/proc/&lt;pid&gt; 中的其他各种接口来编写我自己的库来做ptrace() 之类的事情。不幸的是,该界面(至少在当时)被标记为直接使用不安全,可能随时更改等,但在实践中似乎很稳定。不知道它是否已经改变了,这是大约 2011 年左右,我想......

      要开发基本的 ptrace 等效功能,请从:

      man 4 proc
      

      使用/proc/&lt;pid&gt;/ctrl 接口,您可以做几乎所有事情(以及更多)而不是使用 ptrace,例如读/写内存/寄存器、附加/分离、设置系统调用断点等。使用 not 太多工作,你可以编写自己的 ptrace 仿真 API。这些是我编写的 API 低级部分的原型:

      procfs_ctl_PCSFAULT (pid_t pid, fltset_t * fltset);
      procfs_ctl_PCWATCH (pid_t pid, prwatch_t * prwatch);
      procfs_ctl_PCSTRACE (pid_t pid, sigset_t * sigset);
      procfs_ctl_PCSEXIT (pid_t pid, sysset_t * sysset);
      procfs_ctl_PCSENTRY (pid_t pid, sysset_t * sysset);
      procfs_ctl_PCWSTOP (pid_t pid);
      procfs_ctl_PCSVADDR (pid_t pid, long vaddr);
      procfs_ctl_PCSTOP (pid_t pid);
      procfs_ctl_PCWRITE (pid_t pid, off_t off, void *buff, size_t count);
      procfs_ctl_PCTWSTOP (pid_t pid, long delay);
      procfs_ctl_PCSCRED (pid_t pid, prcred_t * cred);
      procfs_ctl_PCREAD (pid_t pid, off_t off, void *buff, size_t count);
      procfs_ctl_PCSSIG (pid_t pid);
      procfs_ctl_PCRUN (pid_t pid, long flags);
      procfs_ctl_PCDSTOP (pid_t pid);
      procfs_ctl_PCCSIG (pid_t pid);
      procfs_ctl_PCCFAULT (pid_t pid);
      procfs_ctl_PCKILL (pid_t pid, long signal);
      procfs_ctl_PCSREG (pid_t pid, long lwpid, prgregset_t * regs);
      

      您可能会看到在这些函数之上为 ptrace 编写一个兼容层是多么容易。 Solaris Internals 这本书在这样做时非常有用 - 虽然关于 proc 接口的章节几乎是手册页的逐字副本,但必须快速翻阅真是太好了。

      最终,我最终没有生成与 ptrace 兼容的 API——我跳过了这一步并实现了执行更高级别功能的函数——使用这些基于 /proc/&lt;pid&gt;/ctrl 的较低级别函数的高级代码示例,这里是我基于这些低级函数实现的一些示例高级函数的列表,这些函数演示了它们提供的所有构建块(几乎所有内容,正如我所说)

      注意:这些是为特定程序设计的,该程序需要对正在运行的二进制文件(无符号)执行奇异/危险/不受支持的事情,例如查找字符串和地址引用、定位和调用现有函数、注入和运行与位置无关的代码,钩子系统调用和修改参数和读取返回值等,所以这里有很多奇怪的函数。

      此外,涉及搜索对字符串和指针的引用的内容写得不是很好——它们只是为了在我正在使用的应用程序上工作而编写的。你真的应该使用像真正的二进制分析库这样的东西,但这只是展示了 proc 接口是多么强大。这一切都适用于 Solaris 9/10 SPARC。例子:

      TrapPostSyscall (pid, SYS_dup);
      SingleStep(pid,lwpid,flags);
      AttachProcess (pid);
      ContinueProcess (pid, PRCFAULT | PRCSIG | PRSABORT);
      DetachProcess (pid);
      GetFaultAddress(pid,1);
      GetMainDataSection (pid, &datamap);
      WhyStopped (pid, 1));
      PrintRegisters(regs);
      ReadGeneralRegisterSet (pid, 1, &saved_regs);
      SetProgramCounter (pid, 1, mapping - 4);
      StopProcess (pid);
      TraceFault (pid, FLTWATCH);
      TrapPostSyscall (pid, SYS_dup);
      TrapPostSyscall (pid, SYS_execve);
      TrapSyscallClearall (pid);
      WaitForProcessStop (pid);
      WatchMemory (pid, datamap.pr_vaddr, datamap.pr_size,WA_TRAPAFTER | WA_WRITE);
      WriteGeneralRegisterSet (pid, 1, &saved_regs);
      WriteToProcess (pid, mapping, call_pic, sizeof (call_pic));
      ReadFromProcess (pid, prmap.pr_vaddr, buff, size);
      GetIndividualRegister (pid, 1, R_O0, (long *) fd);
      SetIndividualRegister (pid,1,R_O0,fd);
      IsProcessStopped (pid);
      SearchProcessForReference (pid, stringat);
      SearchProcessMem (pid,needle,strlen(needle)+1);
      GetPreviousSave (pid, SearchProcessForReference (pid, stringat));
      GetMapFromVirtualAddress (pid, base, &prmap);
      GetNextProcessMapping (pid, &prmap);
      SearchProcessWordRef (pid, addr);
      GetReadWriteExecMapping (pid);
      CreateRemoteMapping (pid, NULL, PAGESIZE)
      TrapSyscall (pid, SYS_dup);
      TrapSyscallClearall(pid);
      TrapPostSyscall (pid, SYS_dup);
      TrapPostSyscallClearall (pid);
      

      如果你对此感兴趣,我可以 GPL 低级或高级的东西,你可以很容易地围绕它们生成 ptrace 兼容的包装器。给我发个便条,我会在 GPLv2

      下分享

      【讨论】:

        猜你喜欢
        • 2012-04-05
        • 2015-03-01
        • 2014-09-14
        • 2011-11-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-06-21
        相关资源
        最近更新 更多