Skip to content

Instantly share code, notes, and snippets.

@tbodt
Created May 4, 2019 18:16
Show Gist options
  • Save tbodt/372b95eb66d16ef047018dd1ec4a680b to your computer and use it in GitHub Desktop.
Save tbodt/372b95eb66d16ef047018dd1ec4a680b to your computer and use it in GitHub Desktop.
jit
//
// AppDelegate.m
// ptrace test
//
// Created by Theodore Dubois on 2/1/19.
// Copyright © 2019 Theodore Dubois. All rights reserved.
//
#import "AppDelegate.h"
#include <sys/mman.h>
#include "ptrace.h"
@import Darwin.Mach.mach_init;
@import Darwin.Mach.vm_types;
@import Darwin.Mach.vm_prot;
@import Darwin.Mach.vm_inherit;
/* Routine mach_vm_remap */
#ifdef mig_external
mig_external
#else
extern
#endif /* mig_external */
kern_return_t mach_vm_remap
(
vm_map_t target_task,
mach_vm_address_t *target_address,
mach_vm_size_t size,
mach_vm_offset_t mask,
int flags,
vm_map_t src_task,
mach_vm_address_t src_address,
boolean_t copy,
vm_prot_t *cur_protection,
vm_prot_t *max_protection,
vm_inherit_t inheritance
);
/* Routine mach_vm_protect */
#ifdef mig_external
mig_external
#else
extern
#endif /* mig_external */
kern_return_t mach_vm_protect
(
vm_map_t target_task,
mach_vm_address_t address,
mach_vm_size_t size,
boolean_t set_maximum,
vm_prot_t new_protection
);
@interface AppDelegate ()
@end
@implementation AppDelegate
char *code;
char *code_exec;
void cacheflush(void *a) {
asm volatile("dc cvau, %0\n"
"dsb ish\n"
"ic ivau, %0\n"
"dsb ish\n"
"isb" : : "r" (a));
}
void gimme_code() {
const char *code_file = [NSFileManager.defaultManager.temporaryDirectory URLByAppendingPathComponent:@"code"].fileSystemRepresentation;
int code_fd = open(code_file, O_CREAT|O_RDWR);
NSLog(@"open: %s", strerror(errno));
ftruncate(code_fd, 0x4000);
NSLog(@"truncate: %s", strerror(errno));
code_exec = mmap(NULL, 0x4000, PROT_READ|PROT_EXEC, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
NSLog(@"map exec: %s", strerror(errno));
close(code_fd);
code = mmap(NULL, 0x4000, PROT_READ|PROT_EXEC, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
munmap(code, 0x4000);
mach_vm_address_t target = code;
vm_prot_t cur, max;
kern_return_t err = mach_vm_remap(mach_task_self(), &target, 0x4000, 0, 0, mach_task_self(), code_exec, FALSE, &cur, &max, VM_INHERIT_SHARE);
NSLog(@"remap exec: %d", err);
code = target;
mprotect(code, 0x4000, PROT_READ|PROT_WRITE);
NSLog(@"mprotect write: %s", strerror(errno));
*code = 1;
NSLog(@"%d", code_exec[0]);
memcpy(code, "\x00\x02\x80\x52\xc0\x03\x5f\xd6\x00\x00\xa0\xe1", 12);
cacheflush(code);
cacheflush(code_exec);
NSLog(@"code returned %d", ((int (*)(void)) code_exec)());
}
void run_it(char *code) {
errno = 0;
mprotect(code, 0x1000, PROT_READ|PROT_EXEC);
NSLog(@"mprotect exec: %s", strerror(errno));
NSLog(@"code returned %d", ((int (*)(void)) code)());
errno = 0;
mprotect(code, 0x1000, PROT_WRITE|PROT_EXEC);
NSLog(@"mprotect write: %s", strerror(errno));
}
void test_exec() {
char *code = mmap(NULL, 0x1000, PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
memcpy(code, "\x00\x02\x80\x52\xc0\x03\x5f\xd6", 8);
run_it(code);
code[1] = 0;
run_it(code);
munmap(code, 0x1000);
}
void sigusr1_handler() {
NSLog(@"received sigusr1");
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
errno = 0;
ptrace(PT_TRACE_ME, 0, 0, 0);
NSLog(@"traceme: %s", strerror(errno));
ptrace(PT_SIGEXC, 0, 0, 0);
NSLog(@"sigexc: %s", strerror(errno));
gimme_code();
test_exec();
signal(SIGUSR1, sigusr1_handler);
NSLog(@"sending sigusr1");
kill(getpid(), SIGUSR1);
NSLog(@"still alive");
test_exec();
NSLog(@"exiting");
exit(0);
return YES;
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment