├── 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 |
--------------------------------------------------------------------------------