在 Linux 中,在进入 sys 调用时,%eax 中的值是多少? (不是 orig_eax)
当系统调用返回时,我在 %eax 中得到系统调用返回值,但是在输入时我得到 -38,即十六进制的 0xFFFFFFDA。这适用于写/读。这个数字是多少?它可以用来安全地区分入口和出口吗?
When a syscall returns, I get the syscall return value in %eax, however on entry I am getting -38, which is 0xFFFFFFDA in hex. This is for both write/read. What is this number? Can it be used to safely differentiate an entry from an exit?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
系统调用条目上的 eax 中的 -38 显然是 ENOSYS(未实现函数),并由 arch/x86/kernel/entry_32.S 中的 syscall_trace_entry 放置在那里。我想可以安全地假设它总是出现在系统调用入口处,但是它也可以出现在系统调用退出处(如果系统调用返回 ENOSYS)。
就我个人而言,尽管我也看到过一些依赖于 ENOSYS 的代码,但在使用 ptrace 时,我一直只是跟踪系统调用进入还是退出。 (我假设你正在使用 ptrace)我想如果当你附加到它时该进程恰好位于系统调用内部,那么这将不起作用,但我很幸运没有遇到这个问题。
我快速浏览了 strace 源,我猜它也会跟踪状态,因为有一条评论说“我们正在附加到一个已经运行的进程。尝试找出系统调用中进程的状态,以处理第一个活动顺利。”稍后它说“该进程在系统调用过程中处于休眠状态。伪造系统调用进入事件。”。
简而言之,该值不能安全地用于区分进入和退出。也就是说,我不确定手动跟踪它是最好的方法,因为我没有真正得到任何来源肯定会告诉您使用该技术,抱歉。 :)
The -38 in eax on syscall entry is apparently ENOSYS (Function not implemented), and is put there by syscall_trace_entry in arch/x86/kernel/entry_32.S. I suppose it's safe to assume that it will always be there on syscall entry, however it can also be there on syscall exit, if the syscall returns ENOSYS.
Personally, I have always just kept track of whether I'm in syscall entry or exit when using ptrace, although I have seen some code relying on the ENOSYS too. (I'm assuming you're using ptrace) I guess that won't work if the process happens to be inside a syscall when you attach to it, but I have been lucky enough to not bump into that problem.
I took a quick look at strace sources, and I guess it keeps track of the state too, since there was a comment saying "We are attaching to an already running process. Try to figure out the state of the process in syscalls, to handle the first event well." and slightly after that it said "The process is asleep in the middle of a syscall. Fake the syscall entry event.".
In short, the value can't be safely used to differentiate an entry from an exit. That said, I'm not sure that tracking it manually is the best method, since I haven't really got any source which would definitely tell you to use that technique, sorry. :)
当你在 eax 中得到 -38 时,我仍然不明白,但是当执行系统调用时,eax 包含一个定义系统调用的数字(在 2.6 内核中,你可以查看 arch/x86/include/asm/unistd_64.h 来查看每次呼叫的号码)。
所以顺序如下:
也许你的问题不是这么表述的,但如果你是不编写内核代码/驱动程序,判断您是在系统调用进入之前还是在系统调用退出之后的最简单方法是:当您在代码中时为 TRUE ;-)。进入/退出本身(或多或少)在一条指令中即时发生,因此要么您在系统调用中(然后您就会知道,因为它必须是某些内核代码或阻塞调用),要么您不在系统调用中(几乎每次调试时)你的代码)。
I still not get when you get the -38 in eax, but when doing a syscall eax contains a number that defines the syscall (in a 2.6 Kernel you can have a look at arch/x86/include/asm/unistd_64.h to see the numbers for each call).
So the sequence is the following:
Maybe your question is not so formulated, but if you are not writing kernel code/driver the easiest way to tell, wether you are before syscall entry or after syscall exit is: TRUE when you are in your code ;-). The entry/exit itself happen (more or less) instant in one instruction, so either you are in the syscall (then you would know because it must be some kernel code or the blocking call) or you are not (almost everytime when you debug your code).