如何查找程序使用哪种类型的系统调用

发布于 2024-08-31 06:27:47 字数 286 浏览 12 评论 0原文

我正在 x86_64 机器上工作。我的linux内核也是64位内核。由于实现系统调用有不同的方法(int 80、syscall、sysenter),我想知道我的机器正在使用什么类型的系统调用。我是linux新手。我写了一个演示程序。

#include <stdio.h>
int main()
{
  getpid();
  return 0;
}

getpid() 执行一个系统调用。任何人都可以给我一个方法来查找我的机器将使用哪种类型的系统调用来执行此程序..谢谢....

I am working on x86_64 machine. My linux kernel is also 64 bit kernel. As there are different ways to implement a system call (int 80, syscall, sysenter), i wanted to know what type of system call my machine is using. I am newbie to linux. I have written a demo program.

#include <stdio.h>
int main()
{
  getpid();
  return 0;
}

getpid() does one system call. Can anybody give me a method to find which type of system call will be used by my machine for this program.. Thank you....

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

别理我 2024-09-07 06:27:47
victory:~ # gcc getpid.c -o getpid -g
victory:~ # gdb getpid
<snip>
(gdb) break main
Breakpoint 1 at 0x400540: file getpid.c, line 4.
(gdb) run
Starting program: /root/getpid 

Breakpoint 1, main () at getpid.c:4
4     getpid();
(gdb) disassemble
Dump of assembler code for function main:
0x000000000040053c <main+0>:    push   %rbp
0x000000000040053d <main+1>:    mov    %rsp,%rbp
0x0000000000400540 <main+4>:    mov    $0x0,%eax
0x0000000000400545 <main+9>:    callq  0x400440 <getpid@plt>
0x000000000040054a <main+14>:   mov    $0x0,%eax
0x000000000040054f <main+19>:   leaveq 
0x0000000000400550 <main+20>:   retq   
End of assembler dump.

看起来我们对 getpid() 的调用实际上是一个库调用。让我们在那里设置一个断点并继续。

(gdb) break getpid
Breakpoint 2 at 0x7ffff7b29c00
(gdb) cont
Continuing.

Breakpoint 2, 0x00007ffff7b29c00 in getpid () from /lib64/libc.so.6
(gdb) disassemble
Dump of assembler code for function getpid:
0x00007ffff7b29c00 <getpid+0>:  mov    %fs:0x94,%edx
0x00007ffff7b29c08 <getpid+8>:  cmp    $0x0,%edx
0x00007ffff7b29c0b <getpid+11>: mov    %edx,%eax
0x00007ffff7b29c0d <getpid+13>: jle    0x7ffff7b29c11 <getpid+17>
0x00007ffff7b29c0f <getpid+15>: repz retq 
0x00007ffff7b29c11 <getpid+17>: jne    0x7ffff7b29c1f <getpid+31>
0x00007ffff7b29c13 <getpid+19>: mov    %fs:0x90,%eax
0x00007ffff7b29c1b <getpid+27>: test   %eax,%eax
0x00007ffff7b29c1d <getpid+29>: jne    0x7ffff7b29c0f <getpid+15>
0x00007ffff7b29c1f <getpid+31>: mov    $0x27,%eax
0x00007ffff7b29c24 <getpid+36>: syscall 
0x00007ffff7b29c26 <getpid+38>: test   %edx,%edx
0x00007ffff7b29c28 <getpid+40>: mov    %rax,%rsi
0x00007ffff7b29c2b <getpid+43>: jne    0x7ffff7b29c0f <getpid+15>
0x00007ffff7b29c2d <getpid+45>: mov    %esi,%fs:0x90
0x00007ffff7b29c35 <getpid+53>: mov    %esi,%eax
0x00007ffff7b29c37 <getpid+55>: retq   
End of assembler dump.

getpid() 库中隐藏的是系统调用汇编指令。这是一条 AMD64 指令,支持快速上下文切换到ring0以进行系统调用。

victory:~ # gcc getpid.c -o getpid -g
victory:~ # gdb getpid
<snip>
(gdb) break main
Breakpoint 1 at 0x400540: file getpid.c, line 4.
(gdb) run
Starting program: /root/getpid 

