/* * This patches CoreGraphics to fix the libtiff buffer overflow. * * If run with no arguments, it will look for CoreGraphics in its default location. When * run with an argument, it will patch that file. (For use outside of the touch.) * * This assumes a little endian platform - it won't work on the PPC, sorry. * * The C code was adapted from a springboard patch I found on pastebin. * * The code changes are summarized below.cp * < 307ea47c e1d430b2 ldrh r3, [r4, #2] < 307ea480 e2433001 sub r3, r3, #0x1 < 307ea484 e3530007 cmp r3, #0x7 < 307ea488 908ff103 addls pc, pc, r3, lsl #2 < 307ea48c eafffe52 b 0x307e9ddc < 307ea490 ea000006 b 0x307ea4b0 < 307ea494 eafffe50 b 0x307e9ddc < 307ea498 ea000050 b 0x307ea5e0 < 307ea49c eafffe4e b 0x307e9ddc < 307ea4a0 eafffe4d b 0x307e9ddc < 307ea4a4 ea000001 b 0x307ea4b0 < 307ea4a8 eafffe4b b 0x307e9ddc < 307ea4ac ea00004b b 0x307ea5e0 --- > 307ea47c e5943004 ldr r3, [r4, #4] > 307ea480 e3530002 cmp r3, #0x2 > 307ea484 cafffdf8 bgt 0x307e9c6c > 307ea488 e1d430b2 ldrh r3, [r4, #2] > 307ea48c e3530001 cmp r3, #0x1 > 307ea490 0a000006 beq 0x307ea4b0 > 307ea494 e3530006 cmp r3, #0x6 > 307ea498 0a000004 beq 0x307ea4b0 > 307ea49c e3530003 cmp r3, #0x3 > 307ea4a0 0a00004e beq 0x307ea5e0 > 307ea4a4 e3530008 cmp r3, #0x8 > 307ea4a8 0a00004c beq 0x307ea5e0 > 307ea4ac eafffe4a b 0x307e9ddc * */ #include #include #include #include #include #include #include #include #define MS_SIZE 3291960 #define MS_FILE "/System/Library/Frameworks/CoreGraphics.framework/CoreGraphics" struct Patch { unsigned int offset; unsigned int old; unsigned int new; }; struct Patch patches[] = { {0x001f747c, 0xe1d430b2, 0xe5943004}, {0x001f7480, 0xe2433001, 0xe3530002}, {0x001f7484, 0xe3530007, 0xcafffdf8}, {0x001f7488, 0x908ff103, 0xe1d430b2}, {0x001f748c, 0xeafffe52, 0xe3530001}, {0x001f7490, 0xea000006, 0x0a000006}, {0x001f7494, 0xeafffe50, 0xe3530006}, {0x001f7498, 0xea000050, 0x0a000004}, {0x001f749c, 0xeafffe4e, 0xe3530003}, {0x001f74a0, 0xeafffe4d, 0x0a00004e}, {0x001f74a4, 0xea000001, 0xe3530008}, {0x001f74a8, 0xeafffe4b, 0x0a00004c}, {0x001f74ac, 0xea00004b, 0xeafffe4a}, { 0, 0, 0 } }; void checkError(int rval, const char* format, ...) { if (rval) return; va_list args; va_start(args, format); vfprintf(stderr, format, args); va_end(args); exit(-1); } int main(int argc, char **argv) { unsigned int *DATA; FILE *fd; struct stat s; char *filename = MS_FILE; if (argc > 1) { filename = argv[1]; } int len = strlen(filename); char *backupName = malloc(len+5); strcpy(backupName, filename); strcpy(backupName+len,".bak"); char *newName = malloc(len+5); strcpy(newName, filename); strcpy(newName+len,".new"); fprintf(stdout,"Patching %s to %s\n", filename, newName); checkError(stat(filename, &s)==0, "Could not stat file '%s': %s\n", filename, strerror(errno)); checkError(s.st_size == MS_SIZE, "%s: file size mismatch: %d; expecting %d\n", filename, (int)s.st_size, (int)MS_SIZE); fd = fopen(filename, "rb"); checkError(fd != NULL, "Could not open '%s' for reading: %s\n", filename, strerror(errno)); DATA = malloc(MS_SIZE+1); checkError(DATA != NULL,"Couldn't allocation %d bytes of memory\n", (int)MS_SIZE); fread(DATA, MS_SIZE, 1, fd); fclose(fd); struct Patch *patch = patches; while (patch->offset) { fprintf(stderr,"Patch %08x: %08x -> %08x\n", (int)patch->offset, (int)patch->old, (int)patch->new); int offset = patch->offset / 4; unsigned int old = DATA[offset]; if (old != patch->old) { fprintf(stderr, "Mismatch at %08x: got %08x instead of %08x\n", (int)patch->offset, (int)DATA[offset], (int)patch->old); exit(-1); } DATA[offset] = patch->new; patch++; } fprintf(stderr, "Writing %s\n",newName); fd = fopen(newName, "wb"); checkError(fd != NULL, "Could not open '%s' for writing: %s\n", newName, strerror(errno)); checkError(fwrite(DATA, MS_SIZE, 1, fd) == 1, "Write to %s failed\n", newName); fclose(fd); fprintf(stderr, "Renaming files\n"); //checkError(link(filename,backupName), "Can't link %s to %s\n", filename, backupName); checkError(unlink(filename) == 0, "Can't unlink %s\n",filename); checkError(link(newName,filename) == 0, "Can't link %s to %s\n", newName, filename); checkError(unlink(newName) == 0, "Can't unlink %s\n", newName); return 0; }