关于使用PTRACE_SYSEMU的任何好的指南? [英] Any good guides on using PTRACE_SYSEMU?

查看:132
本文介绍了关于使用PTRACE_SYSEMU的任何好的指南?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

任何人对推荐答案

有一个使用PTRACE_SYSEMU的Linux内核源进行的小型测试:

There is small test from linux kernel sources which uses PTRACE_SYSEMU:

http://code .metager.de/source/xref/linux/stable/tools/testing/selftests/x86/ptrace_syscall.c http://lxr.free-electrons.com /source/tools/testing/selftests/x86/ptrace_syscall.c

186 struct user_regs_struct regs;
187
188 printf("[RUN]\tSYSEMU\n");
189 if (ptrace(PTRACE_SYSEMU, chld, 0, 0) != 0)
190     err(1, "PTRACE_SYSCALL");
191 wait_trap(chld);
192
193 if (ptrace(PTRACE_GETREGS, chld, 0, &regs) != 0)
194     err(1, "PTRACE_GETREGS");
195
196 if (regs.user_syscall_nr != SYS_gettid ||
197     regs.user_arg0 != 10 || regs.user_arg1 != 11 ||
198     regs.user_arg2 != 12 || regs.user_arg3 != 13 ||
199     regs.user_arg4 != 14 || regs.user_arg5 != 15) {
200     printf("[FAIL]\tInitial args are wrong (nr=%lu, args=%lu %lu %lu %lu %lu %lu)\n", (unsigned long)regs.user_syscall_nr, (unsigned long)regs.user_arg0, (unsigned long)regs.user_arg1, (unsigned long)regs.user_arg2, (unsigned long)regs.user_arg3, (unsigned long)regs.user_arg4, (unsigned long)regs.user_arg5);
201     nerrs++;
202 } else {
203     printf("[OK]\tInitial nr and args are correct\n");
204 }
205
206 printf("[RUN]\tRestart the syscall (ip = 0x%lx)\n",
207        (unsigned long)regs.user_ip);
208
209 /*
210  * This does exactly what it appears to do if syscall is int80 or
211  * SYSCALL64.  For SYSCALL32 or SYSENTER, though, this is highly
212  * magical.  It needs to work so that ptrace and syscall restart
213  * work as expected.
214  */
215 regs.user_ax = regs.user_syscall_nr;
216 regs.user_ip -= 2;
217 if (ptrace(PTRACE_SETREGS, chld, 0, &regs) != 0)
218     err(1, "PTRACE_SETREGS");
219
220 if (ptrace(PTRACE_SYSEMU, chld, 0, 0) != 0)
221     err(1, "PTRACE_SYSCALL");
222 wait_trap(chld);
223
224 if (ptrace(PTRACE_GETREGS, chld, 0, &regs) != 0)
225     err(1, "PTRACE_GETREGS");
226

因此,它看起来就像是另一个ptrace调用,它将允许程序运行直到由它进行下一个系统调用为止;然后停止child并向ptracer发出信号.它可以读取寄存器,可以选择更改某些寄存器并重新启动系统调用.

So, it looks like just another ptrace call which will allow program to run until next system call is made by it; then stop child and signal the ptracer. It can read registers, optionally change some and restart the syscall.

http://lxr.free -electrons.com/source/kernel/ptrace.c?v=4.10#L1039 就像其他步进ptrace调用一样:

Implemented in http://lxr.free-electrons.com/source/kernel/ptrace.c?v=4.10#L1039 like other stepping ptrace calls:

1039 #ifdef PTRACE_SINGLESTEP
1040         case PTRACE_SINGLESTEP:
1041 #endif
1042 #ifdef PTRACE_SINGLEBLOCK
1043         case PTRACE_SINGLEBLOCK:
1044 #endif
1045 #ifdef PTRACE_SYSEMU
1046         case PTRACE_SYSEMU:
1047         case PTRACE_SYSEMU_SINGLESTEP:
1048 #endif
1049         case PTRACE_SYSCALL:
1050         case PTRACE_CONT:
1051                 return ptrace_resume(child, request, data);