Breakpoint 1, main () at getpid.c:4
4     getpid();
(gdb) disassemble
Dump of assembler code for function main:
0x000000000040053c <main+0>:    push   %rbp
0x000000000040053d <main+1>:    mov    %rsp,%rbp
0x0000000000400540 <main+4>:    mov    $0x0,%eax
0x0000000000400545 <main+9>:    callq  0x400440 <getpid@plt>
0x000000000040054a <main+14>:   mov    $0x0,%eax
0x000000000040054f <main+19>:   leaveq 
0x0000000000400550 <main+20>:   retq   
End of assembler dump.

Looks like our call to getpid() is actually a library call. Let's set a breakpoint there and continue.

(gdb) break getpid
Breakpoint 2 at 0x7ffff7b29c00
(gdb) cont
Continuing.

Breakpoint 2, 0x00007ffff7b29c00 in getpid () from /lib64/libc.so.6
(gdb) disassemble
Dump of assembler code for function getpid:
0x00007ffff7b29c00 <getpid+0>:  mov    %fs:0x94,%edx
0x00007ffff7b29c08 <getpid+8>:  cmp    $0x0,%edx
0x00007ffff7b29c0b <getpid+11>: mov    %edx,%eax
0x00007ffff7b29c0d <getpid+13>: jle    0x7ffff7b29c11 <getpid+17>
0x00007ffff7b29c0f <getpid+15>: repz retq 
0x00007ffff7b29c11 <getpid+17>: jne    0x7ffff7b29c1f <getpid+31>
0x00007ffff7b29c13 <getpid+19>: mov    %fs:0x90,%eax
0x00007ffff7b29c1b <getpid+27>: test   %eax,%eax
0x00007ffff7b29c1d <getpid+29>: jne    0x7ffff7b29c0f <getpid+15>
0x00007ffff7b29c1f <getpid+31>: mov    $0x27,%eax
0x00007ffff7b29c24 <getpid+36>: syscall 
0x00007ffff7b29c26 <getpid+38>: test   %edx,%edx
0x00007ffff7b29c28 <getpid+40>: mov    %rax,%rsi
0x00007ffff7b29c2b <getpid+43>: jne    0x7ffff7b29c0f <getpid+15>
0x00007ffff7b29c2d <getpid+45>: mov    %esi,%fs:0x90
0x00007ffff7b29c35 <getpid+53>: mov    %esi,%eax
0x00007ffff7b29c37 <getpid+55>: retq   
End of assembler dump.

Buried in the getpid() library is the syscall assembler instruction. This is an AMD64 instruction that supports a fast context switch to ring0 for the purpose of system calls.

垂暮老矣 2024-09-07 06:27:47

在linux下,可以使用strace来记录特定进程进行了哪些系统调用。

Under linux, you can use strace to record which system calls are made by a particular process.

独﹏钓一江月 2024-09-07 06:27:47

一种方法是使用 gdb 逐步执行机器代码(使用 stepi),直到找到启动系统调用的指令。因为不同的机器将指令放在不同的位置(有时在系统调用包装器本身中,有时在系统调用包装器调用的函数中),所以我无法预测指令的确切位置。

例如,在一台旧机器上,getpid 本身执行了 int 0x80,而在一台较新的机器上,getpid 执行了 call *gs :0x10 将其带到 __kernel_vsyscall 执行 sysenter

One way is to use the gdb to step through the machine code (using stepi) until you get to the instruction that initiates the system call. Because different machines put the instruction in different places (sometimes in the system call wrapper itself and sometimes in a function called by the system call wrapper), I can't predict where exactly the instruction will be.

For example, on one old machine, getpid itself did a int 0x80 while in a newer machine, getpid does a call *gs:0x10 which brings it to __kernel_vsyscall which does a sysenter

月亮邮递员 2024-09-07 06:27:47

我为此创建了一个基于 strace 的简单工具。
它完全按照您的要求执行:

ubuntu@pc:~$ ./syscalls whoami
ubuntu
The following syscalls were called:
access
arch_prctl
brk
close
connect
execve
exit_group
fstat
geteuid
lseek
mmap
mprotect
munmap
open
read
socket
write
The syscalls were saved to /home/ubuntu/syscalls.txt

https://github.com/avilum/syscalls

I created a simple tool for that, based on strace.
It performs exactly what you asked for:

ubuntu@pc:~$ ./syscalls whoami
ubuntu
The following syscalls were called:
access
arch_prctl
brk
close
connect
execve
exit_group
fstat
geteuid
lseek
mmap
mprotect
munmap
open
read
socket
write
The syscalls were saved to /home/ubuntu/syscalls.txt

https://github.com/avilum/syscalls

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文