1 #include <TargetConditionals.h>
8 #if __has_include(<ptrauth.h>)
13 #include <sys/syslimits.h>
30 while ((ch
= getopt(argc
, argv
, "i")) != -1) {
39 "\t-i: interactive\n",
45 page_size
= getpagesize();
46 page
= mmap(NULL
, page_size
, PROT_READ
| PROT_EXEC
, MAP_ANON
| MAP_SHARED
, -1, 0);
48 fprintf(stderr
, "%s:%d mmap() error %d (%s)\n",
50 errno
, strerror(errno
));
53 if (opt_interactive
) {
54 fprintf(stdout
, "allocated page at %p\n",
58 if (mprotect(page
, page_size
, PROT_READ
| PROT_WRITE
) != 0) {
59 fprintf(stderr
, "%s:%d mprotect(RW) error %d (%s)\n",
61 errno
, strerror(errno
));
66 // arm64 chdir() syscall
68 0x90, 0x01, 0x80, 0xd2, // movz x16, #0xc
69 0x01, 0x10, 0x00, 0xd4, // svc #0x80
70 0xc0, 0x03, 0x5f, 0xd6, // ret
73 // armv7 chdir() syscall
75 0x0c, 0xc0, 0xa0, 0xe3, // mov r12 #0xc
76 0x80, 0x00, 0x00, 0xef, // svc #0x80
77 0x1e, 0xff, 0x2f, 0xe1, // bx lr
80 // x86_64 chdir() syscall
82 0xb8, 0x0c, 0x00, 0x00, 0x02, // movl $0x200000c, %eax
83 0x49, 0x89, 0xca, // movq %rcx, %r10
84 0x0f, 0x05, // syscall
88 // i386 chdir() syscall
94 memcpy(page
, chdir_code
, sizeof chdir_code
);
96 if (opt_interactive
) {
98 "changed page protection to r/w and copied code at %p\n",
100 fprintf(stdout
, "pausing...\n");
105 if (mprotect(page
, page_size
, PROT_READ
| PROT_EXEC
) != 0) {
106 fprintf(stderr
, "%s:%d mprotect(RX) error %d (%s)\n",
108 errno
, strerror(errno
));
112 if (opt_interactive
) {
114 "changed page protection to r/x at %p\n",
116 fprintf(stdout
, "pausing...\n");
121 char origdir
[PATH_MAX
];
122 getcwd(origdir
, sizeof(origdir
) - 1);
125 if (opt_interactive
) {
126 fprintf(stdout
, "cwd before = %s\n", getwd(NULL
));
129 void (*mychdir
)(char *) = page
;
130 #if __has_feature(ptrauth_calls)
131 mychdir
= ptrauth_sign_unauthenticated(mychdir
, ptrauth_key_function_pointer
, 0);
133 mychdir(getenv("HOME"));
134 if (opt_interactive
) {
135 fprintf(stdout
, "cwd after = %s\n", getwd(NULL
));
136 fprintf(stdout
, "pausing...\n");
141 fprintf(stdout
, "%s: WARNING: unsigned code was executed\n",
145 /* fail: unsigned code was executed */
146 fprintf(stdout
, "%s: FAIL\n", cmdname
);
148 #else /* !TARGET_OS_OSX */
149 /* no fail: unsigned code is only prohibited on embedded platforms */
150 fprintf(stdout
, "%s: SUCCESS\n", cmdname
);
152 #endif /* !TARGET_OS_OSX */