2

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

4

3 回答 3

4

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

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

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

于 2011-07-15T15:04:25.977 回答
2

有些,例如 Solaris,已经将 ptrace 作为系统调用完全删除,将其保留为库调用,根据平台的 procfs 重新解释对 ptrace 的调用

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

此外,似乎该strace实用程序在 Solaris 上不可用,而是有一个名为的实用程序truss,看看您的系统上是否有该实用程序。

于 2011-07-15T15:04:00.767 回答
0

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

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

要开发基本的 ptrace 等效功能,请从以下内容开始:

man 4 proc

使用该/proc/<pid>/ctrl接口,您可以做比使用 ptrace 所做的几乎所有事情(甚至更多),例如读/写内存/寄存器、附加/分离、设置系统调用断点等。无需太多工作,您就可以编写您的自己的 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/<pid>/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下分享

于 2014-10-19T17:41:25.483 回答