Articles of ptrace

计数程序的系统调用,并用strace检查结果的有效性

我正在使用ptrace来计算程序的系统调用。 问题是给定一个程序A,我的程序打印出系统调用的数量(打开,closures,读取,写入)。 我的程序和strace(带-c选项)的结果与程序A的参数是一样的,除了开放的系统调用。 我的程序打印15和strace打印3。 但是我猜测,strace也打印了一些其他的系统调用,这些可能总结为我的程序计算的15个开放系统调用。 我在查看ORIG_EAX / RAX寄存器时使用SYS_open来检查ptrace的结果。 strace打印的系统调用在这里。 更新: 我从terminal编译我的程序并从那里运行,结果与strace相同。 我正在开发netbeans。 为什么会发生?

使用ptrace进行系统调用,但不戳文本

从跟踪器进行系统调用的最好方法是什么,以便跟踪器调用系统调用? 我宁愿这样做,而不写入Tracee的文本页面。 如果tracee进程是dynamic可执行文件,则dynamic链接程序将保证有系统调用的指令。 跟踪器可以find并设置指令指针。 一个静态可执行文件实际上会在文本中的某个地方有指令。 如果最好的方法是将系统调用指令写入文本, PTRACE_POKETEXT自动将目标页面更改为可写? 如果没有,我们有鸡和鸡蛋的问题。 如果是这样,追踪器是否负责将页面更改回只读?

子程序在执行时不继续执行

我做了以下简单的例子,使用ptrace从subprocess读取内存。 我希望在一个小matrix乘法程序的执行过程中每秒钟在特定地址0x601050处看到这个值。 我使用PTRACE_PEEKDATA,然后是PTRACE_CONT,并在无限循环中hibernate1秒钟,这样做。 然而,matrix乘法程序永远不会进行 – 它应该打印到第一条指令的标准输出,但它似乎永远不会执行。 我明白,ptrace(PTRACE_CONT,pid)会指示孩子恢复执行,而sleep(1)允许它执行一秒钟(直到下一次ptrace调用),但事实并非如此。 #include <string.h> #include <errno.h> #include <inttypes.h> #include <stdlib.h> #include <stdio.h> #include <unistd.h> #include <sys/ptrace.h> #include <sys/types.h> #include <sys/wait.h> #include <sys/user.h> #include <sys/reg.h> int read_mem(long *out, pid_t pid, long addr, size_t sz) { long tmp; size_t copied = 0; while(copied < sz) { tmp = ptrace(PTRACE_PEEKDATA, pid, addr+copied); if(errno) […]

CPU上下文会被ptrace中断,用户空间堆栈还是内核堆栈?

在Linux x86_64上,当我使用ptrace来停止进程时,所有线程的CPU上下文会被保存,还是只保存进程的CPU上下文? 进程的用户空间堆栈或内核堆栈上的上下文是什么? 或者别的地方? 还是多份? 对于其他情况(而不是ptrace),哪里可以中断(包括exception和系统调用)CPU上下文保存,内核堆栈,用户空间堆栈或其他地方? ptrace是一个中断吗? 更新 看来,ptrace的上下文pt_regs_x86_t,保存的位置是由程序员决定的。 但是内核是否也会为被中断的上下文存储一个副本?

如何在Linux上使用Ptrace来打印C ++其他进程的调用堆栈

我正在研究一个需要在Linux上执行所有进程的调用堆栈的应用程序。 我正在尝试使用ptrace,但无法继续使用它,因为我需要在代码中遵循的步骤对我而言并不清楚。 我也尝试了回溯,但它的使用限于当前的过程。 有人能指导我吗? 谢谢,Sandeep

如何在Ubuntu x64中插入int3与ptrace?

我试图按照这个指南来实现与设置断点相同的结果,唯一的区别是我在x64系统上。 所以,我有“Hello,World!”这个代码: ; The _start symbol must be declared for the linker (ld) global _start section .text _start: ; Prepare arguments for the sys_write system call: ; – rax: system call number (sys_write) ; – rdi: file descriptor (stdout) ; – rsi: pointer to string ; – rdx: string length mov rax, 1 mov rdi, […]

为什么在连接tracee的时候GDB可以屏蔽tracee的SIGKILL?

信号(7)手册页说, SIGKILL不能被捕获,阻塞或忽略。 但是我刚才注意到,在使用GDB连接到一个进程后,我不能再发送SIGKILL到这个进程(同样,其他的信号也不能传送)。 但是在我分离并退出GDB之后, SIGKILL像往常一样交付。 在我看来,GDB在连接时阻止了该信号(代表tracee),并在分离时解除阻塞。 但是, ptrace(2)手册页说: 在跟踪的过程中,即使信号被忽略,每次信号传递时Tracee也会停止。 ( SIGKILL是一个例外,具有其通常的效果。) 那为什么这样呢? GDB使用什么技巧? 这是一个示范的简单例子: testing程序 #include <pthread.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <signal.h> #include <errno.h> #include <string.h> /* Simple error handling functions */ #define handle_error_en(en, msg) \ do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0) struct sigaction act; void sighandler(int signum, […]

PTRACE_SYSCALL和orig_eax

我想杀死一个subprocess,如果它执行其他系统调用而不是读写(甚至过滤这些调用,但是这是一个不同的故事),但默认情况下会执行一些系统调用。 我已经编译了一个空的testing子(即刻退出)程序,并且我还有一个父进程,它可以分叉并执行子程序。 父进程使用PTRACE_SYSCALL并每次检查orig_eax。 我的testing程序报告说,孩子被停止了49次(我认为这意味着48/2 + 1次系统调用)。 我想知道系统调用序列是否始终是相同的(初始化)和/或可以知道什么时候可以开始以及什么时候停止在父系统中的kill-on-syscall?

Linux:有没有办法使用ptrace而不停止/暂停进程(SIGSTOP)?

我试图将一个程序从Windows移植到Linux。 当我发现Linux上没有“真正的” ReadProcessMemory对应项时,遇到了一个问题。 我寻找一个替代品,我发现ptrace ,一个强大的stream程debugging器。 我在C ++中快速地编写了两个小控制台应用程序来testingptrace ,然后在程序中使用它。 TestApp 这是微量元素。 它每隔50毫秒不断打印两个整数,每次增加1个值。 #include <QCoreApplication> #include <QThread> #include <iostream> using namespace std; class Sleeper : public QThread { public: static void usleep(unsigned long usecs){QThread::usleep(usecs);} static void msleep(unsigned long msecs){QThread::msleep(msecs);} static void sleep(unsigned long secs){QThread::sleep(secs);} }; int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); int value = […]

在开始时停止subprocess

我试图实现检查点function来检查点的过程。 我通过分派subprocess来做到这一点。 不过,我需要在开始时暂停subprocess。 稍后,我们可以通过取消暂停subprocess并使父进程自行closures来从检查点重新启动。 这里是我为checkpoint和restart_from_checkpoint写的代码以及如何调用它们的例子。 #include <stdio.h> #include <unistd.h> #include <sys/ptrace.h> #include <sys/wait.h> pid_t checkpoint(); void restart_from_checkpoint( pid_t pid ); int main( int argc, char *argv[] ) { int i; pid_t child_pid; pid_t parent_pid = getpid(); for( i = 0; i < 10; i++ ) { if ( i == 4 ) { printf( "%6s: […]