-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathsyscall.c
134 lines (115 loc) · 3.13 KB
/
syscall.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#if defined(__linux__) || defined(__APPLE__)
/* this code will be compiled on linux and macos.
* specific differences are highlighted below. */
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#if defined(__linux__)
# include <asm/unistd.h>
# define SYSCALL_MASK 0x0
#elif defined(__APPLE__) && (defined(__x86_64__) || defined(__i386__))
# include <sys/syscall.h>
# define SYSCALL_MASK 0x02000000
#elif defined(__APPLE__) && defined(__aarch64__)
# include <sys/syscall.h>
# define SYSCALL_MASK 0x0
#endif
pid_t getpid_syscall(void)
{
pid_t res;
asm volatile (
/* this test for 32 bit architecture is a bit brittle... */
#if defined(__i386__)
// 32 bit version:
"int $0x80"
: "=a"(res)
/* TODO: replace 0x0000 below with the syscall number
* or a symbolic constant. */
: "0"(SYSCALL_MASK | 0x0000)
#elif defined(__x86_64__)
// 64 bit version:
"syscall"
: "=a"(res)
/* TODO: replace 0x0000 below with the syscall number
* or a symbolic constant. */
: "0"(SYSCALL_MASK | 0x0000)
: "rcx", "r11"
#elif defined(__ARM_ARCH_6__)
// found on Raspberry Pi 32bit Raspberry OS compatibility mode
"mov r7,%1\n\t"
"swi #0x00\n\t"
"mov %0, r0"
: "=r"(res)
/* TODO: replace 0x0000 below with the syscall number
* or a symbolic constant. */
: "0"(SYSCALL_MASK | 0x0000)
#elif defined(__aarch64__)
// found on APPLES M1 (and probably M2, other successors on ARM based)
// architecture (no matter if linux or apple system)
"mov x16,%1\n"
"svc #0x00\n"
"mov %w0, w0"
: "=r"(res)
/* TODO: replace 0x0000 below with the syscall number
* or a symbolic constant. */
: "0"(SYSCALL_MASK | 0x0000)
#else
#error Unsupported Architecture. Send a PR to add support!
#endif
);
if (res <= 0) {
errno = -res;
}
return res;
}
#elif defined(_WIN32)
/* this code will be compiled on windows */
#define _CRT_NONSTDC_NO_DEPRECATE
#include <stdio.h>
#include <errno.h>
#include <windows.h>
#include <winternl.h>
#include <conio.h>
#include <process.h>
/* we define a pid integer to be of DWORD size */
typedef DWORD pid_t;
/* declare the function that is defined in assembly in syscall_.asm */
extern NTSTATUS CallNtQueryInformationProcess(
IN HANDLE ProcessHandle,
IN PROCESSINFOCLASS ProcessInformationClass,
OUT PVOID ProcessInformation,
IN ULONG ProcessInformationLength,
OUT PULONG ReturnLength);
/* Wrapper function, so we can use a common interface down in the main function. */
pid_t getpid_syscall(void)
{
PROCESS_BASIC_INFORMATION pbi;
ULONG insize = sizeof(pbi);
ULONG outsize = 0;
int res = CallNtQueryInformationProcess(
GetCurrentProcess(),
ProcessBasicInformation,
&pbi,
insize,
&outsize
);
return pbi.UniqueProcessId;
}
#else
#error Unsupported OS. Send a PR to add support!
#endif
int main(void)
{
/* produce user mode API pid */
pid_t pid_getpid = getpid();
/* produce syscall API pid */
pid_t pid_syscall = getpid_syscall();
/* error handling is always useful */
if (pid_syscall <= 0) {
perror("getpid_syscall");
return 1;
}
/* print both and exit */
printf("%d\n%d\n", pid_getpid, pid_syscall);
return 0;
}