├── LICENSE ├── README.md ├── cache-strings ├── cache_format.h ├── macho.h ├── main.c └── meson.build ├── dsmos-dump ├── README.md ├── macho.h ├── main.c ├── meson.build └── schedule_data.h ├── foulplay ├── README.md ├── main.c └── meson.build └── kdumpd ├── .gitignore ├── LICENSE ├── Makefile ├── README.md ├── com.apple.kdumpd.plist ├── kdump.h ├── kdumpd.8 ├── kdumpd.c ├── kdumpsubs.c └── kdumpsubs.h /LICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # apple-tools 2 | 3 | A collection of tools for working with Apple software/hardware. 4 | 5 | All tools are public domain unless stated otherwise (see LICENSE in corresponding folder) 6 | 7 | * `cache-strings`: `strings` but for `dyld_cache_*`. Shows the name and location 8 | of the string in a given dyld 9 | * `foulplay`: Decrypt FairPlay encrypted binaries on macOS when SIP-enabled 10 | * `dsmos-dump`: You know what it is :-) 11 | * `kdumpd`: A port of macOS' `kdumpd` to Linux 12 | -------------------------------------------------------------------------------- /cache-strings/cache_format.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | typedef struct { 6 | char magic[16]; 7 | 8 | uint32_t mapping_offset; 9 | uint32_t mapping_count; 10 | 11 | uint32_t images_offset; 12 | uint32_t images_count; 13 | 14 | uint64_t base_address; 15 | 16 | uint64_t code_sig_offset; 17 | uint64_t code_sig_size; 18 | 19 | uint64_t slide_info_offset; 20 | uint64_t slide_info_size; 21 | } cache_header_t; 22 | 23 | typedef struct { 24 | uint64_t address; 25 | uint64_t size; 26 | uint64_t file_offset; 27 | uint32_t max_prot; 28 | uint32_t init_prot; 29 | } cache_mapping_t; 30 | 31 | typedef struct { 32 | uint64_t address; 33 | uint64_t mod_time; 34 | uint64_t inode; 35 | uint32_t path_offset; 36 | uint32_t unused; 37 | } cache_image_t; 38 | 39 | -------------------------------------------------------------------------------- /cache-strings/macho.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | /* mach/machine.h */ 6 | typedef int cpu_type_t; 7 | typedef int cpu_subtype_t; 8 | 9 | #define CPU_ARCH_ABI64 0x01000000 10 | #define CPU_TYPE_X86 ((cpu_type_t) 7) 11 | #define CPU_TYPE_X86_64 (CPU_TYPE_X86 | CPU_ARCH_ABI64) 12 | #define CPU_SUBTYPE_X86_64_ALL ((cpu_subtype_t)3) 13 | 14 | 15 | /* mach/vm_prot.h */ 16 | 17 | /* 18 | * Types defined: 19 | * 20 | * vm_prot_t VM protection values. 21 | */ 22 | 23 | typedef int vm_prot_t; 24 | 25 | /* 26 | * Protection values, defined as bits within the vm_prot_t type 27 | */ 28 | 29 | #define VM_PROT_NONE ((vm_prot_t) 0x00) 30 | 31 | #define VM_PROT_READ ((vm_prot_t) 0x01) /* read permission */ 32 | #define VM_PROT_WRITE ((vm_prot_t) 0x02) /* write permission */ 33 | #define VM_PROT_EXECUTE ((vm_prot_t) 0x04) /* execute permission */ 34 | 35 | /* 36 | * The default protection for newly-created virtual memory 37 | */ 38 | 39 | #define VM_PROT_DEFAULT (VM_PROT_READ|VM_PROT_WRITE) 40 | 41 | /* 42 | * The maximum privileges possible, for parameter checking. 43 | */ 44 | 45 | #define VM_PROT_ALL (VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE) 46 | 47 | /* 48 | * An invalid protection value. 49 | * Used only by memory_object_lock_request to indicate no change 50 | * to page locks. Using -1 here is a bad idea because it 51 | * looks like VM_PROT_ALL and then some. 52 | */ 53 | 54 | #define VM_PROT_NO_CHANGE ((vm_prot_t) 0x08) 55 | 56 | /* 57 | * When a caller finds that he cannot obtain write permission on a 58 | * mapped entry, the following flag can be used. The entry will 59 | * be made "needs copy" effectively copying the object (using COW), 60 | * and write permission will be added to the maximum protections 61 | * for the associated entry. 62 | */ 63 | 64 | #define VM_PROT_COPY ((vm_prot_t) 0x10) 65 | 66 | 67 | /* 68 | * Another invalid protection value. 69 | * Used only by memory_object_data_request upon an object 70 | * which has specified a copy_call copy strategy. It is used 71 | * when the kernel wants a page belonging to a copy of the 72 | * object, and is only asking the object as a result of 73 | * following a shadow chain. This solves the race between pages 74 | * being pushed up by the memory manager and the kernel 75 | * walking down the shadow chain. 76 | */ 77 | 78 | #define VM_PROT_WANTS_COPY ((vm_prot_t) 0x10) 79 | 80 | 81 | /* mach-o/loader.h */ 82 | 83 | #define MH_MAGIC_64 0xfeedfacf /* the 64-bit mach magic number */ 84 | #define MH_CIGAM_64 0xcffaedfe 85 | 86 | struct mach_header_64 { 87 | uint32_t magic; /* mach magic number identifier */ 88 | cpu_type_t cputype; /* cpu specifier */ 89 | cpu_subtype_t cpusubtype; /* machine specifier */ 90 | uint32_t filetype; /* type of file */ 91 | uint32_t ncmds; /* number of load commands */ 92 | uint32_t sizeofcmds; /* the size of all the load commands */ 93 | uint32_t flags; /* flags */ 94 | uint32_t reserved; /* reserved */ 95 | }; 96 | 97 | struct load_command { 98 | uint32_t cmd; /* type of load command */ 99 | uint32_t cmdsize; /* total size of command in bytes */ 100 | }; 101 | 102 | #define MH_EXECUTE 0x2 /* demand paged executable file */ 103 | #define MH_DYLINKER 0x7 104 | 105 | #define LC_REQ_DYLD 0x80000000 106 | 107 | /* Constants for the cmd field of all load commands, the type */ 108 | #define LC_SEGMENT 0x1 /* segment of this file to be mapped */ 109 | #define LC_SYMTAB 0x2 /* link-edit stab symbol table info */ 110 | #define LC_SYMSEG 0x3 /* link-edit gdb symbol table info (obsolete) */ 111 | #define LC_THREAD 0x4 /* thread */ 112 | #define LC_UNIXTHREAD 0x5 /* unix thread (includes a stack) */ 113 | #define LC_LOADFVMLIB 0x6 /* load a specified fixed VM shared library */ 114 | #define LC_IDFVMLIB 0x7 /* fixed VM shared library identification */ 115 | #define LC_IDENT 0x8 /* object identification info (obsolete) */ 116 | #define LC_FVMFILE 0x9 /* fixed VM file inclusion (internal use) */ 117 | #define LC_PREPAGE 0xa /* prepage command (internal use) */ 118 | #define LC_DYSYMTAB 0xb /* dynamic link-edit symbol table info */ 119 | #define LC_LOAD_DYLIB 0xc /* load a dynamically linked shared library */ 120 | #define LC_ID_DYLIB 0xd /* dynamically linked shared lib ident */ 121 | #define LC_LOAD_DYLINKER 0xe /* load a dynamic linker */ 122 | #define LC_ID_DYLINKER 0xf /* dynamic linker identification */ 123 | #define LC_PREBOUND_DYLIB 0x10 /* modules prebound for a dynamically */ 124 | /* linked shared library */ 125 | #define LC_ROUTINES 0x11 /* image routines */ 126 | #define LC_SUB_FRAMEWORK 0x12 /* sub framework */ 127 | #define LC_SUB_UMBRELLA 0x13 /* sub umbrella */ 128 | #define LC_SUB_CLIENT 0x14 /* sub client */ 129 | #define LC_SUB_LIBRARY 0x15 /* sub library */ 130 | #define LC_TWOLEVEL_HINTS 0x16 /* two-level namespace lookup hints */ 131 | #define LC_PREBIND_CKSUM 0x17 /* prebind checksum */ 132 | 133 | /* 134 | * load a dynamically linked shared library that is allowed to be missing 135 | * (all symbols are weak imported). 136 | */ 137 | #define LC_LOAD_WEAK_DYLIB (0x18 | LC_REQ_DYLD) 138 | 139 | #define LC_SEGMENT_64 0x19 /* 64-bit segment of this file to be 140 | mapped */ 141 | #define LC_ROUTINES_64 0x1a /* 64-bit image routines */ 142 | #define LC_UUID 0x1b /* the uuid */ 143 | #define LC_RPATH (0x1c | LC_REQ_DYLD) /* runpath additions */ 144 | #define LC_CODE_SIGNATURE 0x1d /* local of code signature */ 145 | #define LC_SEGMENT_SPLIT_INFO 0x1e /* local of info to split segments */ 146 | #define LC_REEXPORT_DYLIB (0x1f | LC_REQ_DYLD) /* load and re-export dylib */ 147 | #define LC_LAZY_LOAD_DYLIB 0x20 /* delay load of dylib until first use */ 148 | #define LC_ENCRYPTION_INFO 0x21 /* encrypted segment information */ 149 | #define LC_DYLD_INFO 0x22 /* compressed dyld information */ 150 | #define LC_DYLD_INFO_ONLY (0x22|LC_REQ_DYLD) /* compressed dyld information only */ 151 | 152 | /* 153 | * The 64-bit segment load command indicates that a part of this file is to be 154 | * mapped into a 64-bit task's address space. If the 64-bit segment has 155 | * sections then section_64 structures directly follow the 64-bit segment 156 | * command and their size is reflected in cmdsize. 157 | */ 158 | struct segment_command_64 { /* for 64-bit architectures */ 159 | uint32_t cmd; /* LC_SEGMENT_64 */ 160 | uint32_t cmdsize; /* includes sizeof section_64 structs */ 161 | char segname[16]; /* segment name */ 162 | uint64_t vmaddr; /* memory address of this segment */ 163 | uint64_t vmsize; /* memory size of this segment */ 164 | uint64_t fileoff; /* file offset of this segment */ 165 | uint64_t filesize; /* amount to map from the file */ 166 | vm_prot_t maxprot; /* maximum VM protection */ 167 | vm_prot_t initprot; /* initial VM protection */ 168 | uint32_t nsects; /* number of sections in segment */ 169 | uint32_t flags; /* flags */ 170 | }; 171 | 172 | struct section_64 { /* for 64-bit architectures */ 173 | char sectname[16]; /* name of this section */ 174 | char segname[16]; /* segment this section goes in */ 175 | uint64_t addr; /* memory address of this section */ 176 | uint64_t size; /* size in bytes of this section */ 177 | uint32_t offset; /* file offset of this section */ 178 | uint32_t align; /* section alignment (power of 2) */ 179 | uint32_t reloff; /* file offset of relocation entries */ 180 | uint32_t nreloc; /* number of relocation entries */ 181 | uint32_t flags; /* flags (section type and attributes)*/ 182 | uint32_t reserved1; /* reserved (for offset or index) */ 183 | uint32_t reserved2; /* reserved (for count or sizeof) */ 184 | uint32_t reserved3; /* reserved */ 185 | }; 186 | 187 | /* 188 | * A program that uses a dynamic linker contains a dylinker_command to identify 189 | * the name of the dynamic linker (LC_LOAD_DYLINKER). And a dynamic linker 190 | * contains a dylinker_command to identify the dynamic linker (LC_ID_DYLINKER). 191 | * A file can have at most one of these. 192 | * This struct is also used for the LC_DYLD_ENVIRONMENT load command and 193 | * contains string for dyld to treat like environment variable. 194 | */ 195 | struct dylinker_command { 196 | uint32_t cmd; /* LC_ID_DYLINKER, LC_LOAD_DYLINKER or 197 | LC_DYLD_ENVIRONMENT */ 198 | uint32_t cmdsize; /* includes pathname string */ 199 | uint32_t name; /* dynamic linker's path name */ 200 | }; 201 | 202 | /* Constants for the flags field of the mach_header */ 203 | #define MH_NOUNDEFS 0x1 /* the object file has no undefined 204 | references */ 205 | #define MH_INCRLINK 0x2 /* the object file is the output of an 206 | incremental link against a base file 207 | and can't be link edited again */ 208 | #define MH_DYLDLINK 0x4 /* the object file is input for the 209 | dynamic linker and can't be staticly 210 | link edited again */ 211 | #define MH_BINDATLOAD 0x8 /* the object file's undefined 212 | references are bound by the dynamic 213 | linker when loaded. */ 214 | #define MH_PREBOUND 0x10 /* the file has its dynamic undefined 215 | references prebound. */ 216 | #define MH_SPLIT_SEGS 0x20 /* the file has its read-only and 217 | read-write segments split */ 218 | #define MH_LAZY_INIT 0x40 /* the shared library init routine is 219 | to be run lazily via catching memory 220 | faults to its writeable segments 221 | (obsolete) */ 222 | #define MH_TWOLEVEL 0x80 /* the image is using two-level name 223 | space bindings */ 224 | #define MH_FORCE_FLAT 0x100 /* the executable is forcing all images 225 | to use flat name space bindings */ 226 | #define MH_NOMULTIDEFS 0x200 /* this umbrella guarantees no multiple 227 | defintions of symbols in its 228 | sub-images so the two-level namespace 229 | hints can always be used. */ 230 | #define MH_NOFIXPREBINDING 0x400 /* do not have dyld notify the 231 | prebinding agent about this 232 | executable */ 233 | #define MH_PREBINDABLE 0x800 /* the binary is not prebound but can 234 | have its prebinding redone. only used 235 | when MH_PREBOUND is not set. */ 236 | #define MH_ALLMODSBOUND 0x1000 /* indicates that this binary binds to 237 | all two-level namespace modules of 238 | its dependent libraries. only used 239 | when MH_PREBINDABLE and MH_TWOLEVEL 240 | are both set. */ 241 | #define MH_SUBSECTIONS_VIA_SYMBOLS 0x2000/* safe to divide up the sections into 242 | sub-sections via symbols for dead 243 | code stripping */ 244 | #define MH_CANONICAL 0x4000 /* the binary has been canonicalized 245 | via the unprebind operation */ 246 | #define MH_WEAK_DEFINES 0x8000 /* the final linked image contains 247 | external weak symbols */ 248 | #define MH_BINDS_TO_WEAK 0x10000 /* the final linked image uses 249 | weak symbols */ 250 | 251 | #define MH_ALLOW_STACK_EXECUTION 0x20000/* When this bit is set, all stacks 252 | in the task will be given stack 253 | execution privilege. Only used in 254 | MH_EXECUTE filetypes. */ 255 | #define MH_DEAD_STRIPPABLE_DYLIB 0x400000 /* Only for use on dylibs. When 256 | linking against a dylib that 257 | has this bit set, the static linker 258 | will automatically not create a 259 | LC_LOAD_DYLIB load command to the 260 | dylib if no symbols are being 261 | referenced from the dylib. */ 262 | #define MH_ROOT_SAFE 0x40000 /* When this bit is set, the binary 263 | declares it is safe for use in 264 | processes with uid zero */ 265 | 266 | #define MH_SETUID_SAFE 0x80000 /* When this bit is set, the binary 267 | declares it is safe for use in 268 | processes when issetugid() is true */ 269 | 270 | #define MH_NO_REEXPORTED_DYLIBS 0x100000 /* When this bit is set on a dylib, 271 | the static linker does not need to 272 | examine dependent dylibs to see 273 | if any are re-exported */ 274 | #define MH_PIE 0x200000 /* When this bit is set, the OS will 275 | load the main executable at a 276 | random address. Only used in 277 | MH_EXECUTE filetypes. */ 278 | #define SG_PROTECTED_VERSION_1 0x08 279 | 280 | /* mach-o/fat.h */ 281 | 282 | #define FAT_MAGIC 0xcafebabe 283 | #define FAT_CIGAM 0xbebafeca 284 | 285 | struct fat_header { 286 | int32_t magic; /* FAT_MAGIC */ 287 | int32_t nfat_arch; /* number of structs that follow */ 288 | }; 289 | 290 | struct fat_arch { 291 | cpu_type_t cputype; /* cpu specifier (int) */ 292 | cpu_subtype_t cpusubtype; /* machine specifier (int) */ 293 | unsigned long offset; /* file offset to this object file */ 294 | unsigned long size; /* size of this object file */ 295 | unsigned long align; /* alignment as a power of 2 */ 296 | }; 297 | 298 | /* osfmk/mach/i386/thread_status.h */ 299 | #define x86_THREAD_STATE64 4 300 | 301 | /* osfmk/mach/i386/_structs.h */ 302 | struct __darwin_x86_thread_state64 { 303 | uint64_t rax; 304 | uint64_t rbx; 305 | uint64_t rcx; 306 | uint64_t rdx; 307 | uint64_t rdi; 308 | uint64_t rsi; 309 | uint64_t rbp; 310 | uint64_t rsp; 311 | uint64_t r8; 312 | uint64_t r9; 313 | uint64_t r10; 314 | uint64_t r11; 315 | uint64_t r12; 316 | uint64_t r13; 317 | uint64_t r14; 318 | uint64_t r15; 319 | uint64_t rip; 320 | uint64_t rflags; 321 | uint64_t cs; 322 | uint64_t fs; 323 | uint64_t gs; 324 | }; 325 | 326 | /* osfmk/mach/i386/vm_param.h */ 327 | #define VM_USRSTACK64 0x00007FFEEFC00000UL 328 | 329 | 330 | /* osfmk/i386/cpu_capabilities.h */ 331 | #define _COMM_PAGE64_AREA_LENGTH ( 1 * 4096 ) /* reserved length of entire comm area (2MB) */ 332 | #ifdef __ASSEMBLER__ 333 | #define _COMM_PAGE64_BASE_ADDRESS ( 0x00007fffffe00000 ) /* base address of allocated memory */ 334 | #else /* __ASSEMBLER__ */ 335 | #define _COMM_PAGE64_BASE_ADDRESS ( 0x00007fffffe00000ULL ) /* base address of allocated memory */ 336 | #endif /* __ASSEMBLER__ */ 337 | #define _COMM_PAGE64_START_ADDRESS ( _COMM_PAGE64_BASE_ADDRESS ) /* address traditional commpage code starts on */ 338 | #define _COMM_PAGE64_AREA_USED ( 1 * 4096 ) /* this is the amt actually populated */ 339 | -------------------------------------------------------------------------------- /cache-strings/main.c: -------------------------------------------------------------------------------- 1 | #ifndef _GNU_SOURCE 2 | #define _GNU_SOURCE 3 | #endif 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #include "cache_format.h" 15 | #include "macho.h" 16 | 17 | static int 18 | segment_range(const char *path, uint64_t address, uintptr_t result) 19 | { 20 | char *base = (char*) address; 21 | struct mach_header_64 *header = (struct mach_header_64*) base; 22 | assert(header->magic == MH_MAGIC_64); 23 | 24 | uint32_t offset = sizeof(struct mach_header_64); 25 | 26 | for (uint32_t i = 0; i < header->ncmds; i++) { 27 | struct load_command *command = (struct load_command*) (base + offset); 28 | 29 | if (command->cmd == LC_SEGMENT_64) { 30 | struct segment_command_64 *segment = (struct segment_command_64*) 31 | command; 32 | 33 | uintptr_t start = segment->vmaddr; 34 | uintptr_t end = start + segment->vmsize; 35 | if (result >= start && result <= end) { 36 | printf("%s:%.*s (0x%08lx-0x%08lx)\n", path, (int) sizeof(segment->segname), 37 | segment->segname, segment->vmaddr, segment->vmaddr + segment->vmsize); 38 | return 1; 39 | } 40 | } 41 | 42 | offset += command->cmdsize; 43 | } 44 | 45 | return 0; 46 | } 47 | 48 | static void 49 | search(cache_header_t *header, cache_mapping_t *mapping, const char *needle) 50 | { 51 | char *base = (char*) mapping->address; 52 | uint32_t needle_size = strlen(needle); 53 | 54 | char *result = base; 55 | while ((result = memmem(result, mapping->size - ((uintptr_t) result - mapping->address), needle, needle_size)) != NULL) { 56 | cache_image_t *image = (cache_image_t*) ((char*) header + header->images_offset); 57 | for (uint32_t i = 0; i < header->images_count; i++) { 58 | const char *path = (char*) header + image->path_offset; 59 | // If a result was found, stop searching. 60 | // 61 | if (segment_range(path, image->address, (uintptr_t) result)) { 62 | break; 63 | } 64 | image++; 65 | } 66 | 67 | printf("\t%p:%.*s\n", result, needle_size, result); 68 | result += needle_size; 69 | } 70 | } 71 | 72 | int 73 | main(int argc, char *argv[]) 74 | { 75 | int f = 0; 76 | struct stat s; 77 | uint8_t *base = NULL; 78 | 79 | if (argc < 3) { 80 | return 1; 81 | } 82 | 83 | f = open(argv[2], O_RDONLY); 84 | if (f < 0) { 85 | perror("open"); 86 | return 1; 87 | } 88 | 89 | if (fstat(f, &s) < 0) { 90 | perror("fstat"); 91 | goto error; 92 | } 93 | 94 | base = mmap(NULL, s.st_size, PROT_READ, MAP_PRIVATE, f, 0); 95 | if (base == MAP_FAILED) { 96 | perror("mmap"); 97 | goto error; 98 | } 99 | 100 | cache_header_t *header = (cache_header_t*) base; 101 | assert(memcmp(header->magic, "dyld_v1 arm64e", sizeof(header->magic)) == 0); 102 | 103 | cache_mapping_t *mapping = (cache_mapping_t*) (base + header->mapping_offset); 104 | 105 | for (uint32_t i = 0; i < header->mapping_count; i++) { 106 | // Map each mapping into the specified address. This IS NOT SECURE. 107 | // 108 | void *cache_map = mmap((void*) mapping->address, mapping->size, PROT_READ, 109 | MAP_PRIVATE | MAP_FIXED, f, mapping->file_offset); 110 | if (cache_map == MAP_FAILED) { 111 | perror("mmap"); 112 | goto error; 113 | } 114 | 115 | search(header, mapping, argv[1]); 116 | 117 | mapping++; 118 | } 119 | 120 | // Remove all mappings. 121 | // 122 | mapping = (cache_mapping_t*) (base + header->mapping_offset); 123 | 124 | for (uint32_t i = 0; i < header->mapping_count; i++) { 125 | munmap((void*) mapping->address, mapping->size); 126 | } 127 | 128 | munmap(base, s.st_size); 129 | close(f); 130 | return 0; 131 | error: 132 | if (base) 133 | munmap(base, s.st_size); 134 | if (f) 135 | close(f); 136 | return 1; 137 | } 138 | -------------------------------------------------------------------------------- /cache-strings/meson.build: -------------------------------------------------------------------------------- 1 | project('cache-strings', 'c', 2 | version: '0.1.0', 3 | ) 4 | 5 | executable('cache-strings', 6 | sources: ['main.c'], 7 | ) 8 | -------------------------------------------------------------------------------- /dsmos-dump/README.md: -------------------------------------------------------------------------------- 1 | # dsmos-dump 2 | 3 | Program to "unprotect" macOS executables 4 | 5 | For more information: see the "Dont Steal Mac OS.kext" executable :-) 6 | -------------------------------------------------------------------------------- /dsmos-dump/macho.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | /* mach/machine.h */ 6 | typedef int cpu_type_t; 7 | typedef int cpu_subtype_t; 8 | 9 | #define CPU_ARCH_ABI64 0x01000000 10 | #define CPU_TYPE_X86 ((cpu_type_t) 7) 11 | #define CPU_TYPE_X86_64 (CPU_TYPE_X86 | CPU_ARCH_ABI64) 12 | #define CPU_SUBTYPE_X86_64_ALL ((cpu_subtype_t)3) 13 | 14 | 15 | /* mach/vm_prot.h */ 16 | 17 | /* 18 | * Types defined: 19 | * 20 | * vm_prot_t VM protection values. 21 | */ 22 | 23 | typedef int vm_prot_t; 24 | 25 | /* 26 | * Protection values, defined as bits within the vm_prot_t type 27 | */ 28 | 29 | #define VM_PROT_NONE ((vm_prot_t) 0x00) 30 | 31 | #define VM_PROT_READ ((vm_prot_t) 0x01) /* read permission */ 32 | #define VM_PROT_WRITE ((vm_prot_t) 0x02) /* write permission */ 33 | #define VM_PROT_EXECUTE ((vm_prot_t) 0x04) /* execute permission */ 34 | 35 | /* 36 | * The default protection for newly-created virtual memory 37 | */ 38 | 39 | #define VM_PROT_DEFAULT (VM_PROT_READ|VM_PROT_WRITE) 40 | 41 | /* 42 | * The maximum privileges possible, for parameter checking. 43 | */ 44 | 45 | #define VM_PROT_ALL (VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE) 46 | 47 | /* 48 | * An invalid protection value. 49 | * Used only by memory_object_lock_request to indicate no change 50 | * to page locks. Using -1 here is a bad idea because it 51 | * looks like VM_PROT_ALL and then some. 52 | */ 53 | 54 | #define VM_PROT_NO_CHANGE ((vm_prot_t) 0x08) 55 | 56 | /* 57 | * When a caller finds that he cannot obtain write permission on a 58 | * mapped entry, the following flag can be used. The entry will 59 | * be made "needs copy" effectively copying the object (using COW), 60 | * and write permission will be added to the maximum protections 61 | * for the associated entry. 62 | */ 63 | 64 | #define VM_PROT_COPY ((vm_prot_t) 0x10) 65 | 66 | 67 | /* 68 | * Another invalid protection value. 69 | * Used only by memory_object_data_request upon an object 70 | * which has specified a copy_call copy strategy. It is used 71 | * when the kernel wants a page belonging to a copy of the 72 | * object, and is only asking the object as a result of 73 | * following a shadow chain. This solves the race between pages 74 | * being pushed up by the memory manager and the kernel 75 | * walking down the shadow chain. 76 | */ 77 | 78 | #define VM_PROT_WANTS_COPY ((vm_prot_t) 0x10) 79 | 80 | 81 | /* mach-o/loader.h */ 82 | 83 | #define MH_MAGIC_64 0xfeedfacf /* the 64-bit mach magic number */ 84 | #define MH_CIGAM_64 0xcffaedfe 85 | 86 | struct mach_header_64 { 87 | uint32_t magic; /* mach magic number identifier */ 88 | cpu_type_t cputype; /* cpu specifier */ 89 | cpu_subtype_t cpusubtype; /* machine specifier */ 90 | uint32_t filetype; /* type of file */ 91 | uint32_t ncmds; /* number of load commands */ 92 | uint32_t sizeofcmds; /* the size of all the load commands */ 93 | uint32_t flags; /* flags */ 94 | uint32_t reserved; /* reserved */ 95 | }; 96 | 97 | struct load_command { 98 | uint32_t cmd; /* type of load command */ 99 | uint32_t cmdsize; /* total size of command in bytes */ 100 | }; 101 | 102 | #define MH_EXECUTE 0x2 /* demand paged executable file */ 103 | #define MH_DYLINKER 0x7 104 | 105 | #define LC_REQ_DYLD 0x80000000 106 | 107 | /* Constants for the cmd field of all load commands, the type */ 108 | #define LC_SEGMENT 0x1 /* segment of this file to be mapped */ 109 | #define LC_SYMTAB 0x2 /* link-edit stab symbol table info */ 110 | #define LC_SYMSEG 0x3 /* link-edit gdb symbol table info (obsolete) */ 111 | #define LC_THREAD 0x4 /* thread */ 112 | #define LC_UNIXTHREAD 0x5 /* unix thread (includes a stack) */ 113 | #define LC_LOADFVMLIB 0x6 /* load a specified fixed VM shared library */ 114 | #define LC_IDFVMLIB 0x7 /* fixed VM shared library identification */ 115 | #define LC_IDENT 0x8 /* object identification info (obsolete) */ 116 | #define LC_FVMFILE 0x9 /* fixed VM file inclusion (internal use) */ 117 | #define LC_PREPAGE 0xa /* prepage command (internal use) */ 118 | #define LC_DYSYMTAB 0xb /* dynamic link-edit symbol table info */ 119 | #define LC_LOAD_DYLIB 0xc /* load a dynamically linked shared library */ 120 | #define LC_ID_DYLIB 0xd /* dynamically linked shared lib ident */ 121 | #define LC_LOAD_DYLINKER 0xe /* load a dynamic linker */ 122 | #define LC_ID_DYLINKER 0xf /* dynamic linker identification */ 123 | #define LC_PREBOUND_DYLIB 0x10 /* modules prebound for a dynamically */ 124 | /* linked shared library */ 125 | #define LC_ROUTINES 0x11 /* image routines */ 126 | #define LC_SUB_FRAMEWORK 0x12 /* sub framework */ 127 | #define LC_SUB_UMBRELLA 0x13 /* sub umbrella */ 128 | #define LC_SUB_CLIENT 0x14 /* sub client */ 129 | #define LC_SUB_LIBRARY 0x15 /* sub library */ 130 | #define LC_TWOLEVEL_HINTS 0x16 /* two-level namespace lookup hints */ 131 | #define LC_PREBIND_CKSUM 0x17 /* prebind checksum */ 132 | 133 | /* 134 | * load a dynamically linked shared library that is allowed to be missing 135 | * (all symbols are weak imported). 136 | */ 137 | #define LC_LOAD_WEAK_DYLIB (0x18 | LC_REQ_DYLD) 138 | 139 | #define LC_SEGMENT_64 0x19 /* 64-bit segment of this file to be 140 | mapped */ 141 | #define LC_ROUTINES_64 0x1a /* 64-bit image routines */ 142 | #define LC_UUID 0x1b /* the uuid */ 143 | #define LC_RPATH (0x1c | LC_REQ_DYLD) /* runpath additions */ 144 | #define LC_CODE_SIGNATURE 0x1d /* local of code signature */ 145 | #define LC_SEGMENT_SPLIT_INFO 0x1e /* local of info to split segments */ 146 | #define LC_REEXPORT_DYLIB (0x1f | LC_REQ_DYLD) /* load and re-export dylib */ 147 | #define LC_LAZY_LOAD_DYLIB 0x20 /* delay load of dylib until first use */ 148 | #define LC_ENCRYPTION_INFO 0x21 /* encrypted segment information */ 149 | #define LC_DYLD_INFO 0x22 /* compressed dyld information */ 150 | #define LC_DYLD_INFO_ONLY (0x22|LC_REQ_DYLD) /* compressed dyld information only */ 151 | 152 | /* 153 | * The 64-bit segment load command indicates that a part of this file is to be 154 | * mapped into a 64-bit task's address space. If the 64-bit segment has 155 | * sections then section_64 structures directly follow the 64-bit segment 156 | * command and their size is reflected in cmdsize. 157 | */ 158 | struct segment_command_64 { /* for 64-bit architectures */ 159 | uint32_t cmd; /* LC_SEGMENT_64 */ 160 | uint32_t cmdsize; /* includes sizeof section_64 structs */ 161 | char segname[16]; /* segment name */ 162 | uint64_t vmaddr; /* memory address of this segment */ 163 | uint64_t vmsize; /* memory size of this segment */ 164 | uint64_t fileoff; /* file offset of this segment */ 165 | uint64_t filesize; /* amount to map from the file */ 166 | vm_prot_t maxprot; /* maximum VM protection */ 167 | vm_prot_t initprot; /* initial VM protection */ 168 | uint32_t nsects; /* number of sections in segment */ 169 | uint32_t flags; /* flags */ 170 | }; 171 | 172 | struct section_64 { /* for 64-bit architectures */ 173 | char sectname[16]; /* name of this section */ 174 | char segname[16]; /* segment this section goes in */ 175 | uint64_t addr; /* memory address of this section */ 176 | uint64_t size; /* size in bytes of this section */ 177 | uint32_t offset; /* file offset of this section */ 178 | uint32_t align; /* section alignment (power of 2) */ 179 | uint32_t reloff; /* file offset of relocation entries */ 180 | uint32_t nreloc; /* number of relocation entries */ 181 | uint32_t flags; /* flags (section type and attributes)*/ 182 | uint32_t reserved1; /* reserved (for offset or index) */ 183 | uint32_t reserved2; /* reserved (for count or sizeof) */ 184 | uint32_t reserved3; /* reserved */ 185 | }; 186 | 187 | /* 188 | * A program that uses a dynamic linker contains a dylinker_command to identify 189 | * the name of the dynamic linker (LC_LOAD_DYLINKER). And a dynamic linker 190 | * contains a dylinker_command to identify the dynamic linker (LC_ID_DYLINKER). 191 | * A file can have at most one of these. 192 | * This struct is also used for the LC_DYLD_ENVIRONMENT load command and 193 | * contains string for dyld to treat like environment variable. 194 | */ 195 | struct dylinker_command { 196 | uint32_t cmd; /* LC_ID_DYLINKER, LC_LOAD_DYLINKER or 197 | LC_DYLD_ENVIRONMENT */ 198 | uint32_t cmdsize; /* includes pathname string */ 199 | uint32_t name; /* dynamic linker's path name */ 200 | }; 201 | 202 | /* Constants for the flags field of the mach_header */ 203 | #define MH_NOUNDEFS 0x1 /* the object file has no undefined 204 | references */ 205 | #define MH_INCRLINK 0x2 /* the object file is the output of an 206 | incremental link against a base file 207 | and can't be link edited again */ 208 | #define MH_DYLDLINK 0x4 /* the object file is input for the 209 | dynamic linker and can't be staticly 210 | link edited again */ 211 | #define MH_BINDATLOAD 0x8 /* the object file's undefined 212 | references are bound by the dynamic 213 | linker when loaded. */ 214 | #define MH_PREBOUND 0x10 /* the file has its dynamic undefined 215 | references prebound. */ 216 | #define MH_SPLIT_SEGS 0x20 /* the file has its read-only and 217 | read-write segments split */ 218 | #define MH_LAZY_INIT 0x40 /* the shared library init routine is 219 | to be run lazily via catching memory 220 | faults to its writeable segments 221 | (obsolete) */ 222 | #define MH_TWOLEVEL 0x80 /* the image is using two-level name 223 | space bindings */ 224 | #define MH_FORCE_FLAT 0x100 /* the executable is forcing all images 225 | to use flat name space bindings */ 226 | #define MH_NOMULTIDEFS 0x200 /* this umbrella guarantees no multiple 227 | defintions of symbols in its 228 | sub-images so the two-level namespace 229 | hints can always be used. */ 230 | #define MH_NOFIXPREBINDING 0x400 /* do not have dyld notify the 231 | prebinding agent about this 232 | executable */ 233 | #define MH_PREBINDABLE 0x800 /* the binary is not prebound but can 234 | have its prebinding redone. only used 235 | when MH_PREBOUND is not set. */ 236 | #define MH_ALLMODSBOUND 0x1000 /* indicates that this binary binds to 237 | all two-level namespace modules of 238 | its dependent libraries. only used 239 | when MH_PREBINDABLE and MH_TWOLEVEL 240 | are both set. */ 241 | #define MH_SUBSECTIONS_VIA_SYMBOLS 0x2000/* safe to divide up the sections into 242 | sub-sections via symbols for dead 243 | code stripping */ 244 | #define MH_CANONICAL 0x4000 /* the binary has been canonicalized 245 | via the unprebind operation */ 246 | #define MH_WEAK_DEFINES 0x8000 /* the final linked image contains 247 | external weak symbols */ 248 | #define MH_BINDS_TO_WEAK 0x10000 /* the final linked image uses 249 | weak symbols */ 250 | 251 | #define MH_ALLOW_STACK_EXECUTION 0x20000/* When this bit is set, all stacks 252 | in the task will be given stack 253 | execution privilege. Only used in 254 | MH_EXECUTE filetypes. */ 255 | #define MH_DEAD_STRIPPABLE_DYLIB 0x400000 /* Only for use on dylibs. When 256 | linking against a dylib that 257 | has this bit set, the static linker 258 | will automatically not create a 259 | LC_LOAD_DYLIB load command to the 260 | dylib if no symbols are being 261 | referenced from the dylib. */ 262 | #define MH_ROOT_SAFE 0x40000 /* When this bit is set, the binary 263 | declares it is safe for use in 264 | processes with uid zero */ 265 | 266 | #define MH_SETUID_SAFE 0x80000 /* When this bit is set, the binary 267 | declares it is safe for use in 268 | processes when issetugid() is true */ 269 | 270 | #define MH_NO_REEXPORTED_DYLIBS 0x100000 /* When this bit is set on a dylib, 271 | the static linker does not need to 272 | examine dependent dylibs to see 273 | if any are re-exported */ 274 | #define MH_PIE 0x200000 /* When this bit is set, the OS will 275 | load the main executable at a 276 | random address. Only used in 277 | MH_EXECUTE filetypes. */ 278 | #define SG_PROTECTED_VERSION_1 0x08 279 | 280 | /* mach-o/fat.h */ 281 | 282 | #define FAT_MAGIC 0xcafebabe 283 | #define FAT_CIGAM 0xbebafeca 284 | 285 | struct fat_header { 286 | int32_t magic; /* FAT_MAGIC */ 287 | int32_t nfat_arch; /* number of structs that follow */ 288 | }; 289 | 290 | struct fat_arch { 291 | cpu_type_t cputype; /* cpu specifier (int) */ 292 | cpu_subtype_t cpusubtype; /* machine specifier (int) */ 293 | unsigned long offset; /* file offset to this object file */ 294 | unsigned long size; /* size of this object file */ 295 | unsigned long align; /* alignment as a power of 2 */ 296 | }; 297 | 298 | /* osfmk/mach/i386/thread_status.h */ 299 | #define x86_THREAD_STATE64 4 300 | 301 | /* osfmk/mach/i386/_structs.h */ 302 | struct __darwin_x86_thread_state64 { 303 | uint64_t rax; 304 | uint64_t rbx; 305 | uint64_t rcx; 306 | uint64_t rdx; 307 | uint64_t rdi; 308 | uint64_t rsi; 309 | uint64_t rbp; 310 | uint64_t rsp; 311 | uint64_t r8; 312 | uint64_t r9; 313 | uint64_t r10; 314 | uint64_t r11; 315 | uint64_t r12; 316 | uint64_t r13; 317 | uint64_t r14; 318 | uint64_t r15; 319 | uint64_t rip; 320 | uint64_t rflags; 321 | uint64_t cs; 322 | uint64_t fs; 323 | uint64_t gs; 324 | }; 325 | 326 | /* osfmk/mach/i386/vm_param.h */ 327 | #define VM_USRSTACK64 0x00007FFEEFC00000UL 328 | 329 | 330 | /* osfmk/i386/cpu_capabilities.h */ 331 | #define _COMM_PAGE64_AREA_LENGTH ( 1 * 4096 ) /* reserved length of entire comm area (2MB) */ 332 | #ifdef __ASSEMBLER__ 333 | #define _COMM_PAGE64_BASE_ADDRESS ( 0x00007fffffe00000 ) /* base address of allocated memory */ 334 | #else /* __ASSEMBLER__ */ 335 | #define _COMM_PAGE64_BASE_ADDRESS ( 0x00007fffffe00000ULL ) /* base address of allocated memory */ 336 | #endif /* __ASSEMBLER__ */ 337 | #define _COMM_PAGE64_START_ADDRESS ( _COMM_PAGE64_BASE_ADDRESS ) /* address traditional commpage code starts on */ 338 | #define _COMM_PAGE64_AREA_USED ( 1 * 4096 ) /* this is the amt actually populated */ 339 | -------------------------------------------------------------------------------- /dsmos-dump/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include "macho.h" 12 | #include "schedule_data.h" 13 | 14 | #define PAGE_SIZE 0x1000 15 | 16 | static void 17 | unprotect_segment(uint8_t* base, struct segment_command_64* segment) 18 | { 19 | uint8_t* scratch = malloc(PAGE_SIZE); 20 | 21 | // First three pages are NOT protected. 22 | // 23 | uint8_t* src = base + PAGE_SIZE * 3; 24 | uint32_t count = (segment->vmsize / PAGE_SIZE) - 3; 25 | 26 | for (uint32_t i = 0; i < count; i++) { 27 | // Zero-ed IV each run. 28 | // 29 | uint8_t iv[8] = {}; 30 | // Unprotect the page into the scratch space and write the unprotected 31 | // page back to the original page. 32 | // 33 | BF_cbc_encrypt(src, scratch, PAGE_SIZE, (BF_KEY*) &schedule_data, iv, BF_DECRYPT); 34 | memcpy(src, scratch, PAGE_SIZE); 35 | 36 | src += PAGE_SIZE; 37 | } 38 | 39 | free(scratch); 40 | } 41 | 42 | int 43 | main(int argc, char* argv[]) 44 | { 45 | int f = 0; 46 | struct stat s; 47 | uint8_t* base = NULL; 48 | 49 | if (argc < 2) { 50 | return 1; 51 | } 52 | 53 | f = open(argv[1], O_RDWR); 54 | if (f < 0) { 55 | perror("open"); 56 | return 1; 57 | } 58 | 59 | if (fstat(f, &s) < 0) { 60 | perror("fstat"); 61 | goto error; 62 | } 63 | 64 | base = mmap(NULL, s.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, f, 0); 65 | if (base == MAP_FAILED) { 66 | perror("mmap"); 67 | goto error; 68 | } 69 | 70 | struct mach_header_64* header = (struct mach_header_64*) base; 71 | assert(header->magic == MH_MAGIC_64); 72 | assert(header->cputype == CPU_TYPE_X86_64); 73 | assert(header->cpusubtype == CPU_SUBTYPE_X86_64_ALL); 74 | 75 | uint32_t offset = sizeof(struct mach_header_64); 76 | 77 | for (uint32_t i = 0; i < header->ncmds; i++) { 78 | struct load_command* command = (struct load_command*) (base + offset); 79 | 80 | if (command->cmd == LC_SEGMENT_64) { 81 | struct segment_command_64* segment = (struct segment_command_64*) command; 82 | if (segment->flags & SG_PROTECTED_VERSION_1) { 83 | assert((segment->vmsize % PAGE_SIZE) == 0); 84 | unprotect_segment(base, segment); 85 | segment->flags &= ~SG_PROTECTED_VERSION_1; 86 | } 87 | } 88 | 89 | offset += command->cmdsize; 90 | } 91 | 92 | munmap(base, s.st_size); 93 | close(f); 94 | return 0; 95 | error: 96 | if (base) 97 | munmap(base, s.st_size); 98 | if (f) 99 | close(f); 100 | return 1; 101 | } 102 | -------------------------------------------------------------------------------- /dsmos-dump/meson.build: -------------------------------------------------------------------------------- 1 | project('dsmos-dump', 'c', 2 | version: '0.1.0', 3 | ) 4 | 5 | openssl_dep = dependency('openssl') 6 | 7 | executable('dsmos-dump', 8 | sources: ['main.c'], 9 | dependencies: [openssl_dep], 10 | ) 11 | -------------------------------------------------------------------------------- /dsmos-dump/schedule_data.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | // This is a Blowfish scheduled key with the Apple secret. 6 | // You know how to get it :-) 7 | // 8 | uint8_t schedule_data[] = { 9 | 0x87, 0x31, 0xd7, 0x22, 0x02, 0x61, 0xe7, 0x98, 0x76, 0x68, 0x88, 0xeb, 10 | 0x4d, 0x4b, 0xb5, 0x2b, 0xd3, 0x49, 0xc3, 0x41, 0x2a, 0xd1, 0xf9, 0xe4, 11 | 0xa1, 0x29, 0x76, 0xf5, 0x7d, 0x17, 0x23, 0xe3, 0x70, 0xf3, 0xac, 0x56, 12 | 0xfc, 0xb5, 0x1d, 0x52, 0x3d, 0x5f, 0x0b, 0x55, 0x14, 0x95, 0x5a, 0xb1, 13 | 0x80, 0x7c, 0x2f, 0x4a, 0x5c, 0xaa, 0x8c, 0xf5, 0x1d, 0xd8, 0x5b, 0xfe, 14 | 0x93, 0x1c, 0x4a, 0x71, 0xb8, 0x30, 0x5e, 0x97, 0x90, 0xab, 0x19, 0xfb, 15 | 0xcf, 0x0d, 0x29, 0xf1, 0x60, 0x73, 0x08, 0x00, 0x27, 0x41, 0x0b, 0x76, 16 | 0x6d, 0xfc, 0x10, 0xec, 0x6d, 0x92, 0xef, 0x71, 0xe1, 0x19, 0xed, 0xd3, 17 | 0x8a, 0x12, 0x74, 0x51, 0xcc, 0xd4, 0x87, 0xa6, 0x7a, 0xf3, 0x8d, 0x81, 18 | 0xce, 0x25, 0xe8, 0x9f, 0x9a, 0x72, 0x22, 0xa7, 0xa2, 0x0f, 0xdb, 0x21, 19 | 0xcd, 0x68, 0xf6, 0x10, 0xb4, 0xd7, 0x89, 0x6b, 0x37, 0xff, 0x59, 0xb2, 20 | 0xc8, 0x67, 0xa8, 0xc8, 0x97, 0xa3, 0x4d, 0xb4, 0xaf, 0xe7, 0x78, 0x3d, 21 | 0x1f, 0xd3, 0x06, 0x02, 0x89, 0xc8, 0x5d, 0x69, 0xec, 0x1b, 0x2d, 0x31, 22 | 0xc6, 0x45, 0xcb, 0x5c, 0x77, 0x36, 0x5b, 0x9b, 0x29, 0xe7, 0x16, 0xf2, 23 | 0x40, 0xdc, 0xc5, 0x09, 0x84, 0xf3, 0xcd, 0xec, 0x29, 0xe1, 0xeb, 0x0f, 24 | 0xbb, 0x6a, 0xc5, 0x4e, 0xc8, 0x6c, 0x57, 0x87, 0x02, 0xac, 0xe1, 0xc8, 25 | 0x39, 0xbc, 0xa4, 0xb6, 0x9f, 0x41, 0x8e, 0xca, 0x2b, 0x58, 0x02, 0xda, 26 | 0x1f, 0xf2, 0x5d, 0x09, 0x75, 0xb4, 0x80, 0x9b, 0x0e, 0x16, 0x7e, 0x8f, 27 | 0x15, 0x2f, 0x1f, 0x90, 0x3f, 0xb5, 0xbe, 0x24, 0xde, 0xd9, 0x06, 0xd7, 28 | 0x7b, 0x6b, 0x9a, 0x8a, 0x67, 0x14, 0x7a, 0x01, 0x25, 0x3c, 0x9c, 0x45, 29 | 0x79, 0xe8, 0x9f, 0xd4, 0x43, 0xcc, 0x2c, 0xa2, 0x45, 0x27, 0xf5, 0xc9, 30 | 0x08, 0x73, 0x63, 0xbe, 0x8b, 0x86, 0x41, 0x07, 0x83, 0x16, 0x94, 0xcd, 31 | 0x98, 0x81, 0x1b, 0xf1, 0x24, 0xa6, 0x67, 0x5d, 0x7a, 0x2e, 0xac, 0x45, 32 | 0xc8, 0xe5, 0x60, 0x3d, 0x5e, 0xa6, 0xfa, 0xbd, 0x18, 0x7d, 0xe5, 0x52, 33 | 0x0a, 0xbc, 0x4d, 0x63, 0x2d, 0x4b, 0xf2, 0x39, 0x82, 0x3e, 0x95, 0xfe, 34 | 0xec, 0x38, 0xb5, 0x52, 0x5b, 0xd7, 0xe0, 0xec, 0x14, 0xd8, 0xc8, 0xd2, 35 | 0xca, 0x18, 0x9d, 0xba, 0xab, 0x51, 0xed, 0xb0, 0x8b, 0x17, 0x88, 0x66, 36 | 0x09, 0x65, 0x32, 0x9e, 0xd8, 0xe3, 0x46, 0x84, 0x72, 0x2d, 0x71, 0x6a, 37 | 0xf5, 0x5e, 0xcd, 0xa1, 0x18, 0x09, 0x89, 0xe0, 0x66, 0xcb, 0xc7, 0x90, 38 | 0x4a, 0x57, 0x1c, 0x2d, 0x95, 0x4e, 0xdd, 0xf1, 0x6d, 0x5d, 0x0f, 0x39, 39 | 0x17, 0xd3, 0x82, 0xfb, 0x87, 0x1b, 0x06, 0x5f, 0x5a, 0xd8, 0x56, 0x14, 40 | 0x0a, 0x55, 0x7d, 0x41, 0x49, 0xe2, 0x58, 0x1c, 0x3f, 0xd9, 0x08, 0x58, 41 | 0xa9, 0x16, 0x9e, 0x4e, 0xd8, 0xc0, 0x10, 0xd1, 0xd9, 0x5e, 0x60, 0x15, 42 | 0x7f, 0xba, 0x91, 0x84, 0xd1, 0x4c, 0x2c, 0x4a, 0x36, 0xc0, 0x13, 0xec, 43 | 0xd8, 0x3e, 0xdf, 0xe1, 0xf5, 0xf0, 0xa4, 0xf7, 0x19, 0x4e, 0xf8, 0x1f, 44 | 0x28, 0x7d, 0xb9, 0xcf, 0xa8, 0x27, 0xd4, 0xd5, 0x0e, 0x9f, 0x6f, 0x11, 45 | 0x8c, 0xdb, 0x0a, 0xed, 0x2d, 0xe6, 0x6e, 0xcb, 0x7c, 0x7c, 0xe6, 0xac, 46 | 0xcb, 0xcf, 0xc4, 0x34, 0x0d, 0xa0, 0x4f, 0x6c, 0x21, 0x03, 0xbc, 0x6b, 47 | 0xfb, 0xc0, 0x72, 0xf8, 0x4b, 0x17, 0x0d, 0x4d, 0x71, 0xfa, 0xf1, 0x97, 48 | 0xba, 0x33, 0xb2, 0x15, 0xbe, 0x17, 0xed, 0x55, 0xc9, 0x93, 0x5d, 0xe4, 49 | 0x33, 0x74, 0xe1, 0xb1, 0x04, 0xf7, 0x9f, 0x7d, 0xb7, 0x10, 0x0a, 0x44, 50 | 0x1d, 0xb1, 0x63, 0x86, 0x97, 0xfb, 0xc3, 0x0f, 0xd9, 0x60, 0x71, 0x81, 51 | 0x09, 0xb8, 0xfd, 0x5e, 0x79, 0xc8, 0xf1, 0xc2, 0x0c, 0x0c, 0xa0, 0xa6, 52 | 0x79, 0x39, 0x7d, 0xf3, 0x57, 0xf6, 0x24, 0x61, 0x64, 0xfe, 0x6f, 0xcc, 53 | 0xab, 0x6a, 0xe0, 0xd2, 0x02, 0x21, 0xef, 0x56, 0xfd, 0x7b, 0x4a, 0x6a, 54 | 0x51, 0x04, 0xd8, 0xbe, 0x53, 0x00, 0xee, 0x41, 0x57, 0x2a, 0x2a, 0x9f, 55 | 0x79, 0x8c, 0xf3, 0x32, 0xcf, 0x85, 0xd5, 0xed, 0x5e, 0xe8, 0x13, 0x54, 56 | 0x11, 0xd2, 0x9d, 0x10, 0x69, 0xc7, 0x2c, 0x81, 0x01, 0x1a, 0x84, 0x72, 57 | 0xca, 0xc5, 0x0c, 0x9d, 0x5f, 0xb8, 0x4c, 0xe4, 0xac, 0x70, 0xb8, 0x54, 58 | 0xd5, 0x4a, 0x5b, 0x9a, 0x98, 0x03, 0x42, 0x99, 0x9f, 0xd2, 0x30, 0x2f, 59 | 0x9c, 0x12, 0x5a, 0xe3, 0x3c, 0x3c, 0xde, 0x6c, 0x60, 0x52, 0x72, 0x57, 60 | 0x76, 0xf2, 0x8c, 0xbe, 0x93, 0x11, 0x95, 0x4c, 0xa5, 0xf9, 0xbc, 0x61, 61 | 0x8a, 0x9a, 0xeb, 0xd3, 0x43, 0xb8, 0x56, 0x37, 0x0d, 0xf3, 0xda, 0x5d, 62 | 0x2d, 0x24, 0x1c, 0x24, 0xdc, 0x92, 0xdd, 0x01, 0x5b, 0xec, 0xb0, 0x4c, 63 | 0x15, 0x3a, 0xef, 0x3f, 0x6c, 0xc8, 0x8e, 0x50, 0xe5, 0x5e, 0x79, 0x6a, 64 | 0xa5, 0x16, 0x75, 0x16, 0x25, 0xa8, 0x56, 0xb8, 0x3f, 0xef, 0xe6, 0xbe, 65 | 0x69, 0x72, 0x92, 0x8a, 0xea, 0xd2, 0x99, 0xc7, 0x51, 0xba, 0x6e, 0x85, 66 | 0x2f, 0x31, 0xa2, 0xc7, 0xe5, 0x34, 0xdf, 0x51, 0x9f, 0xab, 0x0a, 0x19, 67 | 0x08, 0xf9, 0xa6, 0xad, 0xc9, 0x28, 0x3b, 0x6d, 0x35, 0xf4, 0xac, 0x33, 68 | 0x3e, 0xec, 0x9c, 0x8a, 0xf4, 0xda, 0x5d, 0x21, 0x09, 0x3a, 0x06, 0x24, 69 | 0x70, 0xc1, 0xe6, 0xae, 0x65, 0xe5, 0x8a, 0x3b, 0x79, 0x01, 0xc1, 0x9c, 70 | 0xc0, 0x36, 0x04, 0x39, 0x1e, 0x78, 0xc2, 0xbc, 0x38, 0xef, 0xe2, 0x5a, 71 | 0xa4, 0x94, 0x30, 0x54, 0x05, 0x3a, 0x71, 0xe3, 0xef, 0x69, 0x44, 0xfe, 72 | 0x6e, 0x9f, 0x52, 0x46, 0x5b, 0x8a, 0xab, 0x3d, 0x48, 0xcf, 0x92, 0xc0, 73 | 0x2f, 0x51, 0x84, 0x75, 0xc2, 0x21, 0x38, 0x02, 0x5c, 0xa3, 0x29, 0x40, 74 | 0x38, 0xbc, 0x96, 0x45, 0x3a, 0x1b, 0xca, 0x6b, 0x18, 0x69, 0x04, 0x52, 75 | 0xfb, 0xa7, 0x53, 0x55, 0x14, 0xde, 0xe6, 0xac, 0x4b, 0x39, 0xab, 0xbb, 76 | 0x5e, 0xc9, 0xa0, 0xfb, 0xc5, 0x4d, 0xcb, 0x02, 0x89, 0xf6, 0x74, 0x50, 77 | 0x93, 0xdd, 0xb5, 0xa0, 0x70, 0x53, 0xcb, 0x1f, 0x5f, 0x02, 0xb9, 0xbd, 78 | 0x43, 0x93, 0x76, 0xf5, 0x42, 0x1b, 0x86, 0xe9, 0xe0, 0x33, 0x0f, 0x11, 79 | 0x37, 0x57, 0xb8, 0xed, 0xa3, 0xb6, 0x03, 0xb6, 0xa7, 0x5e, 0x33, 0x48, 80 | 0xec, 0x66, 0x1e, 0x45, 0x8a, 0x03, 0x02, 0x74, 0xe1, 0x6c, 0x3b, 0x9d, 81 | 0x57, 0x59, 0x38, 0xee, 0xc0, 0xa2, 0x3b, 0x26, 0x41, 0xe3, 0xcb, 0x9a, 82 | 0xfc, 0x7b, 0x76, 0xe7, 0x59, 0xa6, 0xcd, 0x9e, 0x05, 0xac, 0xa0, 0x76, 83 | 0xba, 0x87, 0x90, 0xd2, 0xc2, 0x3b, 0x8f, 0x74, 0x41, 0x95, 0x77, 0xab, 84 | 0x7c, 0x9b, 0x9c, 0xfe, 0x2f, 0xee, 0x3d, 0x39, 0x3f, 0x14, 0x5c, 0x23, 85 | 0x5d, 0x02, 0x33, 0xe5, 0xfc, 0xe8, 0xe2, 0x6e, 0x0b, 0x95, 0xb8, 0xef, 86 | 0xbd, 0xd7, 0xaf, 0x37, 0x98, 0x7b, 0x8c, 0xb7, 0x6d, 0xdc, 0xfa, 0x92, 87 | 0xee, 0x62, 0xc8, 0x90, 0xbc, 0xc8, 0x29, 0x7f, 0x74, 0xc4, 0x6d, 0xea, 88 | 0xd8, 0x96, 0xc9, 0x21, 0xea, 0xd2, 0x32, 0x61, 0xd9, 0x3e, 0xbc, 0x7c, 89 | 0xef, 0x88, 0x11, 0x56, 0xdd, 0x74, 0xaf, 0x66, 0x19, 0x12, 0xae, 0xed, 90 | 0x7c, 0x5b, 0x24, 0xe1, 0x90, 0x81, 0x65, 0x0a, 0x22, 0x2a, 0xf8, 0xce, 91 | 0xef, 0x3e, 0x3a, 0x55, 0x2b, 0xd3, 0x23, 0x90, 0x0c, 0x12, 0xc8, 0x09, 92 | 0xf6, 0xa0, 0x08, 0xdf, 0x7e, 0x47, 0xe5, 0xe2, 0x66, 0xc8, 0xe6, 0x56, 93 | 0x63, 0x1c, 0xf5, 0xdb, 0x52, 0x3b, 0x12, 0x12, 0x72, 0x20, 0xbb, 0xa9, 94 | 0xfd, 0x0d, 0x8b, 0x0a, 0xac, 0x2d, 0x7b, 0xf4, 0x07, 0x95, 0xed, 0xa1, 95 | 0x9f, 0x83, 0x47, 0xdd, 0xf7, 0xf3, 0x8b, 0x58, 0x7c, 0x71, 0xfc, 0xee, 96 | 0x24, 0xd6, 0xb4, 0xb2, 0xee, 0x3a, 0x01, 0x05, 0xef, 0x8c, 0xf2, 0xa4, 97 | 0x5f, 0xaf, 0xb5, 0xc1, 0x1b, 0xeb, 0x80, 0xfa, 0x0c, 0x76, 0xd4, 0xcf, 98 | 0xce, 0xb8, 0x54, 0x43, 0x0f, 0xc5, 0x90, 0x4b, 0x5d, 0x25, 0x53, 0x66, 99 | 0x58, 0xcb, 0xdc, 0x4a, 0x99, 0x8a, 0x09, 0xf0, 0xc0, 0x43, 0x3a, 0x1d, 100 | 0x5d, 0xb2, 0x99, 0x66, 0xfe, 0x96, 0xdc, 0x88, 0xb5, 0xf3, 0x9b, 0x64, 101 | 0xfb, 0xdb, 0x1e, 0xb5, 0x5f, 0x52, 0xf8, 0x76, 0x45, 0x41, 0x97, 0xc3, 102 | 0x7b, 0x58, 0xb1, 0x4f, 0xf3, 0x3d, 0x20, 0x1b, 0xee, 0x97, 0x49, 0x99, 103 | 0x47, 0xe5, 0xf8, 0xbc, 0x15, 0x83, 0x1b, 0xc6, 0x4d, 0x6b, 0xe4, 0x39, 104 | 0x5f, 0xcf, 0xff, 0x37, 0x88, 0x55, 0x85, 0x19, 0xcd, 0x3d, 0x85, 0x3c, 105 | 0x3a, 0x87, 0x39, 0x09, 0x6c, 0x98, 0x89, 0x45, 0x66, 0xaf, 0x76, 0x20, 106 | 0xf8, 0xa2, 0xe7, 0x8c, 0xbf, 0x67, 0xa8, 0x81, 0xb8, 0x28, 0x97, 0x48, 107 | 0xe6, 0x33, 0x43, 0x01, 0xfa, 0x79, 0x82, 0x3d, 0x60, 0xfc, 0xba, 0x73, 108 | 0xd5, 0x98, 0x4a, 0x2f, 0xc6, 0xb8, 0x6e, 0xfd, 0xab, 0xfb, 0x63, 0x4a, 109 | 0x78, 0x16, 0xff, 0x8e, 0xcc, 0x3e, 0xca, 0x3b, 0x85, 0x92, 0xc3, 0x20, 110 | 0x03, 0x31, 0x91, 0xb9, 0xf0, 0xd6, 0x51, 0xcf, 0x40, 0x66, 0xfd, 0x6d, 111 | 0x0c, 0x11, 0x88, 0xa7, 0xfe, 0xe8, 0x25, 0x90, 0xb2, 0x2e, 0x41, 0xc6, 112 | 0xbb, 0x0f, 0xb1, 0xc0, 0x03, 0xbb, 0xb8, 0x1e, 0x1a, 0xf6, 0x0f, 0xb0, 113 | 0xfd, 0x59, 0x68, 0xf7, 0xb3, 0x78, 0xe9, 0x08, 0x4c, 0x6b, 0x66, 0x56, 114 | 0xcc, 0x6d, 0xbe, 0x90, 0xf0, 0xff, 0x77, 0xb8, 0x89, 0xb4, 0xe1, 0xd5, 115 | 0xa0, 0x41, 0xce, 0xb0, 0x4a, 0xf3, 0xfe, 0x2e, 0xeb, 0x63, 0xed, 0x36, 116 | 0xe3, 0xda, 0x3e, 0x69, 0x5d, 0x89, 0x1a, 0x7c, 0x7d, 0x8b, 0xfe, 0xb7, 117 | 0xa1, 0x94, 0xb3, 0x98, 0xef, 0xf3, 0x9d, 0x84, 0x14, 0xf8, 0x33, 0xb1, 118 | 0x34, 0x7b, 0x97, 0x88, 0x38, 0x16, 0x12, 0xbf, 0x42, 0xd9, 0x60, 0xe1, 119 | 0xbc, 0x42, 0x47, 0xdb, 0x3c, 0xb7, 0x35, 0xa7, 0x76, 0x07, 0xf8, 0xe9, 120 | 0x42, 0x55, 0xb3, 0xb2, 0xa4, 0x80, 0x43, 0xd4, 0x95, 0x36, 0x34, 0x5d, 121 | 0x7f, 0x2f, 0x94, 0x82, 0x35, 0xc1, 0x38, 0xbe, 0x4f, 0xa0, 0x30, 0x7c, 122 | 0xf2, 0x96, 0x3e, 0xe8, 0x11, 0xfb, 0x1c, 0xd8, 0xa4, 0xe9, 0xc8, 0x06, 123 | 0xda, 0x7e, 0xbc, 0xa3, 0x33, 0xee, 0xdb, 0xd9, 0x9b, 0x9d, 0x9a, 0xc2, 124 | 0x02, 0xa9, 0xa8, 0xb4, 0x10, 0x3b, 0x14, 0x4e, 0xb1, 0xb4, 0x2f, 0xe9, 125 | 0x0f, 0xf7, 0xa4, 0x9f, 0x03, 0x0e, 0x51, 0x67, 0xe4, 0x51, 0x8f, 0x91, 126 | 0x61, 0xe0, 0x4e, 0x5b, 0x55, 0x6e, 0xa7, 0x05, 0x68, 0x1f, 0xb9, 0x00, 127 | 0xb8, 0x15, 0x0d, 0xcf, 0x65, 0x4e, 0x42, 0x12, 0x08, 0xae, 0x94, 0x3d, 128 | 0x99, 0x86, 0xc3, 0x9b, 0x68, 0x73, 0x18, 0xb7, 0xd9, 0x94, 0x85, 0x37, 129 | 0xb1, 0xdf, 0x81, 0x34, 0xb7, 0x0f, 0x5d, 0xfc, 0xda, 0x22, 0xe5, 0xa9, 130 | 0x4b, 0xde, 0xe5, 0xda, 0xee, 0xe6, 0x88, 0xcc, 0x73, 0xa4, 0x8f, 0x38, 131 | 0x4f, 0xbc, 0x45, 0x43, 0x84, 0xdb, 0xe2, 0x56, 0x08, 0x17, 0x06, 0x67, 132 | 0x90, 0xc7, 0x74, 0x71, 0x7c, 0x65, 0x45, 0x3d, 0xf7, 0x7c, 0x2e, 0xaf, 133 | 0x3a, 0x6c, 0x45, 0x2e, 0x36, 0x69, 0x5b, 0x51, 0xd0, 0x52, 0x79, 0x5b, 134 | 0x8a, 0x43, 0x31, 0x16, 0x63, 0x95, 0x97, 0xcd, 0xec, 0xc0, 0x07, 0x70, 135 | 0x15, 0xc1, 0x1d, 0x7a, 0x6f, 0x17, 0x8e, 0xaa, 0x07, 0xdd, 0x02, 0x4e, 136 | 0x17, 0xbd, 0x5e, 0xff, 0x23, 0x03, 0xc7, 0xcb, 0xbc, 0xbe, 0x2a, 0x6b, 137 | 0x34, 0xb8, 0xfd, 0x80, 0x18, 0x15, 0x13, 0xe3, 0xd7, 0x30, 0x77, 0x07, 138 | 0x9c, 0x9b, 0x80, 0x7e, 0xf4, 0x6f, 0xb9, 0x84, 0x69, 0x9b, 0xe9, 0xc2, 139 | 0xf1, 0x56, 0xdf, 0x90, 0x6f, 0x75, 0x5d, 0x2f, 0x30, 0x65, 0x52, 0x75, 140 | 0x36, 0x40, 0xad, 0x2d, 0x0c, 0xc0, 0x2f, 0xbb, 0x1b, 0x9c, 0xcd, 0x4e, 141 | 0x5d, 0xde, 0x5b, 0xa9, 0xad, 0x83, 0x90, 0xb7, 0xa6, 0xb9, 0x3c, 0xca, 142 | 0xbb, 0x54, 0x2d, 0x89, 0xc7, 0xf9, 0xc7, 0x54, 0x71, 0xbc, 0x1b, 0x72, 143 | 0x1f, 0xfa, 0x11, 0xb0, 0x6e, 0x3c, 0x43, 0x35, 0x24, 0xcd, 0x52, 0x2c, 144 | 0x58, 0x20, 0x51, 0x70, 0x86, 0x52, 0x5e, 0xed, 0x0d, 0xac, 0x4d, 0x21, 145 | 0x2f, 0xe9, 0x93, 0xf5, 0x98, 0xe0, 0x02, 0x02, 0x9c, 0x32, 0xe1, 0xed, 146 | 0xa7, 0xfa, 0x44, 0xd6, 0x55, 0x6b, 0xe0, 0x15, 0xa2, 0xd5, 0x33, 0x25, 147 | 0x2c, 0x58, 0x4c, 0xdf, 0xe6, 0x58, 0x1c, 0xfe, 0x92, 0x97, 0x3c, 0x18, 148 | 0xee, 0x71, 0x6c, 0xca, 0xf1, 0x9f, 0x11, 0x6d, 0x99, 0x49, 0x36, 0x8f, 149 | 0x80, 0x96, 0x49, 0x16, 0xf9, 0xa8, 0xb5, 0x6f, 0xaa, 0x73, 0x63, 0x6d, 150 | 0x54, 0x6c, 0x8e, 0x4c, 0x9b, 0xc9, 0xb9, 0x79, 0xcd, 0x34, 0x57, 0x41, 151 | 0x78, 0xc0, 0x52, 0x19, 0xc4, 0xa5, 0x84, 0x2d, 0x0d, 0x00, 0xc6, 0x68, 152 | 0x3a, 0x84, 0xeb, 0x93, 0x69, 0x9b, 0xf5, 0x53, 0x95, 0x81, 0xa5, 0x2c, 153 | 0xd6, 0xf4, 0x24, 0xcd, 0x56, 0x02, 0x06, 0xd9, 0xc9, 0xc8, 0xbe, 0x99, 154 | 0x5e, 0xd4, 0xa0, 0xd3, 0xa2, 0x7e, 0x27, 0x86, 0xb9, 0xcd, 0xad, 0x6d, 155 | 0x30, 0x05, 0x01, 0xc1, 0x14, 0xb9, 0x6b, 0x13, 0x8c, 0x5c, 0x84, 0x53, 156 | 0x02, 0x5c, 0x32, 0xa3, 0x81, 0xfd, 0xcf, 0x54, 0x97, 0xaa, 0x94, 0x8e, 157 | 0xf1, 0x69, 0x0b, 0x8f, 0x5d, 0x00, 0x51, 0x90, 0xc4, 0xfb, 0x0d, 0xf1, 158 | 0xd7, 0xc1, 0x81, 0x92, 0xb2, 0x11, 0x53, 0xf5, 0xbd, 0x2d, 0x52, 0x65, 159 | 0xbc, 0xbf, 0xa1, 0x39, 0x16, 0xbe, 0xc9, 0x46, 0x4e, 0x48, 0x6d, 0xa5, 160 | 0xeb, 0xb6, 0x95, 0xcd, 0x13, 0x9b, 0x9d, 0x76, 0x2d, 0x2b, 0xd1, 0x07, 161 | 0x81, 0x58, 0x10, 0x30, 0x5d, 0x37, 0x82, 0x5d, 0xbe, 0xd0, 0x68, 0x9d, 162 | 0x48, 0xac, 0xb0, 0xc3, 0x7f, 0xdc, 0x8a, 0x96, 0x36, 0xbc, 0x32, 0xdc, 163 | 0x91, 0x0e, 0x8b, 0x8f, 0xb7, 0xf4, 0xab, 0x1b, 0x0d, 0xf7, 0xc0, 0x58, 164 | 0x99, 0x7d, 0x3c, 0x7a, 0x5c, 0x49, 0xb8, 0x69, 0x34, 0x1c, 0x6a, 0x1a, 165 | 0x52, 0xad, 0x3f, 0xc8, 0x50, 0x79, 0x12, 0xec, 0x87, 0x1f, 0xde, 0xe3, 166 | 0xea, 0xae, 0x33, 0x8d, 0xbe, 0x88, 0x13, 0x61, 0x8e, 0xf1, 0xa0, 0xb5, 167 | 0x0d, 0x0e, 0x7c, 0x08, 0xfd, 0x03, 0x88, 0xf6, 0xf3, 0x56, 0xb2, 0xf9, 168 | 0xc3, 0x76, 0x3c, 0x1e, 0x3d, 0x98, 0xbc, 0x7c, 0x87, 0xaf, 0x58, 0x66, 169 | 0x39, 0x73, 0x5a, 0x7a, 0x63, 0xdf, 0x8f, 0xbc, 0xd0, 0x81, 0x2b, 0xab, 170 | 0xf1, 0x31, 0xb9, 0x1f, 0x97, 0x20, 0x9f, 0x03, 0x5a, 0x6b, 0x0d, 0xa0, 171 | 0xe1, 0xa9, 0xb0, 0x7c, 0x0f, 0x49, 0x9a, 0x57, 0xfb, 0x32, 0xd9, 0xc1, 172 | 0x26, 0xd3, 0x1a, 0xba, 0x9d, 0xae, 0x12, 0xdb, 0x38, 0x12, 0xf3, 0xb7, 173 | 0x4e, 0x60, 0xdb, 0xdd, 0x4e, 0x59, 0xf5, 0x36, 0x2d, 0x81, 0x90, 0xbb, 174 | 0xe6, 0xd6, 0xc0, 0xc2, 0xf8, 0xb6, 0xb4, 0x36, 0x3c, 0x30, 0x16, 0x22, 175 | 0xce, 0x8f, 0x64, 0x88, 0x5b, 0xba, 0xd2, 0x08, 0x73, 0xa5, 0xbf, 0xe3, 176 | 0x4e, 0x7c, 0x69, 0xa8, 0x68, 0x78, 0xef, 0xe7, 0x0e, 0x7e, 0x6f, 0x9c, 177 | 0xf9, 0x07, 0x22, 0x27, 0x0a, 0x9d, 0x84, 0x48, 0xfa, 0x3d, 0x5a, 0xfd, 178 | 0x8a, 0x62, 0x9c, 0x9e, 0x0e, 0x8e, 0xd1, 0x8b, 0xda, 0x0c, 0xac, 0xe8, 179 | 0x22, 0xac, 0x09, 0x8a, 0x9d, 0x36, 0xad, 0x5b, 0x0c, 0x8a, 0xaa, 0xa5, 180 | 0x25, 0x4d, 0xbf, 0xa6, 0xfb, 0x6b, 0xa2, 0x22, 0x11, 0xd8, 0x47, 0xcd, 181 | 0x5b, 0xe3, 0x1e, 0xb3, 0xf3, 0xef, 0x0f, 0xea, 0x18, 0xb1, 0x13, 0x5b, 182 | 0xba, 0x8d, 0x8c, 0xe3, 0x61, 0x91, 0xc5, 0x0d, 0x73, 0x6b, 0x14, 0x28, 183 | 0x3b, 0xc7, 0x79, 0xf6, 0x20, 0xa4, 0x4d, 0x1b, 0x2a, 0xcd, 0xab, 0xf9, 184 | 0x04, 0x2b, 0xde, 0x34, 0x95, 0xe7, 0xbc, 0x3c, 0x8a, 0x08, 0x65, 0x83, 185 | 0xb7, 0xf6, 0x71, 0x5f, 0xcc, 0xcb, 0x4e, 0xa8, 0xc1, 0x61, 0x4e, 0xde, 186 | 0x14, 0xa3, 0x63, 0xe9, 0x5f, 0x50, 0x11, 0xc2, 0x59, 0xa7, 0xa1, 0xdc, 187 | 0xdf, 0x60, 0x9a, 0x5c, 0xcd, 0xa4, 0x67, 0x8d, 0x87, 0x1c, 0x15, 0x4b, 188 | 0x50, 0xe3, 0xf5, 0x48, 0x55, 0x0a, 0x6f, 0xb9, 0x4c, 0x4d, 0x25, 0x7a, 189 | 0x78, 0xf4, 0x8d, 0x65, 0x18, 0x18, 0xb0, 0xb6, 0x32, 0x3c, 0x76, 0x8f, 190 | 0x6e, 0x5c, 0x12, 0x73, 0xa3, 0xba, 0xaa, 0x85, 0x14, 0xcd, 0x21, 0xd5, 191 | 0xb4, 0x3d, 0xc1, 0x16, 0x0a, 0x1e, 0x8d, 0x04, 0xc3, 0x9c, 0xeb, 0x75, 192 | 0x6a, 0x34, 0x45, 0x8e, 0xf6, 0x3e, 0x3a, 0xc1, 0xbf, 0x76, 0x22, 0x67, 193 | 0x6e, 0xde, 0x6f, 0x09, 0x52, 0x8c, 0xcc, 0x9e, 0x23, 0x52, 0x22, 0x81, 194 | 0xb5, 0x50, 0x5f, 0x4a, 0xf5, 0x31, 0x56, 0xcc, 0x48, 0x5a, 0xa0, 0xc2, 195 | 0x27, 0xb5, 0xc6, 0xe4, 0x9d, 0xb1, 0x38, 0x4a, 0x78, 0x85, 0xb1, 0xdb, 196 | 0xa5, 0xcb, 0x63, 0x95, 0xa6, 0x2a, 0x86, 0x21, 0xa2, 0x44, 0x60, 0xe3, 197 | 0x45, 0xde, 0x53, 0x79, 0x02, 0x54, 0x60, 0x1d, 0xec, 0xe1, 0x6a, 0x2f, 198 | 0xea, 0x04, 0x78, 0xc5, 0x50, 0x52, 0x9c, 0x92, 0x08, 0x53, 0x26, 0x95, 199 | 0x93, 0x73, 0xbc, 0x1f, 0xed, 0x8c, 0x9c, 0x1e, 0x47, 0x97, 0xec, 0x68, 200 | 0xe8, 0xf2, 0x0c, 0x6a, 0x2f, 0x06, 0x86, 0x85, 0x46, 0x6a, 0x2b, 0xa0, 201 | 0x62, 0xd8, 0xb2, 0xb8, 0x9e, 0x10, 0xe7, 0x6f, 0x96, 0xf5, 0x45, 0x1b, 202 | 0x0a, 0xcc, 0xbf, 0x85, 0x13, 0x60, 0x7b, 0x46, 0x0f, 0xc9, 0xd2, 0x5c, 203 | 0x4f, 0x2c, 0xa8, 0xca, 0x47, 0x02, 0xb2, 0x6d, 0xbb, 0x08, 0x05, 0x29, 204 | 0x1b, 0xbe, 0x4a, 0x91, 0xc7, 0xdd, 0x0d, 0x48, 0x7e, 0xfc, 0x57, 0x7d, 205 | 0x67, 0xa9, 0xc7, 0xd3, 0xe3, 0xc9, 0x94, 0x81, 0xa4, 0x33, 0x26, 0x06, 206 | 0x4c, 0xd6, 0x18, 0xd1, 0x19, 0x6e, 0x5a, 0x31, 0x78, 0x10, 0xa5, 0x88, 207 | 0x30, 0xd4, 0x34, 0x68, 0x8a, 0xb1, 0x94, 0xde, 0x58, 0xee, 0x1a, 0x43, 208 | 0xab, 0x39, 0x40, 0x92, 0x38, 0x0c, 0x02, 0xcf, 0xa5, 0x80, 0x38, 0xc9, 209 | 0xe7, 0xb1, 0xf7, 0xee, 0xa1, 0xc9, 0xb9, 0x3d, 0x98, 0x18, 0x73, 0x2e, 210 | 0x22, 0x40, 0x83, 0x7a, 0xeb, 0x06, 0xfb, 0xb7, 0x2a, 0xd8, 0xce, 0x61, 211 | 0xe7, 0xcb, 0x3b, 0x67, 0x1b, 0xf5, 0x17, 0xb3, 0x81, 0xfa, 0x82, 0xa4, 212 | 0xf1, 0xc0, 0xb4, 0x60, 0x01, 0x17, 0xd4, 0xc8, 0x49, 0x29, 0x3d, 0xe2, 213 | 0x7a, 0x13, 0x8e, 0x0a, 0xac, 0xbc, 0xd2, 0x78, 0xd0, 0x68, 0x14, 0xa7, 214 | 0x1e, 0xf8, 0xd0, 0xa7, 0xf8, 0xaa, 0x95, 0x46, 0x53, 0x5e, 0x1d, 0x73, 215 | 0xd3, 0xa6, 0xce, 0x8c, 0x39, 0x6d, 0xd5, 0x71, 0xa7, 0xbb, 0x21, 0x72, 216 | 0xe4, 0x99, 0x88, 0x30, 0x38, 0xcb, 0x9f, 0x9f, 0xaf, 0x23, 0x89, 0xda, 217 | 0xf2, 0xa3, 0x43, 0xd9, 0xcc, 0x9d, 0xd9, 0x08, 0xa5, 0x09, 0xd2, 0x2e, 218 | 0xdb, 0x2d, 0x90, 0x05, 0x29, 0xff, 0x9c, 0xd3, 0x11, 0xc6, 0xe6, 0x5a, 219 | 0xbe, 0x81, 0x57, 0x14, 0xe5, 0x42, 0x82, 0x9a, 0xf7, 0x94, 0x3b, 0x10, 220 | 0x98, 0x93, 0xed, 0x80, 0x81, 0x2c, 0x08, 0x32, 0x70, 0xb7, 0x96, 0xdf, 221 | 0x4d, 0x55, 0x4f, 0x1d, 0x8d, 0xde, 0x97, 0x20, 0x46, 0xac, 0x20, 0x30, 222 | 0x66, 0x49, 0xfe, 0x4f, 0xb2, 0x72, 0xb5, 0x72, 0xa6, 0x66, 0x66, 0x62, 223 | 0x64, 0x25, 0x18, 0x2a, 0xd4, 0x66, 0xba, 0x80, 0x31, 0x5b, 0xd5, 0x41, 224 | 0xa9, 0x33, 0x4f, 0x57, 0x9d, 0x28, 0xef, 0xaf, 0x9c, 0xb1, 0x92, 0xe3, 225 | 0xd6, 0x62, 0x34, 0x22, 0x5f, 0x7d, 0x46, 0x9d, 0xcb, 0xec, 0x5e, 0xcd, 226 | 0x51, 0x98, 0xba, 0xdd, 0x3a, 0x53, 0x3a, 0xd2, 0xfb, 0xce, 0xd2, 0xc6, 227 | 0x05, 0x39, 0x94, 0x93, 0x49, 0x0c, 0xca, 0xb7, 0x69, 0xed, 0x5a, 0xb9, 228 | 0xb3, 0xde, 0x49, 0x4b, 0x05, 0x4f, 0x27, 0x68, 0xfa, 0x9e, 0x34, 0x53, 229 | 0x85, 0x6c, 0xed, 0x7c, 0x2e, 0x91, 0xe2, 0xab, 0x7a, 0xd6, 0x70, 0xef, 230 | 0x1a, 0x8f, 0x36, 0xf7, 0xfb, 0x0f, 0xe0, 0xcc, 0xab, 0x99, 0xd0, 0x3f, 231 | 0x89, 0xc8, 0xbf, 0x05, 0x81, 0x08, 0x87, 0x0a, 0x4f, 0x2a, 0xf6, 0x51, 232 | 0x26, 0xbd, 0x9f, 0x63, 0xc1, 0x59, 0x46, 0xca, 0x66, 0x3d, 0xe1, 0x02, 233 | 0x8e, 0x90, 0xe3, 0xa6, 0x97, 0xe3, 0xbc, 0x44, 0xa5, 0x7e, 0x40, 0x20, 234 | 0x4d, 0xdf, 0x34, 0x93, 0x47, 0x79, 0x80, 0x15, 0x8b, 0x19, 0x4a, 0x73, 235 | 0x56, 0x1c, 0x04, 0x5e, 0x56, 0xc2, 0x4e, 0x1a, 0x03, 0x54, 0x84, 0x8a, 236 | 0x0e, 0x33, 0xfe, 0xbc, 0x5b, 0x33, 0x16, 0x4c, 0xf5, 0xcb, 0x93, 0x36, 237 | 0x20, 0xba, 0xef, 0x30, 0xbc, 0x57, 0xe4, 0x52, 0xd2, 0x48, 0xdc, 0x68, 238 | 0x42, 0x06, 0x0e, 0xec, 0x6a, 0x8f, 0xaf, 0xc4, 0x66, 0xca, 0x7b, 0xec, 239 | 0xe7, 0x19, 0xc3, 0xf6, 0xe5, 0x1a, 0x86, 0xc0, 0xdd, 0x83, 0x35, 0x34, 240 | 0x2a, 0xa9, 0xc7, 0x42, 0x44, 0xa2, 0xe8, 0x7b, 0x1d, 0x2c, 0xd2, 0xf9, 241 | 0x61, 0x8a, 0xb3, 0x02, 0x60, 0x67, 0x91, 0xe5, 0x8a, 0xb7, 0xf6, 0x93, 242 | 0xb6, 0xcc, 0x44, 0xc1, 0x62, 0x81, 0x22, 0x71, 0x24, 0x35, 0x86, 0xf9, 243 | 0xf7, 0x68, 0x87, 0x7c, 0x76, 0x69, 0x0c, 0x64, 0x73, 0x98, 0x9f, 0xfa, 244 | 0xd6, 0xd9, 0x10, 0xf1, 0x36, 0xac, 0x91, 0x3e, 0xd5, 0x75, 0x8d, 0xc3, 245 | 0xae, 0x12, 0x40, 0x31, 0x39, 0xfd, 0x83, 0xe3, 0xd0, 0x32, 0x6b, 0x1c, 246 | 0xfe, 0xd2, 0x15, 0xfe, 0x15, 0x05, 0x08, 0x2d, 0xd2, 0x05, 0x1a, 0x9e, 247 | 0xcc, 0x3a, 0xe8, 0xb6, 0x6f, 0xe6, 0x87, 0x52, 0xc8, 0xd4, 0x36, 0x58, 248 | 0x3f, 0xa8, 0xc1, 0x56, 0xa5, 0xea, 0x0a, 0x8d, 0x53, 0x21, 0xd5, 0xfe, 249 | 0xeb, 0xe9, 0x5b, 0x69, 0x23, 0x2b, 0x87, 0x10, 0xb2, 0xd7, 0xa4, 0xb8, 250 | 0x41, 0x72, 0xff, 0xe5, 0xb8, 0x38, 0x83, 0x53, 0xb9, 0xbb, 0x44, 0xf2, 251 | 0x33, 0x9b, 0xf8, 0xb7, 0x72, 0x0b, 0x49, 0x9c, 0x92, 0x72, 0x6c, 0x84, 252 | 0x69, 0x55, 0x17, 0x85, 0xa2, 0x62, 0x28, 0xa2, 0x58, 0xf0, 0xd1, 0xa5, 253 | 0x7f, 0x2e, 0x6d, 0xc2, 0xa0, 0x49, 0x21, 0x69, 0x98, 0x02, 0x14, 0x5a, 254 | 0x46, 0x80, 0x5c, 0xc2, 0x0c, 0x2d, 0x67, 0x3a, 0xb7, 0x6e, 0xe3, 0x3f, 255 | 0xc7, 0xeb, 0x4f, 0x69, 0xc7, 0xa1, 0xbd, 0x3f, 0x4b, 0x11, 0x02, 0x07, 256 | 0xdc, 0x32, 0xd5, 0x44, 0x4f, 0x63, 0xcc, 0x73, 0x1c, 0xa1, 0x27, 0x8a, 257 | 0xd8, 0x39, 0x7c, 0x61, 0x98, 0xd1, 0xb1, 0x98, 0x33, 0x86, 0x03, 0x1e, 258 | 0xc0, 0xf0, 0x98, 0x0a, 0x21, 0xc5, 0x8b, 0x45, 0xca, 0x27, 0xbd, 0x9a, 259 | 0xb3, 0x1e, 0x0e, 0x2c, 0x92, 0xef, 0x1d, 0xf4, 0x8b, 0xa6, 0x57, 0x32, 260 | 0x06, 0x03, 0x07, 0xd3, 0x0f, 0xbd, 0x39, 0x5e, 0xb1, 0x52, 0x17, 0xc4, 261 | 0x14, 0x5a, 0xf9, 0xc8, 0xe8, 0x4d, 0xbd, 0x9c, 0x1d, 0x23, 0x1f, 0x74, 262 | 0x69, 0xb3, 0x02, 0x0e, 0x9e, 0xaa, 0x58, 0x59, 0xe4, 0xd1, 0x90, 0xac, 263 | 0x07, 0x54, 0x3c, 0x23, 0x71, 0xfc, 0x40, 0x96, 0xa2, 0xc1, 0xca, 0x62, 264 | 0x09, 0x7a, 0x66, 0x5f, 0xd6, 0x77, 0xdb, 0x64, 0x99, 0x80, 0xe7, 0x2f, 265 | 0x8b, 0x55, 0x4c, 0x52, 0x73, 0x1d, 0x2d, 0xe3, 0x54, 0xf0, 0x1a, 0x5e, 266 | 0xcb, 0x78, 0x57, 0x91, 0xe3, 0x56, 0xcd, 0x54, 0x7f, 0xd1, 0x3d, 0x4d, 267 | 0x59, 0xa9, 0x26, 0x66, 0xae, 0x0d, 0x2d, 0x43, 0x18, 0x89, 0xe4, 0xeb, 268 | 0xbd, 0xda, 0xb5, 0xe1, 0x3d, 0x2f, 0x82, 0x25, 0x29, 0xd4, 0xa2, 0x96, 269 | 0xa6, 0x47, 0xaa, 0x90, 0xb0, 0x16, 0x05, 0x77, 0xc1, 0xbd, 0x4d, 0x2a, 270 | 0x3c, 0xb1, 0x7d, 0xfd, 0xa8, 0x83, 0x85, 0xc3, 0x14, 0xae, 0xd6, 0xd5, 271 | 0x7b, 0xbc, 0x65, 0x57, 0x75, 0xf5, 0xf1, 0xff, 0x3e, 0xd9, 0x20, 0x09, 272 | 0x28, 0xff, 0x9b, 0x53, 0xa7, 0x5f, 0xf6, 0xca, 0x74, 0xa3, 0x2d, 0x40, 273 | 0xbd, 0x17, 0xed, 0x23, 0xa1, 0x82, 0x2b, 0x48, 0x4b, 0x12, 0xc4, 0xb7, 274 | 0x8c, 0x3f, 0xe2, 0x58, 0x8a, 0xe2, 0x87, 0x6a, 0xfe, 0x20, 0xaa, 0x3d, 275 | 0xe1, 0x16, 0xcd, 0x75, 0x94, 0x6c, 0x5b, 0xbd, 0x69, 0xb8, 0xc4, 0x10, 276 | 0x8f, 0x12, 0x6a, 0xdb, 0xa5, 0x69, 0x06, 0x1d, 0x15, 0x17, 0x73, 0x44, 277 | 0x0e, 0xa2, 0x42, 0x85, 0x2b, 0xa7, 0x1e, 0x59, 0xd9, 0xfe, 0xcf, 0x70, 278 | 0x6b, 0x21, 0x30, 0x1c, 0xc7, 0xd7, 0x7c, 0x33, 0x7d, 0xc9, 0x21, 0x74, 279 | 0x58, 0x49, 0x1f, 0xcc, 0x29, 0x16, 0x07, 0x2a, 0x27, 0xfa, 0x33, 0xa6, 280 | 0x4b, 0x8b, 0xa7, 0x17, 0xc8, 0x24, 0xfe, 0xfe, 0xc0, 0x27, 0xcc, 0x3a, 281 | 0x8c, 0x09, 0x1d, 0xea, 0x44, 0x0e, 0x64, 0x0f, 0x6e, 0xbc, 0x65, 0xef, 282 | 0xdc, 0x81, 0x93, 0xe8, 0xf8, 0xae, 0x2a, 0xb0, 0x96, 0x81, 0x9b, 0x31, 283 | 0x2b, 0xcd, 0x0e, 0x39, 0x73, 0x77, 0x6a, 0xf3, 0x14, 0x74, 0x16, 0xc1, 284 | 0x14, 0x23, 0xa3, 0x2a, 0xe9, 0x5d, 0xe9, 0xed, 0x2d, 0xbe, 0x48, 0x16, 285 | 0xd5, 0x4f, 0xc4, 0xa3, 0xdb, 0x86, 0x5c, 0x47, 0xa7, 0x39, 0x7d, 0x41, 286 | 0x4a, 0xed, 0xa1, 0x49, 0xec, 0xa2, 0xd5, 0x2b, 0x11, 0x02, 0xf1, 0xc0, 287 | 0xda, 0xff, 0xdb, 0x0a, 0x27, 0xed, 0x96, 0xc0, 0x45, 0x0f, 0xfa, 0x56, 288 | 0xd1, 0xa8, 0x1e, 0x3f, 0xa6, 0x78, 0x30, 0x83, 0x02, 0x7f, 0x20, 0x03, 289 | 0x7f, 0x9f, 0xc7, 0xf0, 0x70, 0x18, 0xc6, 0x3e, 0x7f, 0x5d, 0xcc, 0xa6, 290 | 0x7b, 0xdd, 0xc9, 0xb2, 0xc8, 0x8f, 0x0d, 0xf4, 0x4f, 0x18, 0x20, 0x06, 291 | 0x12, 0xbb, 0x22, 0x91, 0x84, 0xd4, 0xe2, 0xf1, 0x7f, 0x8d, 0x24, 0x5f, 292 | 0x7e, 0xfc, 0x01, 0xdf, 0x94, 0x0c, 0x7f, 0x7e, 0x2b, 0x18, 0xa1, 0xf3, 293 | 0x0a, 0xde, 0x2d, 0xee, 0x7c, 0xc7, 0xd9, 0x19, 0xc1, 0xd6, 0xe0, 0x05, 294 | 0x9c, 0x22, 0x5b, 0x85, 0x20, 0x32, 0x35, 0xc4, 0x13, 0x27, 0xb6, 0x10, 295 | 0xaa, 0x23, 0x37, 0xb6, 0xfc, 0x82, 0x1b, 0x2c, 0xa0, 0x66, 0x2e, 0x73, 296 | 0x48, 0xae, 0x3a, 0x23, 0x7a, 0x1e, 0xda, 0x56, 0xe1, 0xc7, 0x48, 0x6b, 297 | 0x7a, 0x7c, 0x91, 0x82, 0x04, 0x19, 0x0d, 0x1f, 0x9c, 0x77, 0x3e, 0x99, 298 | 0x81, 0x22, 0x28, 0x4d, 0xae, 0x49, 0xa6, 0x12, 0x66, 0x9f, 0x4b, 0x7f, 299 | 0x28, 0x17, 0xef, 0x5d, 0xeb, 0x51, 0x86, 0x00, 0x44, 0xee, 0xb6, 0x30, 300 | 0x93, 0x0d, 0x49, 0x2c, 0x7a, 0x06, 0xee, 0x3e, 0xbf, 0x74, 0x25, 0xff, 301 | 0x40, 0xc6, 0x8c, 0x57, 0x61, 0xf6, 0x0e, 0xd8, 0xf7, 0x1e, 0xbd, 0xe9, 302 | 0xbf, 0x4e, 0xfb, 0x97, 0x6e, 0xc5, 0x51, 0xe7, 0x04, 0xe5, 0x90, 0x44, 303 | 0x4c, 0x49, 0xc6, 0x88, 0xa6, 0x6e, 0x20, 0x98, 0x5f, 0xd4, 0x3b, 0x39, 304 | 0xff, 0xcc, 0xb8, 0x33, 0x0e, 0x96, 0xdf, 0x1c, 0x33, 0x24, 0x73, 0x75, 305 | 0x07, 0xb2, 0x00, 0x1a, 0x70, 0x67, 0xf5, 0xcb, 0x74, 0x30, 0xfe, 0xa3, 306 | 0xe4, 0x16, 0x08, 0x7f, 0x4e, 0x9e, 0x99, 0xd1, 0xae, 0x79, 0x8b, 0x80, 307 | 0x70, 0xe9, 0x02, 0xea, 0x69, 0x3d, 0xc9, 0xec, 0x0e, 0x6a, 0x77, 0x2f, 308 | 0x04, 0xac, 0x23, 0xcf, 0xec, 0xce, 0xcc, 0x12, 0xa5, 0x94, 0xe6, 0x91, 309 | 0xc1, 0xf6, 0xc7, 0x24, 0x15, 0x7a, 0x41, 0xca, 0x63, 0x11, 0xf6, 0x0a, 310 | 0xe7, 0xa3, 0x8c, 0x0f, 0x97, 0xd4, 0x91, 0x76, 0x61, 0x37, 0x29, 0xa3, 311 | 0x9d, 0x2b, 0x71, 0xc4, 0x03, 0xfe, 0x21, 0xbe, 0x6b, 0x43, 0x3d, 0x95, 312 | 0xf5, 0x7b, 0x0f, 0x21, 0x52, 0x27, 0x0a, 0x10, 0x99, 0x05, 0x88, 0xd4, 313 | 0x32, 0xd8, 0xa2, 0xca, 0x87, 0x0e, 0x8a, 0xb9, 0x58, 0x11, 0x6b, 0xbb, 314 | 0x47, 0xbf, 0xaa, 0x7b, 0x47, 0x9a, 0xde, 0x6c, 0x22, 0xd8, 0xf5, 0x4c, 315 | 0x41, 0x04, 0xce, 0x21, 0xe0, 0xe4, 0x46, 0x47, 0x82, 0x0e, 0xdf, 0x9c, 316 | 0xf0, 0xb4, 0xb7, 0x4c, 0x0b, 0x9e, 0x7e, 0x17, 0xc1, 0x37, 0xc7, 0x22, 317 | 0x9a, 0x14, 0x8b, 0x3e, 0x25, 0x11, 0x13, 0xa5, 0x6b, 0x8b, 0xc5, 0xed, 318 | 0xf0, 0x05, 0x52, 0x90, 0x1f, 0x58, 0x66, 0x61, 0x73, 0xb6, 0x3f, 0x7b, 319 | 0xc5, 0xe9, 0xf8, 0xc5, 0x30, 0xdc, 0x8f, 0x40, 0x9c, 0x20, 0x95, 0x9a, 320 | 0x0e, 0xa1, 0xda, 0x15, 0x7f, 0x06, 0xd9, 0x17, 0x32, 0xcf, 0x04, 0x40, 321 | 0xeb, 0xe9, 0x31, 0x8a, 0xd7, 0x92, 0x64, 0x35, 0x37, 0xc0, 0x99, 0xb8, 322 | 0xfc, 0x01, 0x0f, 0x74, 0x5d, 0x8b, 0x6e, 0xfa, 0x0d, 0xd8, 0x6b, 0xad, 323 | 0x1b, 0x21, 0x67, 0xa8, 0x3b, 0x90, 0xad, 0xc6, 0x2d, 0x61, 0xb3, 0x70, 324 | 0xd1, 0xa1, 0x25, 0xea, 0xc0, 0x4e, 0x01, 0x41, 0x03, 0xee, 0x82, 0x45, 325 | 0xaa, 0x77, 0xbb, 0x21, 0x1a, 0xb1, 0x02, 0xa8, 0x36, 0x79, 0xff, 0x25, 326 | 0xe2, 0x13, 0x51, 0xa9, 0x91, 0x18, 0xad, 0x24, 0x08, 0x09, 0xe8, 0x31, 327 | 0x7f, 0xeb, 0xc4, 0x44, 0xe1, 0x52, 0x5b, 0xea, 0x67, 0x2a, 0x1b, 0x68, 328 | 0xc9, 0x5a, 0x4b, 0x63, 0x29, 0x72, 0xdd, 0x46, 0x5e, 0x8d, 0x7e, 0x02, 329 | 0x62, 0xec, 0x0c, 0x1d, 0x9c, 0x92, 0x34, 0xf1, 0x9e, 0xcc, 0x66, 0x17, 330 | 0x8e, 0x56, 0x24, 0xaa, 0xd4, 0x8c, 0xc7, 0x79, 0x99, 0x33, 0x3f, 0xbc, 331 | 0xfb, 0xa8, 0xfa, 0xec, 0x57, 0xd9, 0x5c, 0xf6, 0x31, 0xc0, 0x17, 0x67, 332 | 0x7d, 0xec, 0x2f, 0xa6, 0x0d, 0xb4, 0x8b, 0x8a, 0xbc, 0x36, 0x6c, 0xb9, 333 | 0x3e, 0xf5, 0x6b, 0x36, 0x1a, 0xd5, 0x05, 0xde, 0x7c, 0x35, 0x97, 0x7d, 334 | 0x05, 0xed, 0xd8, 0x41, 0x43, 0xd4, 0x1f, 0xa1, 0xf8, 0xf5, 0xae, 0xc8, 335 | 0xb9, 0xc6, 0x60, 0xbc, 0x7f, 0xda, 0x60, 0x3f, 0x77, 0xda, 0x42, 0x90, 336 | 0x37, 0xce, 0xd6, 0x19, 0x8f, 0x7c, 0xe6, 0x0d, 0x6e, 0xcb, 0xd0, 0x0b, 337 | 0x1c, 0x59, 0xc2, 0x99, 0x0c, 0x08, 0x99, 0x2f, 0xe0, 0x51, 0x43, 0x26, 338 | 0x98, 0x12, 0x6b, 0x96, 0xca, 0x16, 0x63, 0x48, 0x01, 0xe0, 0xe7, 0xb7, 339 | 0x27, 0xd1, 0x36, 0x80, 0xe6, 0x9c, 0x96, 0x4b, 0x35, 0xb9, 0x1c, 0x4a, 340 | 0x1f, 0x2a, 0xcc, 0xe2, 0x02, 0xc3, 0xc0, 0xfb, 0x29, 0x0b, 0xa3, 0x18, 341 | 0xb6, 0x48, 0x5d, 0x9c, 0x52, 0x16, 0xdd, 0xf5, 0x33, 0x3f, 0x18, 0xa4, 342 | 0x3c, 0x35, 0xd2, 0x25, 0xba, 0xab, 0xb6, 0xb2, 0x43, 0x99, 0xf5, 0x17, 343 | 0x99, 0x92, 0x0b, 0x88, 0x25, 0x76, 0xe7, 0xd3, 0x70, 0xa8, 0x23, 0xe2, 344 | 0xb1, 0x56, 0xa5, 0xef, 0x60, 0xa6, 0x9f, 0xb2, 0x85, 0xab, 0xb2, 0x3a, 345 | 0xcc, 0x30, 0x4a, 0x13, 0x8a, 0x90, 0x67, 0x46, 0x71, 0x1b, 0xc1, 0x48, 346 | 0x85, 0x8c, 0xfa, 0x75, 0x50, 0xd2, 0xd6, 0x81, 0xc3, 0x0d, 0x96, 0x63, 347 | 0x28, 0x22, 0x83, 0x94, 0xd0, 0xab, 0xe8, 0x3d, 0x1a, 0xa0, 0x40, 0x91, 348 | 0x26, 0x0b, 0xf0, 0x8f, 0xd5, 0x96, 0x64, 0x3e, 0x68, 0x12, 0xbc, 0x9e, 349 | 0x52, 0xd6, 0x17, 0x80, 0x09, 0xa3, 0x02, 0x28, 0xb1, 0x19, 0x6c, 0xf9, 350 | 0x7c, 0x8a, 0x34, 0x11, 0xfc, 0xcb, 0x31, 0xed, 0x22, 0xbc, 0x8a, 0x83, 351 | 0x23, 0x2d, 0xff, 0x63, 0xe6, 0x69, 0x5b, 0xb3, 0x74, 0xb3, 0x04, 0xeb, 352 | 0x27, 0xa9, 0x1e, 0xf3, 0xf3, 0x6d, 0x1c, 0x2a, 0xb1, 0x51, 0x84, 0xd0, 353 | 0x3e, 0xe9, 0x3e, 0x2a, 0x5f, 0xea, 0x2c, 0xb5, 0xcc, 0xe1, 0xd3, 0x8f, 354 | 0xc5, 0x28, 0x26, 0x62, 0xde, 0xbb, 0x0d, 0xdb, 0xa3, 0xe5, 0xed, 0x96, 355 | 0x55, 0xc4, 0xe8, 0xb5, 0x0f, 0x89, 0x45, 0x43, 0x4f, 0x8f, 0x8c, 0x9a, 356 | 0x77, 0x3b, 0xc1, 0xac 357 | }; 358 | 359 | -------------------------------------------------------------------------------- /foulplay/README.md: -------------------------------------------------------------------------------- 1 | # foulplay 2 | 3 | Decrypt FairPlay encrypted binaries on macOS when SIP-enabled. 4 | 5 | By mapping an executable as r-x and then using `mremap_encrypted` on the encrypted 6 | page(s) and then writing them back out to disk, you can fully decrypt FairPlay 7 | binaries. 8 | 9 | This was discovered independently when analyzing kernel sources, but it appears 10 | that the technique was first introduced on iOS (but now works on macOS): https://github.com/JohnCoates/flexdecrypt 11 | -------------------------------------------------------------------------------- /foulplay/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | extern int mremap_encrypted(void*, size_t, uint32_t, uint32_t, uint32_t); 14 | 15 | static int 16 | unprotect(int f, uint8_t *dupe, struct encryption_info_command_64 *info) 17 | { 18 | void *base = mmap(NULL, info->cryptsize, PROT_READ | PROT_EXEC, MAP_PRIVATE, f, info->cryptoff); 19 | if (base == MAP_FAILED) { 20 | perror("mmap"); 21 | return 1; 22 | } 23 | 24 | int error = mremap_encrypted(base, info->cryptsize, info->cryptid, 25 | CPU_TYPE_ARM64, CPU_SUBTYPE_ARM64_ALL); 26 | if (error) { 27 | perror("mremap_encrypted"); 28 | munmap(base, info->cryptsize); 29 | return 1; 30 | } 31 | 32 | memcpy(dupe + info->cryptoff, base, info->cryptsize); 33 | 34 | munmap(base, info->cryptsize); 35 | return 0; 36 | } 37 | 38 | static uint8_t* 39 | map(const char *path, bool mutable, size_t *size, int *descriptor) 40 | { 41 | int f = open(path, mutable ? O_RDWR : O_RDONLY); 42 | if (f < 0) { 43 | perror("open"); 44 | return NULL; 45 | } 46 | 47 | struct stat s; 48 | if (fstat(f, &s) < 0) { 49 | perror("fstat"); 50 | close(f); 51 | return NULL; 52 | } 53 | 54 | uint8_t *base = mmap(NULL, s.st_size, mutable ? PROT_READ | PROT_WRITE : PROT_READ, 55 | mutable ? MAP_SHARED : MAP_PRIVATE, f, 0); 56 | if (base == MAP_FAILED) { 57 | perror("mmap"); 58 | close(f); 59 | return NULL; 60 | } 61 | 62 | *size = s.st_size; 63 | if (descriptor) { 64 | *descriptor = f; 65 | } else { 66 | close(f); 67 | } 68 | return base; 69 | } 70 | 71 | int 72 | main(int argc, char* argv[]) 73 | { 74 | if (argc < 3) { 75 | return 1; 76 | } 77 | 78 | size_t base_size; 79 | int f; 80 | uint8_t *base = map(argv[1], false, &base_size, &f); 81 | if (base == NULL) { 82 | return 1; 83 | } 84 | 85 | size_t dupe_size; 86 | uint8_t *dupe = map(argv[2], true, &dupe_size, NULL); 87 | if (dupe == NULL) { 88 | munmap(base, base_size); 89 | return 1; 90 | } 91 | 92 | // If the files are not of the same size, then they are not duplicates of 93 | // each other, which is an error. 94 | // 95 | if (base_size != dupe_size) { 96 | munmap(base, base_size); 97 | munmap(dupe, dupe_size); 98 | return 1; 99 | } 100 | 101 | struct mach_header_64* header = (struct mach_header_64*) base; 102 | assert(header->magic == MH_MAGIC_64); 103 | assert(header->cputype == CPU_TYPE_ARM64); 104 | assert(header->cpusubtype == CPU_SUBTYPE_ARM64_ALL); 105 | 106 | uint32_t offset = sizeof(struct mach_header_64); 107 | 108 | // Enumerate all load commands and check for the encryption header, if found 109 | // start "unprotect"'ing the contents. 110 | // 111 | for (uint32_t i = 0; i < header->ncmds; i++) { 112 | struct load_command* command = (struct load_command*) (base + offset); 113 | 114 | if (command->cmd == LC_ENCRYPTION_INFO_64) { 115 | struct encryption_info_command_64 *encryption_info = 116 | (struct encryption_info_command_64*) command; 117 | // If "unprotect"'ing is successful, then change the "cryptid" so that 118 | // the loader does not attempt to decrypt decrypted pages. 119 | // 120 | if (unprotect(f, dupe, encryption_info) == 0) { 121 | encryption_info = (struct encryption_info_command_64*) (dupe + offset); 122 | encryption_info->cryptid = 0; 123 | } 124 | // There should only be ONE header present anyways, so stop after 125 | // the first one. 126 | // 127 | break; 128 | } 129 | 130 | offset += command->cmdsize; 131 | } 132 | 133 | munmap(base, base_size); 134 | munmap(dupe, dupe_size); 135 | return 0; 136 | } 137 | -------------------------------------------------------------------------------- /foulplay/meson.build: -------------------------------------------------------------------------------- 1 | project('foulplay', 'c', 2 | version: '0.1.0', 3 | ) 4 | 5 | executable('foulplay', 6 | sources: ['main.c'], 7 | ) 8 | -------------------------------------------------------------------------------- /kdumpd/.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | kdumpd 3 | -------------------------------------------------------------------------------- /kdumpd/LICENSE: -------------------------------------------------------------------------------- 1 | APPLE PUBLIC SOURCE LICENSE 2 | Version 1.0 - March 16, 1999 3 | 4 | Please read this License carefully before downloading this software. 5 | By downloading and using this software, you are agreeing to be bound 6 | by the terms of this License. If you do not or cannot agree to the 7 | terms of this License, please do not download or use the software. 8 | 9 | 1. General; Definitions. This License applies to any program or other 10 | work which Apple Computer, Inc. ("Apple") publicly announces as 11 | subject to this Apple Public Source License and which contains a 12 | notice placed by Apple identifying such program or work as "Original 13 | Code" and stating that it is subject to the terms of this Apple 14 | Public Source License version 1.0 (or subsequent version thereof), 15 | as it may be revised from time to time by Apple ("License"). As 16 | used in this License: 17 | 18 | 1.1 "Applicable Patents" mean: (a) in the case where Apple is the 19 | grantor of rights, (i) patents or patent applications that are now 20 | or hereafter acquired, owned by or assigned to Apple and (ii) whose 21 | claims cover subject matter contained in the Original Code, but only 22 | to the extent necessary to use, reproduce and/or distribute the 23 | Original Code without infringement; and (b) in the case where You 24 | are the grantor of rights, (i) patents and patent applications that 25 | are now or hereafter acquired, owned by or assigned to You and (ii) 26 | whose claims cover subject matter in Your Modifications, taken alone 27 | or in combination with Original Code. 28 | 29 | 1.2 "Covered Code" means the Original Code, Modifications, the 30 | combination of Original Code and any Modifications, and/or any 31 | respective portions thereof. 32 | 33 | 1.3 "Deploy" means to use, sublicense or distribute Covered Code other 34 | than for Your internal research and development (R&D), and includes 35 | without limitation, any and all internal use or distribution of 36 | Covered Code within Your business or organization except for R&D 37 | use, as well as direct or indirect sublicensing or distribution of 38 | Covered Code by You to any third party in any form or manner. 39 | 40 | 1.4 "Larger Work" means a work which combines Covered Code or portions 41 | thereof with code not governed by the terms of this License. 42 | 43 | 1.5 "Modifications" mean any addition to, deletion from, and/or change 44 | to, the substance and/or structure of Covered Code. When code is 45 | released as a series of files, a Modification is: (a) any addition 46 | to or deletion from the contents of a file containing Covered Code; 47 | and/or (b) any new file or other representation of computer program 48 | statements that contains any part of Covered Code. 49 | 50 | 1.6 "Original Code" means the Source Code of a program or other work 51 | as originally made available by Apple under this License, including 52 | the Source Code of any updates or upgrades to such programs or works 53 | made available by Apple under this License, and that has been 54 | expressly identified by Apple as such in the header file(s) of such 55 | work. 56 | 57 | 1.7 "Source Code" means the human readable form of a program or other 58 | work that is suitable for making modifications to it, including all 59 | modules it contains, plus any associated interface definition files, 60 | scripts used to control compilation and installation of an 61 | executable (object code). 62 | 63 | 1.8 "You" or "Your" means an individual or a legal entity exercising 64 | rights under this License. For legal entities, "You" or "Your" 65 | includes any entity which controls, is controlled by, or is under 66 | common control with, You, where "control" means (a) the power, 67 | direct or indirect, to cause the direction or management of such 68 | entity, whether by contract or otherwise, or (b) ownership of fifty 69 | percent (50%) or more of the outstanding shares or beneficial 70 | ownership of such entity. 71 | 72 | 2. Permitted Uses; Conditions & Restrictions. Subject to the terms 73 | and conditions of this License, Apple hereby grants You, effective 74 | on the date You accept this License and download the Original Code, 75 | a world-wide, royalty-free, non-exclusive license, to the extent of 76 | Apple's Applicable Patents and copyrights covering the Original 77 | Code, to do the following: 78 | 79 | 2.1 You may use, copy, modify and distribute Original Code, with or 80 | without Modifications, solely for Your internal research and 81 | development, provided that You must in each instance: 82 | 83 | (a) retain and reproduce in all copies of Original Code the copyright 84 | and other proprietary notices and disclaimers of Apple as they appear 85 | in the Original Code, and keep intact all notices in the Original Code 86 | that refer to this License; 87 | 88 | (b) include a copy of this License with every copy of Source Code of 89 | Covered Code and documentation You distribute, and You may not offer 90 | or impose any terms on such Source Code that alter or restrict this 91 | License or the recipients' rights hereunder, except as permitted under 92 | Section 6; and 93 | 94 | (c) completely and accurately document all Modifications that you have 95 | made and the date of each such Modification, designate the version of 96 | the Original Code you used, prominently include a file carrying such 97 | information with the Modifications, and duplicate the notice in 98 | Exhibit A in each file of the Source Code of all such Modifications. 99 | 100 | 2.2 You may Deploy Covered Code, provided that You must in each 101 | instance: 102 | 103 | (a) satisfy all the conditions of Section 2.1 with respect to the 104 | Source Code of the Covered Code; 105 | 106 | (b) make all Your Deployed Modifications publicly available in Source 107 | Code form via electronic distribution (e.g. download from a web site) 108 | under the terms of this License and subject to the license grants set 109 | forth in Section 3 below, and any additional terms You may choose to 110 | offer under Section 6. You must continue to make the Source Code of 111 | Your Deployed Modifications available for as long as you Deploy the 112 | Covered Code or twelve (12) months from the date of initial 113 | Deployment, whichever is longer; 114 | 115 | (c) must notify Apple and other third parties of how to obtain Your 116 | Deployed Modifications by filling out and submitting the required 117 | information found at 118 | http://www.apple.com/publicsource/modifications.html; and 119 | 120 | (d) if you Deploy Covered Code in object code, executable form only, 121 | include a prominent notice, in the code itself as well as in related 122 | documentation, stating that Source Code of the Covered Code is 123 | available under the terms of this License with information on how and 124 | where to obtain such Source Code. 125 | 126 | 3. Your Grants. In consideration of, and as a condition to, the 127 | licenses granted to You under this License: 128 | 129 | (a) You hereby grant to Apple and all third parties a non-exclusive, 130 | royalty-free license, under Your Applicable Patents and other 131 | intellectual property rights owned or controlled by You, to use, 132 | reproduce, modify, distribute and Deploy Your Modifications of the 133 | same scope and extent as Apple's licenses under Sections 2.1 and 2.2; 134 | and 135 | 136 | (b) You hereby grant to Apple and its subsidiaries a non-exclusive, 137 | worldwide, royalty-free, perpetual and irrevocable license, under Your 138 | Applicable Patents and other intellectual property rights owned or 139 | controlled by You, to use, reproduce, execute, compile, display, 140 | perform, modify or have modified (for Apple and/or its subsidiaries), 141 | sublicense and distribute Your Modifications, in any form, through 142 | multiple tiers of distribution. 143 | 144 | 4. Larger Works. You may create a Larger Work by combining Covered 145 | Code with other code not governed by the terms of this License and 146 | distribute the Larger Work as a single product. In each such 147 | instance, You must make sure the requirements of this License are 148 | fulfilled for the Covered Code or any portion thereof. 149 | 150 | 5. Limitations on Patent License. Except as expressly stated in 151 | Section 2, no other patent rights, express or implied, are granted 152 | by Apple herein. Modifications and/or Larger Works may require 153 | additional patent licenses from Apple which Apple may grant in its 154 | sole discretion. 155 | 156 | 6. Additional Terms. You may choose to offer, and to charge a fee 157 | for, warranty, support, indemnity or liability obligations and/or 158 | other rights consistent with the scope of the license granted herein 159 | ("Additional Terms") to one or more recipients of Covered 160 | Code. However, You may do so only on Your own behalf and as Your 161 | sole responsibility, and not on behalf of Apple. You must obtain the 162 | recipient's agreement that any such Additional Terms are offered by 163 | You alone, and You hereby agree to indemnify, defend and hold Apple 164 | harmless for any liability incurred by or claims asserted against 165 | Apple by reason of any such Additional Terms. 166 | 167 | 7. Versions of the License. Apple may publish revised and/or new 168 | versions of this License from time to time. Each version will be 169 | given a distinguishing version number. Once Original Code has been 170 | published under a particular version of this License, You may 171 | continue to use it under the terms of that version. You may also 172 | choose to use such Original Code under the terms of any subsequent 173 | version of this License published by Apple. No one other than Apple 174 | has the right to modify the terms applicable to Covered Code created 175 | under this License. 176 | 177 | 8. NO WARRANTY OR SUPPORT. The Original Code may contain in whole or 178 | in part pre-release, untested, or not fully tested works. The 179 | Original Code may contain errors that could cause failures or loss 180 | of data, and may be incomplete or contain inaccuracies. You 181 | expressly acknowledge and agree that use of the Original Code, or 182 | any portion thereof, is at Your sole and entire risk. THE ORIGINAL 183 | CODE IS PROVIDED "AS IS" AND WITHOUT WARRANTY, UPGRADES OR SUPPORT 184 | OF ANY KIND AND APPLE AND APPLE'S LICENSOR(S) (FOR THE PURPOSES OF 185 | SECTIONS 8 AND 9, APPLE AND APPLE'S LICENSOR(S) ARE COLLECTIVELY 186 | REFERRED TO AS "APPLE") EXPRESSLY DISCLAIM ALL WARRANTIES AND/OR 187 | CONDITIONS, EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE 188 | IMPLIED WARRANTIES AND/OR CONDITIONS OF MERCHANTABILITY OR 189 | SATISFACTORY QUALITY AND FITNESS FOR A PARTICULAR PURPOSE AND 190 | NONINFRINGEMENT OF THIRD PARTY RIGHTS. APPLE DOES NOT WARRANT THAT 191 | THE FUNCTIONS CONTAINED IN THE ORIGINAL CODE WILL MEET YOUR 192 | REQUIREMENTS, OR THAT THE OPERATION OF THE ORIGINAL CODE WILL BE 193 | UNINTERRUPTED OR ERROR-FREE, OR THAT DEFECTS IN THE ORIGINAL CODE 194 | WILL BE CORRECTED. NO ORAL OR WRITTEN INFORMATION OR ADVICE GIVEN 195 | BY APPLE OR AN APPLE AUTHORIZED REPRESENTATIVE SHALL CREATE A 196 | WARRANTY OR IN ANY WAY INCREASE THE SCOPE OF THIS WARRANTY. You 197 | acknowledge that the Original Code is not intended for use in the 198 | operation of nuclear facilities, aircraft navigation, communication 199 | systems, or air traffic control machines in which case the failure 200 | of the Original Code could lead to death, personal injury, or severe 201 | physical or environmental damage. 202 | 203 | 9. Liability. 204 | 205 | 9.1 Infringement. If any of the Original Code becomes the subject of 206 | a claim of infringement ("Affected Original Code"), Apple may, at 207 | its sole discretion and option: (a) attempt to procure the rights 208 | necessary for You to continue using the Affected Original Code; (b) 209 | modify the Affected Original Code so that it is no longer 210 | infringing; or (c) terminate Your rights to use the Affected 211 | Original Code, effective immediately upon Apple's posting of a 212 | notice to such effect on the Apple web site that is used for 213 | implementation of this License. 214 | 215 | 9.2 LIMITATION OF LIABILITY. UNDER NO CIRCUMSTANCES SHALL APPLE BE 216 | LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT OR CONSEQUENTIAL 217 | DAMAGES ARISING OUT OF OR RELATING TO THIS LICENSE OR YOUR USE OR 218 | INABILITY TO USE THE ORIGINAL CODE, OR ANY PORTION THEREOF, WHETHER 219 | UNDER A THEORY OF CONTRACT, WARRANTY, TORT (INCLUDING NEGLIGENCE), 220 | PRODUCTS LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF 221 | THE POSSIBILITY OF SUCH DAMAGES AND NOTWITHSTANDING THE FAILURE OF 222 | ESSENTIAL PURPOSE OF ANY REMEDY. In no event shall Apple's total 223 | liability to You for all damages under this License exceed the 224 | amount of fifty dollars ($50.00). 225 | 226 | 10. Trademarks. This License does not grant any rights to use the 227 | trademarks or trade names "Apple", "Apple Computer", "Mac OS X", 228 | "Mac OS X Server" or any other trademarks or trade names belonging 229 | to Apple (collectively "Apple Marks") and no Apple Marks may be 230 | used to endorse or promote products derived from the Original Code 231 | other than as permitted by and in strict compliance at all times 232 | with Apple's third party trademark usage guidelines which are 233 | posted at http://www.apple.com/legal/guidelinesfor3rdparties.html. 234 | 235 | 11. Ownership. Apple retains all rights, title and interest in and to 236 | the Original Code and any Modifications made by or on behalf of 237 | Apple ("Apple Modifications"), and such Apple Modifications will 238 | not be automatically subject to this License. Apple may, at its 239 | sole discretion, choose to license such Apple Modifications under 240 | this License, or on different terms from those contained in this 241 | License or may choose not to license them at all. Apple's 242 | development, use, reproduction, modification, sublicensing and 243 | distribution of Covered Code will not be subject to this License. 244 | 245 | 12. Termination. 246 | 247 | 12.1 Termination. This License and the rights granted hereunder will 248 | terminate: 249 | 250 | (a) automatically without notice from Apple if You fail to comply with 251 | any term(s) of this License and fail to cure such breach within 30 252 | days of becoming aware of such breach; (b) immediately in the event of 253 | the circumstances described in Sections 9.1 and/or 13.6(b); or (c) 254 | automatically without notice from Apple if You, at any time during the 255 | term of this License, commence an action for patent infringement 256 | against Apple. 257 | 258 | 12.2 Effect of Termination. Upon termination, You agree to 259 | immediately stop any further use, reproduction, modification and 260 | distribution of the Covered Code, or Affected Original Code in the 261 | case of termination under Section 9.1, and to destroy all copies of 262 | the Covered Code or Affected Original Code (in the case of 263 | termination under Section 9.1) that are in your possession or 264 | control. All sublicenses to the Covered Code which have been 265 | properly granted prior to termination shall survive any termination 266 | of this License. Provisions which, by their nature, should remain 267 | in effect beyond the termination of this License shall survive, 268 | including but not limited to Sections 3, 5, 8, 9, 10, 11, 12.2 and 269 | 13. Neither party will be liable to the other for compensation, 270 | indemnity or damages of any sort solely as a result of terminating 271 | this License in accordance with its terms, and termination of this 272 | License will be without prejudice to any other right or remedy of 273 | either party. 274 | 275 | 13. Miscellaneous. 276 | 277 | 13.1 Export Law Assurances. You may not use or otherwise export or 278 | re-export the Original Code except as authorized by United States 279 | law and the laws of the jurisdiction in which the Original Code was 280 | obtained. In particular, but without limitation, the Original Code 281 | may not be exported or re-exported (a) into (or to a national or 282 | resident of) any U.S. embargoed country or (b) to anyone on the 283 | U.S. Treasury Department's list of Specially Designated Nationals 284 | or the U.S. Department of Commerce's Table of Denial Orders. By 285 | using the Original Code, You represent and warrant that You are not 286 | located in, under control of, or a national or resident of any such 287 | country or on any such list. 288 | 289 | 13.2 Government End Users. The Covered Code is a "commercial item" as 290 | defined in FAR 2.101. Government software and technical data 291 | rights in the Covered Code include only those rights customarily 292 | provided to the public as defined in this License. This customary 293 | commercial license in technical data and software is provided in 294 | accordance with FAR 12.211 (Technical Data) and 12.212 (Computer 295 | Software) and, for Department of Defense purchases, DFAR 296 | 252.227-7015 (Technical Data -- Commercial Items) and 227.7202-3 297 | (Rights in Commercial Computer Software or Computer Software 298 | Documentation). Accordingly, all U.S. Government End Users acquire 299 | Covered Code with only those rights set forth herein. 300 | 301 | 13.3 Relationship of Parties. This License will not be construed as 302 | creating an agency, partnership, joint venture or any other form of 303 | legal association between You and Apple, and You will not represent 304 | to the contrary, whether expressly, by implication, appearance or 305 | otherwise. 306 | 307 | 13.4 Independent Development. Nothing in this License will impair 308 | Apple's right to acquire, license, develop, have others develop for 309 | it, market and/or distribute technology or products that perform 310 | the same or similar functions as, or otherwise compete with, 311 | Modifications, Larger Works, technology or products that You may 312 | develop, produce, market or distribute. 313 | 314 | 13.5 Waiver; Construction. Failure by Apple to enforce any provision 315 | of this License will not be deemed a waiver of future enforcement 316 | of that or any other provision. Any law or regulation which 317 | provides that the language of a contract shall be construed against 318 | the drafter will not apply to this License. 319 | 320 | 13.6 Severability. (a) If for any reason a court of competent 321 | jurisdiction finds any provision of this License, or portion 322 | thereof, to be unenforceable, that provision of the License will be 323 | enforced to the maximum extent permissible so as to effect the 324 | economic benefits and intent of the parties, and the remainder of 325 | this License will continue in full force and effect. (b) 326 | Notwithstanding the foregoing, if applicable law prohibits or 327 | restricts You from fully and/or specifically complying with 328 | Sections 2 and/or 3 or prevents the enforceability of either of 329 | those Sections, this License will immediately terminate and You 330 | must immediately discontinue any use of the Covered Code and 331 | destroy all copies of it that are in your possession or control. 332 | 333 | 13.7 Dispute Resolution. Any litigation or other dispute resolution 334 | between You and Apple relating to this License shall take place in 335 | the Northern District of California, and You and Apple hereby 336 | consent to the personal jurisdiction of, and venue in, the state 337 | and federal courts within that District with respect to this 338 | License. The application of the United Nations Convention on 339 | Contracts for the International Sale of Goods is expressly 340 | excluded. 341 | 342 | 13.8 Entire Agreement; Governing Law. This License constitutes the 343 | entire agreement between the parties with respect to the subject 344 | matter hereof. This License shall be governed by the laws of the 345 | United States and the State of California, except that body of 346 | California law concerning conflicts of law. 347 | 348 | Where You are located in the province of Quebec, Canada, the following 349 | clause applies: The parties hereby confirm that they have requested 350 | that this License and all related documents be drafted in English. Les 351 | parties ont exige que le present contrat et tous les documents 352 | connexes soient rediges en anglais. 353 | 354 | EXHIBIT A. 355 | 356 | "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights 357 | Reserved. This file contains Original Code and/or Modifications of 358 | Original Code as defined in and that are subject to the Apple Public 359 | Source License Version 1.0 (the 'License'). You may not use this file 360 | except in compliance with the License. Please obtain a copy of the 361 | License at http://www.apple.com/publicsource and read it before using 362 | this file. 363 | 364 | The Original Code and all software distributed under the License are 365 | distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 366 | EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 367 | INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 368 | FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the 369 | License for the specific language governing rights and limitations 370 | under the License." 371 | -------------------------------------------------------------------------------- /kdumpd/Makefile: -------------------------------------------------------------------------------- 1 | CFLAGS=-g 2 | LDFLAGS=-lbsd 3 | 4 | .PHONY: clean 5 | 6 | kdumpd: kdumpd.o kdumpsubs.o 7 | $(CC) $(CFLAGS) $(LDFLAGS) $^ -o $@ 8 | 9 | %.o: %.c 10 | $(CC) $(CFLAGS) $^ -c -o $@ 11 | 12 | clean: 13 | rm *.o 14 | rm kdumpd 15 | -------------------------------------------------------------------------------- /kdumpd/README.md: -------------------------------------------------------------------------------- 1 | kdumpd 2 | ====== 3 | 4 | Ported to GNU/Linux. 5 | 6 | Running: 7 | 8 | ``` 9 | sudo mkdir /PanicDumps 10 | sudo chown root /PanicDumps 11 | sudo chmod 1777 /PanicDumps 12 | ./kdumpd -w /PanicDumps 13 | ``` 14 | 15 | On the target iDevice: 16 | ``` 17 | sudo nvram boot-args="debug=0xc44 kdp_match_name=enX wdt=-1 _panicd_ip=169.254.XXX.XXX" 18 | ``` -------------------------------------------------------------------------------- /kdumpd/com.apple.kdumpd.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Disabled 6 | 7 | InitGroups 8 | 9 | Label 10 | com.apple.kdumpd 11 | ProgramArguments 12 | 13 | /usr/libexec/kdumpd 14 | /PanicDumps 15 | 16 | Sockets 17 | 18 | Listener 19 | 20 | SockServiceName 21 | 1069 22 | SockType 23 | dgram 24 | 25 | 26 | UserName 27 | nobody 28 | Umask 29 | 7 30 | inetdCompatibility 31 | 32 | Wait 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /kdumpd/kdump.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. 3 | * 4 | * @APPLE_LICENSE_HEADER_START@ 5 | * 6 | * The contents of this file constitute Original Code as defined in and 7 | * are subject to the Apple Public Source License Version 1.1 (the 8 | * "License"). You may not use this file except in compliance with the 9 | * License. Please obtain a copy of the License at 10 | * http://www.apple.com/publicsource and read it before using this file. 11 | * 12 | * This Original Code and all software distributed under the License are 13 | * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER 14 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 15 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the 17 | * License for the specific language governing rights and limitations 18 | * under the License. 19 | * 20 | * @APPLE_LICENSE_HEADER_END@ 21 | */ 22 | /* 23 | * Copyright (c) 1983, 1993 24 | * The Regents of the University of California. All rights reserved. 25 | * 26 | * Redistribution and use in source and binary forms, with or without 27 | * modification, are permitted provided that the following conditions 28 | * are met: 29 | * 1. Redistributions of source code must retain the above copyright 30 | * notice, this list of conditions and the following disclaimer. 31 | * 2. Redistributions in binary form must reproduce the above copyright 32 | * notice, this list of conditions and the following disclaimer in the 33 | * documentation and/or other materials provided with the distribution. 34 | * 3. All advertising materials mentioning features or use of this software 35 | * must display the following acknowledgement: 36 | * This product includes software developed by the University of 37 | * California, Berkeley and its contributors. 38 | * 4. Neither the name of the University nor the names of its contributors 39 | * may be used to endorse or promote products derived from this software 40 | * without specific prior written permission. 41 | * 42 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 43 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 44 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 45 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 46 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 47 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 48 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 49 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 50 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 51 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 52 | * SUCH DAMAGE. 53 | * 54 | * @(#)kdump.h 8.1 (Berkeley) 6/2/93 55 | */ 56 | 57 | #ifndef _KDUMP_H_ 58 | #define _KDUMP_H_ 59 | #ifdef __APPLE__ 60 | #include 61 | #include 62 | #include 63 | #endif 64 | 65 | /* Mac OS X kernel core dump server, based on the BSD trivial file 66 | * transfer protocol server (FreeBSD distribution), with several 67 | * modifications. This server is *not* compatible with tftp, as the 68 | * protocol has changed considerably. 69 | */ 70 | 71 | #define SEGSIZE 512 /* data segment size */ 72 | #define MAXIMUM_KDP_PKTSIZE (16384) 73 | /* 74 | * Packet types. 75 | */ 76 | #define RRQ 1 /* read request */ 77 | #define WRQ 2 /* write request */ 78 | #define DATA 3 /* data packet */ 79 | #define ACK 4 /* acknowledgement */ 80 | #define ERROR 5 /* error code */ 81 | #define KDP_SEEK 6 /* Seek to specified offset */ 82 | #define KDP_EOF 7 /* end of file */ 83 | 84 | struct kdumphdr { 85 | short th_opcode; /* packet type */ 86 | union { 87 | unsigned int tu_block; /* block # */ 88 | unsigned int tu_code; /* error code */ 89 | char tu_stuff[1]; /* request packet stuff */ 90 | } th_u; 91 | char th_data[0]; /* data or error string */ 92 | }__attribute__((packed)); 93 | 94 | #define th_block th_u.tu_block 95 | #define th_code th_u.tu_code 96 | #define th_stuff th_u.tu_stuff 97 | #define th_msg th_data 98 | 99 | /* 100 | * Error codes. 101 | */ 102 | #define EUNDEF 0 /* not defined */ 103 | #define ENOTFOUND 1 /* file not found */ 104 | #define EACCESS 2 /* access violation */ 105 | #define ENOSPACE 3 /* disk full or allocation exceeded */ 106 | #define EBADOP 4 /* illegal KDUMP operation */ 107 | #define EBADID 5 /* unknown transfer ID */ 108 | #define EEXISTS 6 /* file already exists */ 109 | #define ENOUSER 7 /* no such user */ 110 | 111 | #define DEBUG 0 112 | #define WRITE_DEBUG 0 113 | #define KDUMPD_DEBUG_LEVEL LOG_ALERT 114 | 115 | #ifdef __APPLE__ 116 | #define KDP_LARGE_CRASHDUMP_PKT_SIZE (1440 - sizeof(struct udpiphdr)) 117 | #else 118 | #define KDP_LARGE_CRASHDUMP_PKT_SIZE (1412) 119 | #endif 120 | 121 | #endif 122 | -------------------------------------------------------------------------------- /kdumpd/kdumpd.8: -------------------------------------------------------------------------------- 1 | .\" Copyright (c) 1983, 1991, 1993 2 | .\" The Regents of the University of California. All rights reserved. 3 | .\" 4 | .\" Redistribution and use in source and binary forms, with or without 5 | .\" modification, are permitted provided that the following conditions 6 | .\" are met: 7 | .\" 1. Redistributions of source code must retain the above copyright 8 | .\" notice, this list of conditions and the following disclaimer. 9 | .\" 2. Redistributions in binary form must reproduce the above copyright 10 | .\" notice, this list of conditions and the following disclaimer in the 11 | .\" documentation and/or other materials provided with the distribution. 12 | .\" 3. All advertising materials mentioning features or use of this software 13 | .\" must display the following acknowledgement: 14 | .\" This product includes software developed by the University of 15 | .\" California, Berkeley and its contributors. 16 | .\" 4. Neither the name of the University nor the names of its contributors 17 | .\" may be used to endorse or promote products derived from this software 18 | .\" without specific prior written permission. 19 | .\" 20 | .\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 21 | .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 | .\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 24 | .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 | .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 | .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 | .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 | .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 | .\" SUCH DAMAGE. 31 | .\" 32 | .\" @(#)tftpd.8 8.1 (Berkeley) 6/4/93 33 | .\" $FreeBSD: src/libexec/tftpd/tftpd.8,v 1.15 2001/07/15 07:53:42 dd Exp $ 34 | .\" 35 | .Dd August 29, 2003 36 | .Dt KDUMPD 8 37 | .Os 38 | .Sh NAME 39 | .Nm kdumpd 40 | .Nd Mac OS X remote kernel core dump server 41 | .Sh SYNOPSIS 42 | .Nm /usr/libexec/kdumpd 43 | .Op Ar directory 44 | .Sh DESCRIPTION 45 | .Nm Kdumpd 46 | is a server which receives 47 | kernel states in the form of 48 | a core dump from a remote 49 | Mac OS X machine. 50 | The 51 | .Tn kdumpd 52 | server operates 53 | on UDP port 1069, although this 54 | may be configurable in the future. 55 | The server should be started by 56 | .Xr inetd 8 . 57 | .Pp 58 | The server should have the user ID 59 | with the lowest possible privilege, 60 | usually the user "nobody". 61 | The directory specified as a server 62 | program argument in 63 | .Pa /etc/inetd.conf 64 | directs the server to store kernel cores 65 | in that directory and nowhere else. 66 | The server returns an EEXIST error 67 | to the remote kernel if it receives a 68 | request for an existing file - i.e. 69 | only new files can be created. The server 70 | also disallows path specifications in the 71 | incoming file name. 72 | .Sh HISTORY 73 | The 74 | .Nm 75 | command is based on Berkeley 76 | .Xr tftpd 8 77 | by way of FreeBSD, with several modifications. 78 | -------------------------------------------------------------------------------- /kdumpd/kdumpd.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1983, 1993 3 | * The Regents of the University of California. All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 3. All advertising materials mentioning features or use of this software 14 | * must display the following acknowledgement: 15 | * This product includes software developed by the University of 16 | * California, Berkeley and its contributors. 17 | * 4. Neither the name of the University nor the names of its contributors 18 | * may be used to endorse or promote products derived from this software 19 | * without specific prior written permission. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 | * SUCH DAMAGE. 32 | */ 33 | 34 | #include 35 | 36 | #ifdef __GNUC__ 37 | #define __unused __attribute__ ((unused)) 38 | #endif 39 | 40 | #ifndef lint 41 | __unused static const char copyright[] = 42 | "@(#) Copyright (c) 1983, 1993\n\ 43 | The Regents of the University of California. All rights reserved.\n"; 44 | #endif /* not lint */ 45 | 46 | /* Mac OS X kernel core dump server, based on the BSD trivial file 47 | * transfer protocol server (FreeBSD distribution), with several 48 | * modifications. This server is *not* compatible with tftp, as the 49 | * protocol has changed considerably. 50 | */ 51 | 52 | /* 53 | * Based on the trivial file transfer protocol server. 54 | * 55 | * The original version included many modifications by Jim Guyton 56 | * . 57 | */ 58 | 59 | #include 60 | #include 61 | #include 62 | #include 63 | #include 64 | #include 65 | 66 | #include 67 | #include "kdump.h" 68 | #include 69 | 70 | #include 71 | #include 72 | #include 73 | #include 74 | #include 75 | #include 76 | #include 77 | #include 78 | #include 79 | #include 80 | #include 81 | #include 82 | #include 83 | #include 84 | #ifdef __APPLE__ 85 | #include 86 | #else 87 | #define OSSwapBigToHostInt64 __builtin_bswap64 88 | #include 89 | #endif 90 | 91 | #include "kdumpsubs.h" 92 | 93 | #define DEFAULT_KDUMPD_PORTNO (1069) 94 | #define TIMEOUT 2 95 | 96 | int peer; 97 | int rexmtval = TIMEOUT; 98 | int maxtimeout = 25 * TIMEOUT; 99 | 100 | #define PKTSIZE SEGSIZE+6 101 | 102 | char buf[MAXIMUM_KDP_PKTSIZE]; 103 | char ackbuf[MAXIMUM_KDP_PKTSIZE]; 104 | struct sockaddr_in from; 105 | socklen_t fromlen; 106 | 107 | void kdump __P((struct kdumphdr *, int)); 108 | 109 | /* 110 | * Null-terminated directory prefix list for absolute pathname requests and 111 | * search list for relative pathname requests. 112 | * 113 | * MAXDIRS should be at least as large as the number of arguments that 114 | * inetd allows (currently 20). 115 | */ 116 | #define MAXDIRS 20 117 | static struct dirlist { 118 | char *name; 119 | int len; 120 | } dirs[MAXDIRS+1]; 121 | static int suppress_naks; 122 | static int logging = 1; 123 | static int ipchroot; 124 | static int server_mode = 1; 125 | 126 | static char *errtomsg __P((int)); 127 | static void nak __P((int)); 128 | static char * __P(verifyhost(struct sockaddr_in *)); 129 | uint32_t kdp_crashdump_pkt_size = (SEGSIZE + (sizeof(struct kdumphdr))); 130 | uint32_t kdp_crashdump_seg_size = SEGSIZE; 131 | 132 | #define KDP_FEATURE_MASK_STRING "features" 133 | enum {KDP_FEATURE_LARGE_CRASHDUMPS = 1, KDP_FEATURE_LARGE_PKT_SIZE = 2}; 134 | 135 | uint32_t kdp_crashdump_feature_mask; 136 | uint32_t kdp_feature_large_crashdumps, kdp_feature_large_packets; 137 | 138 | int 139 | main(argc, argv) 140 | int argc; 141 | char *argv[]; 142 | { 143 | register struct kdumphdr *tp; 144 | register int n; 145 | int ch, on; 146 | struct sockaddr_in sin; 147 | char *chroot_dir = NULL; 148 | struct passwd *nobody; 149 | char *chuser = "nobody"; 150 | 151 | openlog("kdumpd", LOG_PID | LOG_NDELAY, LOG_FTP); 152 | while ((ch = getopt(argc, argv, "cClns:u:w")) != -1) { 153 | switch (ch) { 154 | case 'c': 155 | ipchroot = 1; 156 | break; 157 | case 'C': 158 | ipchroot = 2; 159 | break; 160 | case 'l': 161 | logging = 1; 162 | break; 163 | case 'n': 164 | suppress_naks = 1; 165 | break; 166 | case 's': 167 | chroot_dir = optarg; 168 | break; 169 | case 'u': 170 | chuser = optarg; 171 | break; 172 | case 'w': 173 | server_mode = 0; 174 | break; 175 | default: 176 | syslog(LOG_WARNING, "ignoring unknown option -%c", ch); 177 | } 178 | } 179 | 180 | if (optind < argc) { 181 | struct dirlist *dirp; 182 | 183 | /* Get list of directory prefixes. Skip relative pathnames. */ 184 | for (dirp = dirs; optind < argc && dirp < &dirs[MAXDIRS]; 185 | optind++) { 186 | if (argv[optind][0] == '/') { 187 | dirp->name = argv[optind]; 188 | dirp->len = strlen(dirp->name); 189 | dirp++; 190 | } 191 | } 192 | } 193 | else if (chroot_dir) { 194 | dirs->name = "/"; 195 | dirs->len = 1; 196 | } 197 | if (ipchroot && chroot_dir == NULL) { 198 | syslog(LOG_ERR, "-c requires -s"); 199 | exit(1); 200 | } 201 | 202 | /* If we are not in server mode, skip the whole 'inetd' logic below. */ 203 | if (server_mode) { 204 | on = 1; 205 | if (ioctl(0, FIONBIO, &on) < 0) { 206 | syslog(LOG_ERR, "ioctl(FIONBIO): %m"); 207 | exit(1); 208 | } 209 | fromlen = sizeof (from); 210 | n = recvfrom(0, buf, sizeof (buf), 0, 211 | (struct sockaddr *)&from, &fromlen); 212 | if (n < 0) { 213 | syslog(LOG_ERR, "recvfrom: %m"); 214 | exit(1); 215 | } 216 | /* 217 | * Now that we have read the message out of the UDP 218 | * socket, we fork and exit. Thus, inetd will go back 219 | * to listening to the kdump port, and the next request 220 | * to come in will start up a new instance of kdumpd. 221 | * 222 | * We do this so that inetd can run kdumpd in "wait" mode. 223 | * The problem with kdumpd running in "nowait" mode is that 224 | * inetd may get one or more successful "selects" on the 225 | * kdump port before we do our receive, so more than one 226 | * instance of kdumpd may be started up. Worse, if kdumpd 227 | * breaks before doing the above "recvfrom", inetd would 228 | * spawn endless instances, clogging the system. 229 | */ 230 | { 231 | int pid; 232 | int i; 233 | socklen_t j; 234 | 235 | for (i = 1; i < 20; i++) { 236 | pid = fork(); 237 | if (pid < 0) { 238 | sleep(i); 239 | /* 240 | * flush out to most recently sent request. 241 | * 242 | * This may drop some requests, but those 243 | * will be resent by the clients when 244 | * they timeout. The positive effect of 245 | * this flush is to (try to) prevent more 246 | * than one kdumpd being started up to service 247 | * a single request from a single client. 248 | */ 249 | j = sizeof from; 250 | i = recvfrom(0, buf, sizeof (buf), 0, 251 | (struct sockaddr *)&from, &j); 252 | if (i > 0) { 253 | n = i; 254 | fromlen = j; 255 | } 256 | } else { 257 | break; 258 | } 259 | } 260 | if (pid < 0) { 261 | syslog(LOG_ERR, "fork: %m"); 262 | exit(1); 263 | } else if (pid != 0) { 264 | exit(0); 265 | } 266 | } 267 | } 268 | 269 | /* 270 | * Since we exit here, we should do that only after the above 271 | * recvfrom to keep inetd from constantly forking should there 272 | * be a problem. See the above comment about system clogging. 273 | */ 274 | if (chroot_dir) { 275 | if (ipchroot) { 276 | char tempchroot[MAXPATHLEN]; 277 | char *tempaddr; 278 | struct stat sb; 279 | int statret; 280 | 281 | tempaddr = inet_ntoa(from.sin_addr); 282 | snprintf(tempchroot, sizeof(tempchroot), "%s/%s", chroot_dir, tempaddr); 283 | statret = stat(tempchroot, &sb); 284 | if (((sb.st_mode & S_IFMT ) == S_IFDIR) && 285 | (statret == 0 || (statret == -1 && ipchroot == 1))) 286 | chroot_dir = tempchroot; 287 | } 288 | /* Must get this before chroot because /etc might go away */ 289 | if ((nobody = getpwnam(chuser)) == NULL) { 290 | syslog(LOG_ERR, "%s: no such user", chuser); 291 | exit(1); 292 | } 293 | if (chroot(chroot_dir)) { 294 | syslog(LOG_ERR, "chroot: %s: %m", chroot_dir); 295 | exit(1); 296 | } 297 | chdir( "/" ); 298 | setuid(nobody->pw_uid); 299 | } else if (0 != chdir(dirs->name)) { 300 | syslog(LOG_ERR, "chdir%s: %m", dirs->name); 301 | } 302 | 303 | from.sin_family = AF_INET; 304 | alarm(0); 305 | close(0); 306 | close(1); 307 | peer = socket(AF_INET, SOCK_DGRAM, 0); 308 | if (peer < 0) { 309 | syslog(LOG_ERR, "socket: %m"); 310 | exit(1); 311 | } 312 | memset(&sin, 0, sizeof(sin)); 313 | sin.sin_family = AF_INET; 314 | 315 | if (!server_mode) { 316 | sin.sin_addr.s_addr = htonl(INADDR_ANY); 317 | sin.sin_port = htons((uint16_t) DEFAULT_KDUMPD_PORTNO); 318 | } 319 | 320 | if (bind(peer, (struct sockaddr *)&sin, sizeof (sin)) < 0) { 321 | syslog(LOG_ERR, "bind: %m"); 322 | exit(1); 323 | } 324 | 325 | if (!server_mode) { 326 | /* 327 | * Wait for an incoming message from a remote peer, note that we need to 328 | * populate n since kdump() expect the first message to be in buf 329 | * already. 330 | */ 331 | socklen_t slen = sizeof(from); 332 | n = recvfrom(peer, buf, sizeof(buf), 0, 333 | (struct sockaddr *) &from, &slen); 334 | if (n <= 0) { 335 | syslog(LOG_ERR, "recvfrom: %m"); 336 | exit(1); 337 | } 338 | } 339 | 340 | if (connect(peer, (struct sockaddr *)&from, sizeof(from)) < 0) { 341 | syslog(LOG_ERR, "connect: %m"); 342 | exit(1); 343 | } 344 | tp = (struct kdumphdr *)buf; 345 | tp->th_opcode = ntohs(tp->th_opcode); 346 | if (tp->th_opcode == WRQ) 347 | kdump(tp, n); 348 | exit(1); 349 | } 350 | 351 | struct formats; 352 | int validate_access __P((char **, int)); 353 | 354 | void recvfile __P((struct formats *)); 355 | 356 | struct formats { 357 | char *f_mode; 358 | int (*f_validate) __P((char **, int)); 359 | 360 | void (*f_recv) __P((struct formats *)); 361 | int f_convert; 362 | } formats[] = { 363 | { "netascii", validate_access, recvfile, 1 }, 364 | { "octet", validate_access, recvfile, 0 }, 365 | { 0 } 366 | }; 367 | 368 | /* 369 | * Handle initial connection protocol. 370 | */ 371 | void 372 | kdump(tp, size) 373 | struct kdumphdr *tp; 374 | int size; 375 | { 376 | register char *cp; 377 | int first = 1, ecode; 378 | register struct formats *pf; 379 | char *filename, *mode = NULL; 380 | 381 | filename = cp = tp->th_stuff; 382 | again: 383 | while (cp < buf + size) { 384 | if (*cp == '\0') 385 | break; 386 | cp++; 387 | } 388 | if (*cp != '\0') { 389 | nak(EBADOP); 390 | exit(1); 391 | } 392 | if (first) { 393 | mode = ++cp; 394 | first = 0; 395 | goto again; 396 | } 397 | for (cp = mode; *cp; cp++) 398 | if (isupper(*cp)) 399 | *cp = tolower(*cp); 400 | 401 | cp++; 402 | if (strncmp(KDP_FEATURE_MASK_STRING, cp, sizeof(KDP_FEATURE_MASK_STRING)) == 0) { 403 | kdp_crashdump_feature_mask = ntohl(*(uint32_t *) (cp + sizeof(KDP_FEATURE_MASK_STRING))); 404 | kdp_feature_large_crashdumps = kdp_crashdump_feature_mask & KDP_FEATURE_LARGE_CRASHDUMPS; 405 | kdp_feature_large_packets = kdp_crashdump_feature_mask & KDP_FEATURE_LARGE_PKT_SIZE; 406 | 407 | if (kdp_feature_large_packets) { 408 | kdp_crashdump_pkt_size = KDP_LARGE_CRASHDUMP_PKT_SIZE; 409 | kdp_crashdump_seg_size = kdp_crashdump_pkt_size - sizeof(struct kdumphdr); 410 | } 411 | syslog(KDUMPD_DEBUG_LEVEL, "Received feature mask %s:0x%x", cp, kdp_crashdump_feature_mask); 412 | } else 413 | syslog(KDUMPD_DEBUG_LEVEL, "Unable to locate feature mask, mode: %s", mode); 414 | 415 | for (pf = formats; pf->f_mode; pf++) 416 | if (strcmp(pf->f_mode, mode) == 0) 417 | break; 418 | if (pf->f_mode == 0) { 419 | nak(EBADOP); 420 | exit(1); 421 | } 422 | ecode = (*pf->f_validate)(&filename, tp->th_opcode); 423 | if (logging) { 424 | syslog(KDUMPD_DEBUG_LEVEL, "%s: %s request for %s: %s", verifyhost(&from), 425 | tp->th_opcode == WRQ ? "write" : "read", 426 | filename, errtomsg(ecode)); 427 | } 428 | if (ecode) { 429 | /* 430 | * Avoid storms of naks to a RRQ broadcast for a relative 431 | * bootfile pathname from a diskless Sun. 432 | */ 433 | if (suppress_naks && *filename != '/' && ecode == ENOTFOUND) 434 | exit(0); 435 | nak(ecode); 436 | exit(1); 437 | } 438 | if (tp->th_opcode == WRQ) 439 | (*pf->f_recv)(pf); 440 | 441 | exit(0); 442 | } 443 | 444 | 445 | FILE *file; 446 | 447 | /* 448 | * Validate file access. We only allow storage of files that do not already 449 | * exist, and that do not include directory specifiers in their pathnames. 450 | * This is because kernel coredump filenames should always be of the form 451 | * "core-version-IP as dotted quad-random string" as in : 452 | * core-custom-17.202.40.204-a75b4eec 453 | * The file is written to the directory supplied as the first argument 454 | * in inetd.conf 455 | */ 456 | 457 | int 458 | validate_access(char **filep, int mode) 459 | { 460 | struct stat stbuf; 461 | int fd; 462 | char *filename = *filep; 463 | static char pathname[MAXPATHLEN]; 464 | 465 | if (strstr(filename, "/") || strstr(filename, "..")) 466 | return (EACCESS); 467 | 468 | snprintf(pathname, sizeof(pathname), "./%s", filename); 469 | 470 | if (0 == stat(pathname, &stbuf)) 471 | return (EEXIST); 472 | 473 | if (errno != ENOENT) 474 | return (errno); 475 | 476 | 477 | fd = open(filename, O_RDWR|O_CREAT|O_TRUNC , S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); 478 | 479 | if (fd < 0) 480 | return (errno + 100); 481 | 482 | file = fdopen(fd, (mode == RRQ)? "r":"w"); 483 | if (file == NULL) { 484 | return errno+100; 485 | } 486 | 487 | return (0); 488 | } 489 | 490 | int timeout; 491 | jmp_buf timeoutbuf; 492 | 493 | void 494 | timer() 495 | { 496 | 497 | timeout += rexmtval; 498 | if (timeout >= maxtimeout) 499 | { 500 | longjmp(timeoutbuf, 2); 501 | } 502 | longjmp(timeoutbuf, 1); 503 | } 504 | 505 | void 506 | justquit() 507 | { 508 | exit(0); 509 | } 510 | 511 | /* 512 | * Receive a file. 513 | */ 514 | void 515 | recvfile(pf) 516 | struct formats *pf; 517 | { 518 | struct kdumphdr *dp, *w_init(); 519 | register struct kdumphdr *ap; /* ack buffer */ 520 | register int n, size; 521 | volatile unsigned int block; 522 | volatile unsigned int jmpval = 0; 523 | 524 | signal(SIGALRM, timer); 525 | dp = w_init(); 526 | ap = (struct kdumphdr *)ackbuf; 527 | block = 0; 528 | do { 529 | send_seek_ack: timeout = 0; 530 | if (block == 0) 531 | ap->th_opcode = htons((u_short)ACK | ((kdp_feature_large_crashdumps | kdp_feature_large_packets) << 8)); 532 | else 533 | ap->th_opcode = htons((u_short)ACK); 534 | ap->th_block = htonl((unsigned int)block); 535 | block++; 536 | jmpval = setjmp(timeoutbuf); 537 | if (2 == jmpval) 538 | { 539 | syslog (LOG_ERR, "Timing out and flushing file to disk"); 540 | goto flushfile; 541 | } 542 | send_ack: 543 | if (send(peer, ackbuf, 6 , 0) != 6) { 544 | syslog(LOG_ERR, "write: %m"); 545 | goto abort; 546 | } 547 | write_behind(file, pf->f_convert); 548 | for ( ; ; ) { 549 | alarm(rexmtval); 550 | n = recv(peer, dp, kdp_crashdump_pkt_size, 0); 551 | alarm(0); 552 | if (n < 0) { /* really? */ 553 | syslog(LOG_ERR, "read: %m"); 554 | goto abort; 555 | } 556 | dp->th_opcode = ntohs((u_short)dp->th_opcode); 557 | dp->th_block = ntohl((unsigned int)dp->th_block); 558 | #if DEBUG 559 | syslog(KDUMPD_DEBUG_LEVEL, "Received packet type %u, block %u\n", (unsigned)dp->th_opcode, (unsigned)dp->th_block); 560 | #endif 561 | 562 | if (dp->th_opcode == ERROR) 563 | goto abort; 564 | 565 | if (dp->th_opcode == KDP_EOF) 566 | { 567 | syslog (LOG_ERR, "Received last panic dump packet"); 568 | goto final_ack; 569 | } 570 | if (dp->th_opcode == KDP_SEEK) 571 | { 572 | if (dp->th_block == block) 573 | { 574 | off_t crashdump_offset = 0; 575 | unsigned int tempoff = 0; 576 | 577 | if (kdp_feature_large_crashdumps) { 578 | crashdump_offset = OSSwapBigToHostInt64((*(uint64_t *)dp->th_data)); 579 | } 580 | else { 581 | bcopy (dp->th_data, &tempoff, sizeof(unsigned int)); 582 | crashdump_offset = ntohl(tempoff); 583 | } 584 | 585 | #if DEBUG 586 | syslog(KDUMPD_DEBUG_LEVEL, "Seeking to offset 0x%llx\n", crashdump_offset); 587 | #endif 588 | errno = 0; 589 | lseek(fileno (file), crashdump_offset, SEEK_SET); 590 | if (errno) 591 | syslog (LOG_ERR, "lseek: %m"); 592 | 593 | goto send_seek_ack; 594 | } 595 | (void) synchnet(peer); 596 | if (dp->th_block == (block-1)) 597 | { 598 | syslog (LOG_DAEMON|LOG_ERR, "Retransmitting seek ack - current block %u, received block %u", block, dp->th_block); 599 | goto send_ack; /* rexmit */ 600 | } 601 | } 602 | 603 | if (dp->th_opcode == DATA) { 604 | if (dp->th_block == block) { 605 | break; /* normal */ 606 | } 607 | /* Re-synchronize with the other side */ 608 | (void) synchnet(peer); 609 | if (dp->th_block == (block-1)) 610 | { 611 | syslog (LOG_DAEMON|LOG_ERR, "Retransmitting ack - current block %u, received block %u", block, dp->th_block); 612 | goto send_ack; /* rexmit */ 613 | } 614 | else 615 | syslog (LOG_DAEMON|LOG_ERR, "Not retransmitting ack - current block %u, received block %u", block, dp->th_block); 616 | } 617 | } 618 | #if DEBUG 619 | syslog(KDUMPD_DEBUG_LEVEL, "Writing block sized %u, current offset 0x%llx\n", n - 6, ftello(file)); 620 | #endif 621 | size = writeit(file, &dp, n - 6, pf->f_convert); 622 | if (size != (n-6)) { /* ahem */ 623 | if (size < 0) nak(errno + 100); 624 | else nak(ENOSPACE); 625 | goto abort; 626 | } 627 | } while (dp->th_opcode != KDP_EOF); 628 | 629 | final_ack: 630 | ap->th_opcode = htons((u_short)ACK); /* send the "final" ack */ 631 | ap->th_block = htonl((unsigned int) (block)); 632 | (void) send(peer, ackbuf, 6, 0); 633 | flushfile: 634 | write_behind(file, pf->f_convert); 635 | (void) fclose(file); /* close data file */ 636 | syslog (LOG_ERR, "file closed, sending final ACK\n"); 637 | 638 | signal(SIGALRM, justquit); /* just quit on timeout */ 639 | alarm(rexmtval); 640 | n = recv(peer, buf, sizeof (buf), 0); /* normally times out and quits */ 641 | alarm(0); 642 | if (n >= 6 && /* if read some data */ 643 | dp->th_opcode == DATA && /* and got a data block */ 644 | block == dp->th_block) { /* then my last ack was lost */ 645 | (void) send(peer, ackbuf, 6, 0); /* resend final ack */ 646 | } 647 | abort: 648 | return; 649 | } 650 | 651 | /* update if needed, when adding new errmsgs */ 652 | #define MAXERRMSGLEN 40 653 | 654 | struct errmsg { 655 | int e_code; 656 | char *e_msg; 657 | } errmsgs[] = { 658 | { EUNDEF, "Undefined error code" }, 659 | { ENOTFOUND, "File not found" }, 660 | { EACCESS, "Access violation" }, 661 | { ENOSPACE, "Disk full or allocation exceeded" }, 662 | { EBADOP, "Illegal KDUMP operation" }, 663 | { EBADID, "Unknown transfer ID" }, 664 | { EEXISTS, "File already exists" }, 665 | { ENOUSER, "No such user" }, 666 | { -1, 0 } 667 | }; 668 | 669 | static char * 670 | errtomsg(error) 671 | int error; 672 | { 673 | static char buf[20]; 674 | register struct errmsg *pe; 675 | if (error == 0) 676 | return "success"; 677 | for (pe = errmsgs; pe->e_code >= 0; pe++) 678 | if (pe->e_code == error) 679 | return pe->e_msg; 680 | snprintf(buf, sizeof(buf), "error %d", error); 681 | return buf; 682 | } 683 | 684 | /* 685 | * Send a nak packet (error message). 686 | * Error code passed in is one of the 687 | * standard KDUMP codes, or a UNIX errno 688 | * offset by 100. 689 | */ 690 | static void 691 | nak(error) 692 | int error; 693 | { 694 | register struct kdumphdr *tp; 695 | int length; 696 | register struct errmsg *pe; 697 | 698 | tp = (struct kdumphdr *)buf; 699 | tp->th_opcode = htons((u_short)ERROR); 700 | tp->th_code = htons((unsigned int)error); 701 | for (pe = errmsgs; pe->e_code >= 0; pe++) 702 | if (pe->e_code == error) 703 | break; 704 | if (pe->e_code < 0) { 705 | pe->e_msg = strerror(error - 100); 706 | tp->th_code = EUNDEF; /* set 'undef' errorcode */ 707 | } 708 | if (strlen(pe->e_msg) > MAXERRMSGLEN) { 709 | syslog(LOG_ERR, "nak: error msg too long"); 710 | return; 711 | } 712 | 713 | strlcpy(tp->th_msg, pe->e_msg, MAXERRMSGLEN); 714 | length = strlen(pe->e_msg); 715 | tp->th_msg[length] = '\0'; 716 | length += 5; 717 | if (send(peer, buf, length, 0) != length) 718 | syslog(LOG_ERR, "nak: %m"); 719 | 720 | return; 721 | } 722 | 723 | static char * 724 | verifyhost(fromp) 725 | struct sockaddr_in *fromp; 726 | { 727 | struct hostent *hp; 728 | 729 | hp = gethostbyaddr((char *)&fromp->sin_addr, sizeof(fromp->sin_addr), 730 | fromp->sin_family); 731 | if(hp) 732 | return hp->h_name; 733 | else 734 | return inet_ntoa(fromp->sin_addr); 735 | } 736 | -------------------------------------------------------------------------------- /kdumpd/kdumpsubs.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1983, 1993 3 | * The Regents of the University of California. All rights reserved. 4 | * 5 | * Redistribution and use in source and binary forms, with or without 6 | * modification, are permitted provided that the following conditions 7 | * are met: 8 | * 1. Redistributions of source code must retain the above copyright 9 | * notice, this list of conditions and the following disclaimer. 10 | * 2. Redistributions in binary form must reproduce the above copyright 11 | * notice, this list of conditions and the following disclaimer in the 12 | * documentation and/or other materials provided with the distribution. 13 | * 4. Neither the name of the University nor the names of its contributors 14 | * may be used to endorse or promote products derived from this software 15 | * without specific prior written permission. 16 | * 17 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 18 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 21 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 | * SUCH DAMAGE. 28 | */ 29 | 30 | /* Simple minded read-ahead/write-behind subroutines for tftp user and 31 | server. Written originally with multiple buffers in mind, but current 32 | implementation has two buffer logic wired in. 33 | 34 | Todo: add some sort of final error check so when the write-buffer 35 | is finally flushed, the caller can detect if the disk filled up 36 | (or had an i/o error) and return a nak to the other side. 37 | 38 | Jim Guyton 10/85 39 | */ 40 | 41 | #ifdef HAVE_CONFIG_H 42 | #include 43 | #endif 44 | 45 | #include 46 | #include 47 | #include 48 | #ifdef HAVE_SYS_FILIO_H 49 | #include 50 | #endif 51 | #include 52 | #include "kdump.h" 53 | 54 | #include 55 | #include 56 | #include 57 | 58 | #include "kdumpsubs.h" 59 | 60 | #define PKTSIZE SEGSIZE+6 /* should be moved to kdump.h */ 61 | 62 | struct bf { 63 | int counter; /* size of data in buffer, or flag */ 64 | char buf[MAXIMUM_KDP_PKTSIZE]; /* room for data packet */ 65 | } bfs[2]; 66 | 67 | /* Values for bf.counter */ 68 | #define BF_ALLOC -3 /* alloc'd but not yet filled */ 69 | #define BF_FREE -2 /* free */ 70 | /* [-1 .. SEGSIZE] = size of data in the data buffer */ 71 | 72 | static int nextone; /* index of next buffer to use */ 73 | static int current; /* index of buffer in use */ 74 | 75 | /* control flags for crlf conversions */ 76 | int newline = 0; /* fillbuf: in middle of newline expansion */ 77 | int prevchar = -1; /* putbuf: previous char (cr check) */ 78 | 79 | static struct kdumphdr *rw_init __P ((int)); 80 | 81 | struct kdumphdr *w_init() { return rw_init(0); } /* write-behind */ 82 | struct kdumphdr *r_init() { return rw_init(1); } /* read-ahead */ 83 | 84 | extern uint32_t kdp_crashdump_pkt_size; 85 | extern uint32_t kdp_crashdump_seg_size; 86 | 87 | /* init for either read-ahead or write-behind */ 88 | /* zero for write-behind, one for read-head */ 89 | static struct kdumphdr * 90 | rw_init(int x) 91 | { 92 | newline = 0; /* init crlf flag */ 93 | prevchar = -1; 94 | bfs[0].counter = BF_ALLOC; /* pass out the first buffer */ 95 | current = 0; 96 | bfs[1].counter = BF_FREE; 97 | nextone = x; /* ahead or behind? */ 98 | return (struct kdumphdr *)bfs[0].buf; 99 | } 100 | 101 | 102 | /* Have emptied current buffer by sending to net and getting ack. 103 | Free it and return next buffer filled with data. 104 | */ 105 | /* if true, convert to ascii */ 106 | /* file opened for read */ 107 | 108 | /* int */ 109 | /* readit(FILE *file, struct kdumphdr **dpp, int convert) */ 110 | /* { */ 111 | /* struct bf *b; */ 112 | 113 | /* bfs[current].counter = BF_FREE; /\* free old one *\/ */ 114 | /* current = !current; /\* "incr" current *\/ */ 115 | 116 | /* b = &bfs[current]; /\* look at new buffer *\/ */ 117 | /* if (b->counter == BF_FREE) /\* if it's empty *\/ */ 118 | /* read_ahead(file, convert); /\* fill it *\/ */ 119 | /* /\* assert(b->counter != BF_FREE);*\//\* check *\/ */ 120 | /* *dpp = (struct kdumphdr *)b->buf; /\* set caller's ptr *\/ */ 121 | /* return b->counter; */ 122 | /* } */ 123 | 124 | /* 125 | * fill the input buffer, doing ascii conversions if requested 126 | * conversions are lf -> cr,lf and cr -> cr, nul 127 | */ 128 | /* FILE *file; file opened for read */ 129 | /* int convert; if true, convert to ascii */ 130 | void 131 | read_ahead(FILE *file, int convert) 132 | { 133 | register int i; 134 | register char *p; 135 | register int c; 136 | struct bf *b; 137 | struct kdumphdr *dp; 138 | 139 | b = &bfs[nextone]; /* look at "next" buffer */ 140 | if (b->counter != BF_FREE) /* nop if not free */ 141 | return; 142 | nextone = !nextone; /* "incr" next buffer ptr */ 143 | 144 | dp = (struct kdumphdr *)b->buf; 145 | 146 | if (convert == 0) { 147 | b->counter = read(fileno(file), dp->th_data, kdp_crashdump_seg_size); 148 | return; 149 | } 150 | 151 | p = dp->th_data; 152 | for (i = 0 ; i < kdp_crashdump_seg_size; i++) { 153 | if (newline) { 154 | if (prevchar == '\n') 155 | c = '\n'; /* lf to cr,lf */ 156 | else c = '\0'; /* cr to cr,nul */ 157 | newline = 0; 158 | } 159 | else { 160 | c = getc(file); 161 | if (c == EOF) break; 162 | if (c == '\n' || c == '\r') { 163 | prevchar = c; 164 | c = '\r'; 165 | newline = 1; 166 | } 167 | } 168 | *p++ = c; 169 | } 170 | b->counter = (int)(p - dp->th_data); 171 | } 172 | 173 | /* Update count associated with the buffer, get new buffer 174 | from the queue. Calls write_behind only if next buffer not 175 | available. 176 | */ 177 | int 178 | writeit(FILE *file, struct kdumphdr **dpp, int ct, int convert) 179 | { 180 | bfs[current].counter = ct; /* set size of data to write */ 181 | current = !current; /* switch to other buffer */ 182 | if (bfs[current].counter != BF_FREE) /* if not free */ 183 | (void)write_behind(file, convert); /* flush it */ 184 | bfs[current].counter = BF_ALLOC; /* mark as alloc'd */ 185 | *dpp = (struct kdumphdr *)bfs[current].buf; 186 | return ct; /* this is a lie of course */ 187 | } 188 | 189 | 190 | /* 191 | * Output a buffer to a file, converting from netascii if requested. 192 | * CR,NUL -> CR and CR,LF => LF. 193 | * Note spec is undefined if we get CR as last byte of file or a 194 | * CR followed by anything else. In this case we leave it alone. 195 | */ 196 | int 197 | write_behind(FILE *file, int convert) 198 | { 199 | char *buf; 200 | int count; 201 | register int ct; 202 | register char *p; 203 | register int c; /* current character */ 204 | struct bf *b; 205 | struct kdumphdr *dp; 206 | 207 | b = &bfs[nextone]; 208 | if (b->counter < -1) /* anything to flush? */ 209 | return 0; /* just nop if nothing to do */ 210 | 211 | count = b->counter; /* remember byte count */ 212 | b->counter = BF_FREE; /* reset flag */ 213 | dp = (struct kdumphdr *)b->buf; 214 | nextone = !nextone; /* incr for next time */ 215 | buf = dp->th_data; 216 | 217 | if (count <= 0) return -1; /* nak logic? */ 218 | 219 | if (convert == 0) 220 | return write(fileno(file), buf, count); 221 | 222 | p = buf; 223 | ct = count; 224 | while (ct--) { /* loop over the buffer */ 225 | c = *p++; /* pick up a character */ 226 | if (prevchar == '\r') { /* if prev char was cr */ 227 | if (c == '\n') /* if have cr,lf then just */ 228 | fseek(file, -1, 1); /* smash lf on top of the cr */ 229 | else 230 | if (c == '\0') /* if have cr,nul then */ 231 | goto skipit; /* just skip over the putc */ 232 | /* else just fall through and allow it */ 233 | } 234 | putc(c, file); 235 | skipit: 236 | prevchar = c; 237 | } 238 | return count; 239 | } 240 | 241 | 242 | /* When an error has occurred, it is possible that the two sides 243 | * are out of synch. Ie: that what I think is the other side's 244 | * response to packet N is really their response to packet N-1. 245 | * 246 | * So, to try to prevent that, we flush all the input queued up 247 | * for us on the network connection on our host. 248 | * 249 | * We return the number of packets we flushed (mostly for reporting 250 | * when trace is active). 251 | */ 252 | 253 | /*int f;socket to flush */ 254 | int 255 | synchnet(int f) 256 | { 257 | int i, j = 0; 258 | char rbuf[kdp_crashdump_pkt_size]; 259 | struct sockaddr_in from; 260 | socklen_t fromlen; 261 | 262 | while (1) { 263 | (void) ioctl(f, FIONREAD, &i); 264 | if (i) { 265 | j++; 266 | fromlen = sizeof from; 267 | (void) recvfrom(f, rbuf, sizeof (rbuf), 0, 268 | (struct sockaddr *)&from, &fromlen); 269 | } else { 270 | return(j); 271 | } 272 | } 273 | } 274 | -------------------------------------------------------------------------------- /kdumpd/kdumpsubs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. 3 | * 4 | * @APPLE_LICENSE_HEADER_START@ 5 | * 6 | * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights 7 | * Reserved. This file contains Original Code and/or Modifications of 8 | * Original Code as defined in and that are subject to the Apple Public 9 | * Source License Version 1.0 (the 'License'). You may not use this file 10 | * except in compliance with the License. Please obtain a copy of the 11 | * License at http://www.apple.com/publicsource and read it before using 12 | * this file. 13 | * 14 | * The Original Code and all software distributed under the License are 15 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 16 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 17 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the 19 | * License for the specific language governing rights and limitations 20 | * under the License." 21 | * 22 | * @APPLE_LICENSE_HEADER_END@ 23 | */ 24 | /* 25 | * Copyright (c) 1993 26 | * The Regents of the University of California. All rights reserved. 27 | * 28 | * Redistribution and use in source and binary forms, with or without 29 | * modification, are permitted provided that the following conditions 30 | * are met: 31 | * 1. Redistributions of source code must retain the above copyright 32 | * notice, this list of conditions and the following disclaimer. 33 | * 2. Redistributions in binary form must reproduce the above copyright 34 | * notice, this list of conditions and the following disclaimer in the 35 | * documentation and/or other materials provided with the distribution. 36 | * 3. All advertising materials mentioning features or use of this software 37 | * must display the following acknowledgement: 38 | * This product includes software developed by the University of 39 | * California, Berkeley and its contributors. 40 | * 4. Neither the name of the University nor the names of its contributors 41 | * may be used to endorse or promote products derived from this software 42 | * without specific prior written permission. 43 | * 44 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 45 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 46 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 47 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 48 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 49 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 50 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 51 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 52 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 53 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 54 | * SUCH DAMAGE. 55 | * 56 | * @(#)kdumpsubs.h 8.1 (Berkeley) 6/6/93 57 | */ 58 | 59 | /* 60 | * Prototypes for read-ahead/write-behind subroutines for kdump user and 61 | * server. 62 | */ 63 | struct kdumphdr *r_init __P((void)); 64 | void read_ahead __P((FILE *, int)); 65 | int readit __P((FILE *, struct kdumphdr **, int)); 66 | 67 | int synchnet __P((int)); 68 | 69 | struct kdumphdr *w_init __P((void)); 70 | int write_behind __P((FILE *, int)); 71 | int writeit __P((FILE *, struct kdumphdr **, int, int)); 72 | 73 | --------------------------------------------------------------------------------