手册页包含一些信息: http://man7. org/linux/man-pages/man2/ptrace.2.html

And man page has some info: http://man7.org/linux/man-pages/man2/ptrace.2.html

PTRACE_SYSEMU,PTRACE_SYSEMU_SINGLESTEP(从Linux 2.6.14开始) 对于PTRACE_SYSEMU,继续并停止进入下一个 系统调用,将不会执行.见 以下有关syscall-stops的文档.为了 PTRACE_SYSEMU_SINGLESTEP,执行相同操作,但如果执行,也可以单步执行 不是系统调用. 该调用由诸如User之类的程序使用 要模拟所有示踪剂的系统调用的Linux模式. data参数与PTRACE_CONT相同.加法器 参数被忽略.目前支持这些请求 仅在x86上.

PTRACE_SYSEMU, PTRACE_SYSEMU_SINGLESTEP (since Linux 2.6.14) For PTRACE_SYSEMU, continue and stop on entry to the next system call, which will not be executed. See the documentation on syscall-stops below. For PTRACE_SYSEMU_SINGLESTEP, do the same but also singlestep if not a system call. This call is used by programs like User Mode Linux that want to emulate all the tracee's system calls. The data argument is treated as for PTRACE_CONT. The addr argument is ignored. These requests are currently supported only on x86.

因此,它不是可移植的,并且仅作为x86平台上的Usermode linux(um)(作为经典PTRACE_SYSCALL的变体)使用. um测试sysemu并附带一些注释: http://lxr.free-electrons.com/source/arch/um/os-Linux/start_up.c?v=4.10#L155

So, it is not portable and used only for Usermode linux (um) on x86 platform as variant of classic PTRACE_SYSCALL. And um test for sysemu with some comments is here: http://lxr.free-electrons.com/source/arch/um/os-Linux/start_up.c?v=4.10#L155

155 __uml_setup("nosysemu", nosysemu_cmd_param,
156 "nosysemu\n"
157 "    Turns off syscall emulation patch for ptrace (SYSEMU) on.\n"
158 "    SYSEMU is a performance-patch introduced by Laurent Vivier. It changes\n"
159 "    behaviour of ptrace() and helps reducing host context switch rate.\n"
160 "    To make it working, you need a kernel patch for your host, too.\n"
161 "    See http://perso.wanadoo.fr/laurent.vivier/UML/ for further \n"
162 "    information.\n\n");
163 
164 static void __init check_sysemu(void)

评论链接已从2004年重定向到秘密站点 http://sysemu.sourceforge.net/ :

Link in comment was redirecting to secret site http://sysemu.sourceforge.net/ from 2004:

为什么?

UML使用ptrace()和PTRACE_SYSCALL来捕获系统调用.但是,通过 这样,您将无法删除真实的系统调用,而只能对其进行监视. UML, 为了避免真实的系统调用并对其进行仿真,请用替换实际的系统调用 调用getpid().此方法改为生成两个上下文切换 一.解决方案

UML uses ptrace() and PTRACE_SYSCALL to catch system calls. But, by this way, you can't remove the real system call, only monitor it. UML, to avoid the real syscall and emulate it, replaces the real syscall by a call to getpid(). This method generates two context-switches instead of one. A Solution

一个解决方案是将ptrace()的行为更改为不调用实数 syscall,因此我们不必将其替换为对getpid()的调用. 怎么样?

A solution is to change the behaviour of ptrace() to not call the real syscall and thus we don't have to replace it by a call to getpid(). How ?

通过向ptrace()添加新命令PTRACE_SYSEMU,其行为类似于 PTRACE_SYSCALL,而无需执行系统调用.要添加此命令,我们需要 修补主机内核.要在UML内核中使用此新命令,我们 也需要修补UML内核.

By adding a new command to ptrace(), PTRACE_SYSEMU, that acts like PTRACE_SYSCALL without executing syscall. To add this command we need to patch the host kernel. To use this new command in UML kernel, we need to patch the UML kernel too.

这篇关于关于使用PTRACE_SYSEMU的任何好的指南?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