├── .gitIgnore ├── C └── lzvn_decode.c ├── FastCompression.h ├── Makefile ├── README.md ├── lib └── x86_64 │ ├── libFastCompression-Kernel.a │ └── libFastCompression.a ├── lzvn.c ├── lzvn.h ├── lzvn_decode.s ├── lzvn_encode.s └── prelink.h /.gitIgnore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .git 3 | *.o 4 | *.a 5 | lzvn 6 | Backup 7 | Dictionary.plist 8 | kernel 9 | kexts 10 | Prelinkedkernel* 11 | -------------------------------------------------------------------------------- /C/lzvn_decode.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014 Apple Computer, Inc. All rights reserved. 3 | * 4 | * @APPLE_LICENSE_HEADER_START@ 5 | * 6 | * Portions Copyright (c) 2003 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 2.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 | * The lzvn_decode function was first located and disassembled by Pike R. 25 | * Alpha, after that Andy Vandijck wrote a little C program that called the 26 | * assembler code, which 'MinusZwei' converted to flat C code. And below 27 | * you'll find my conversion of the assembler code, this time to a more 28 | * traditional C-style format, to make it easier to understand. 29 | * 30 | * Thanks to Andy Vandijck and 'MinusZwei' for their hard work! 31 | */ 32 | 33 | #include 34 | #include 35 | 36 | #include 37 | 38 | #define DEBUG_STATE_ENABLED 0 39 | 40 | #if DEBUG_STATE_ENABLED 41 | #define _LZVN_DEBUG_DUMP(x...) printf(x) 42 | #else 43 | #define _LZVN_DEBUG_DUMP(x...) 44 | #endif 45 | 46 | #define LZVN_0 0 47 | #define LZVN_1 1 48 | #define LZVN_2 2 49 | #define LZVN_3 3 50 | #define LZVN_4 4 51 | #define LZVN_5 5 52 | #define LZVN_6 6 53 | #define LZVN_7 7 54 | #define LZVN_8 8 55 | #define LZVN_9 9 56 | #define LZVN_10 10 57 | #define LZVN_11 11 58 | 59 | #define CASE_TABLE 127 60 | 61 | //============================================================================== 62 | 63 | size_t lzvn_decode(void * decompressedData, size_t decompressedSize, void * compressedData, size_t compressedSize) 64 | { 65 | const uint64_t decompBuffer = (const uint64_t)decompressedData; 66 | 67 | size_t length = 0; // xor %rax,%rax 68 | 69 | uint64_t compBuffer = (uint64_t)compressedData; 70 | 71 | uint64_t compBufferPointer = 0; // use p(ointer)? 72 | uint64_t caseTableIndex = 0; 73 | uint64_t byteCount = 0; 74 | uint64_t currentLength = 0; // xor %r12,%r12 75 | uint64_t negativeOffset = 0; 76 | uint64_t address = 0; // ((uint64_t)compBuffer + compBufferPointer) 77 | 78 | uint8_t jmpTo = CASE_TABLE; // On the first run! 79 | 80 | // Example values: 81 | // 82 | // byteCount: 10, negativeOffset: 28957, length: 42205762, currentLength: 42205772, compBufferPointer: 42176805 83 | // byteCount: 152, negativeOffset: 28957, length: 42205772, currentLength: 42205924, compBufferPointer: 42176815 84 | // byteCount: 10, negativeOffset: 7933, length: 42205924, currentLength: 42205934, compBufferPointer: 42197991 85 | // byteCount: 45, negativeOffset: 7933, length: 42205934, currentLength: 42205979, compBufferPointer: 42198001 86 | // byteCount: 9, negativeOffset: 64, length: 42205979, currentLength: 42205988, compBufferPointer: 42205915 87 | // byteCount: 10, negativeOffset: 8180, length: 42205988, currentLength: 42205998, compBufferPointer: 42197808 88 | // byteCount: 59, negativeOffset: 8180, length: 42205998, currentLength: 42206057, compBufferPointer: 42197818 89 | // byteCount: 10, negativeOffset: 359, length: 42206057, currentLength: 42206067, compBufferPointer: 42205698 90 | // byteCount: 1, negativeOffset: 359, length: 42206067, currentLength: 42206068, compBufferPointer: 42205708 91 | // byteCount: 10, negativeOffset: 29021, length: 42206068, currentLength: 42206078, compBufferPointer: 42177047 92 | // 93 | // length + byteCount = currentLength 94 | // currentLength - (negativeOffset + byteCount) = compBufferPointer 95 | // length - negativeOffset = compBufferPointer 96 | 97 | static short caseTable[ 256 ] = 98 | { 99 | 1, 1, 1, 1, 1, 1, 2, 3, 1, 1, 1, 1, 1, 1, 4, 3, 100 | 1, 1, 1, 1, 1, 1, 4, 3, 1, 1, 1, 1, 1, 1, 5, 3, 101 | 1, 1, 1, 1, 1, 1, 5, 3, 1, 1, 1, 1, 1, 1, 5, 3, 102 | 1, 1, 1, 1, 1, 1, 5, 3, 1, 1, 1, 1, 1, 1, 5, 3, 103 | 1, 1, 1, 1, 1, 1, 0, 3, 1, 1, 1, 1, 1, 1, 0, 3, 104 | 1, 1, 1, 1, 1, 1, 0, 3, 1, 1, 1, 1, 1, 1, 0, 3, 105 | 1, 1, 1, 1, 1, 1, 0, 3, 1, 1, 1, 1, 1, 1, 0, 3, 106 | 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 107 | 1, 1, 1, 1, 1, 1, 0, 3, 1, 1, 1, 1, 1, 1, 0, 3, 108 | 1, 1, 1, 1, 1, 1, 0, 3, 1, 1, 1, 1, 1, 1, 0, 3, 109 | 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 110 | 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 111 | 1, 1, 1, 1, 1, 1, 0, 3, 1, 1, 1, 1, 1, 1, 0, 3, 112 | 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 113 | 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 114 | 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10 115 | }; 116 | 117 | decompressedSize -= 8; // sub $0x8,%rsi 118 | 119 | if (decompressedSize < 8) // jb Llzvn_exit 120 | { 121 | return 0; 122 | } 123 | 124 | compressedSize = (compBuffer + compressedSize - 8); // lea -0x8(%rdx,%rcx,1),%rcx 125 | 126 | if (compBuffer > compressedSize) // cmp %rcx,%rdx 127 | { 128 | return 0; // ja Llzvn_exit 129 | } 130 | 131 | compBufferPointer = *(uint64_t *)compBuffer; // mov (%rdx),%r8 132 | caseTableIndex = (compBufferPointer & 255); // movzbq (%rdx),%r9 133 | 134 | do // jmpq *(%rbx,%r9,8) 135 | { 136 | switch (jmpTo) // our jump table 137 | { 138 | case CASE_TABLE: /******************************************************/ 139 | 140 | switch (caseTable[(uint8_t)caseTableIndex]) 141 | { 142 | case 0: _LZVN_DEBUG_DUMP("caseTable[0]\n"); 143 | 144 | caseTableIndex >>= 6; // shr $0x6,%r9 145 | compBuffer = (compBuffer + caseTableIndex + 1); // lea 0x1(%rdx,%r9,1),%rdx 146 | 147 | if (compBuffer > compressedSize) // cmp %rcx,%rdx 148 | { 149 | return 0; // ja Llzvn_exit 150 | } 151 | 152 | byteCount = 56; // mov $0x38,%r10 153 | byteCount &= compBufferPointer; // and %r8,%r10 154 | compBufferPointer >>= 8; // shr $0x8,%r8 155 | byteCount >>= 3; // shr $0x3,%r10 156 | byteCount += 3; // add $0x3,%r10 157 | 158 | jmpTo = LZVN_10; // jmp Llzvn_l10 159 | break; 160 | 161 | case 1: _LZVN_DEBUG_DUMP("caseTable[1]\n"); 162 | 163 | caseTableIndex >>= 6; // shr $0x6,%r9 164 | compBuffer = (compBuffer + caseTableIndex + 2); // lea 0x2(%rdx,%r9,1),%rdx 165 | 166 | if (compBuffer > compressedSize) // cmp %rcx,%rdx 167 | { 168 | return 0; // ja Llzvn_exit 169 | } 170 | 171 | negativeOffset = compBufferPointer; // mov %r8,%r12 172 | negativeOffset = OSSwapInt64(negativeOffset); // bswap %r12 173 | byteCount = negativeOffset; // mov %r12,%r10 174 | negativeOffset <<= 5; // shl $0x5,%r12 175 | byteCount <<= 2; // shl $0x2,%r10 176 | negativeOffset >>= 53; // shr $0x35,%r12 177 | byteCount >>= 61; // shr $0x3d,%r10 178 | compBufferPointer >>= 16; // shr $0x10,%r8 179 | byteCount += 3; // add $0x3,%r10 180 | 181 | jmpTo = LZVN_10; // jmp Llzvn_l10 182 | break; 183 | 184 | case 2: _LZVN_DEBUG_DUMP("caseTable[2]\n"); 185 | 186 | return length; 187 | 188 | case 3: _LZVN_DEBUG_DUMP("caseTable[3]\n"); 189 | 190 | caseTableIndex >>= 6; // shr $0x6,%r9 191 | compBuffer = (compBuffer + caseTableIndex + 3); // lea 0x3(%rdx,%r9,1),%rdx 192 | 193 | if (compBuffer > compressedSize) // cmp %rcx,%rdx 194 | { 195 | return 0; // ja Llzvn_exit 196 | } 197 | 198 | byteCount = 56; // mov $0x38,%r10 199 | negativeOffset = 65535; // mov $0xffff,%r12 200 | byteCount &= compBufferPointer; // and %r8,%r10 201 | compBufferPointer >>= 8; // shr $0x8,%r8 202 | byteCount >>= 3; // shr $0x3,%r10 203 | negativeOffset &= compBufferPointer; // and %r8,%r12 204 | compBufferPointer >>= 16; // shr $0x10,%r8 205 | byteCount += 3; // add $0x3,%r10 206 | 207 | jmpTo = LZVN_10; // jmp Llzvn_l10 208 | break; 209 | 210 | case 4: _LZVN_DEBUG_DUMP("caseTable[4]\n"); 211 | 212 | compBuffer++; // add $0x1,%rdx 213 | 214 | if (compBuffer > compressedSize) // cmp %rcx,%rdx 215 | { 216 | return 0; // ja Llzvn_exit 217 | } 218 | 219 | compBufferPointer = *(uint64_t *)compBuffer; // mov (%rdx),%r8 220 | caseTableIndex = (compBufferPointer & 255); // movzbq (%rdx),%r9 221 | 222 | jmpTo = CASE_TABLE; // continue; 223 | break; // jmpq *(%rbx,%r9,8) 224 | 225 | case 5: _LZVN_DEBUG_DUMP("caseTable[5]\n"); 226 | 227 | return 0; // Llzvn_table5; 228 | 229 | case 6: _LZVN_DEBUG_DUMP("caseTable[6]\n"); 230 | 231 | caseTableIndex >>= 3; // shr $0x3,%r9 232 | caseTableIndex &= 3; // and $0x3,%r9 233 | compBuffer = (compBuffer + caseTableIndex + 3); // lea 0x3(%rdx,%r9,1),%rdx 234 | 235 | if (compBuffer > compressedSize) // cmp %rcx,%rdx 236 | { 237 | return 0; // ja Llzvn_exit 238 | } 239 | 240 | byteCount = compBufferPointer; // mov %r8,%r10 241 | byteCount &= 775; // and $0x307,%r10 242 | compBufferPointer >>= 10; // shr $0xa,%r8 243 | negativeOffset = (byteCount & 255); // movzbq %r10b,%r12 244 | byteCount >>= 8; // shr $0x8,%r10 245 | negativeOffset <<= 2; // shl $0x2,%r12 246 | byteCount |= negativeOffset; // or %r12,%r10 247 | negativeOffset = 16383; // mov $0x3fff,%r12 248 | byteCount += 3; // add $0x3,%r10 249 | negativeOffset &= compBufferPointer; // and %r8,%r12 250 | compBufferPointer >>= 14; // shr $0xe,%r8 251 | 252 | jmpTo = LZVN_10; // jmp Llzvn_l10 253 | break; 254 | 255 | case 7: _LZVN_DEBUG_DUMP("caseTable[7]\n"); 256 | 257 | compBufferPointer >>= 8; // shr $0x8,%r8 258 | compBufferPointer &= 255; // and $0xff,%r8 259 | compBufferPointer += 16; // add $0x10,%r8 260 | compBuffer = (compBuffer + compBufferPointer + 2); // lea 0x2(%rdx,%r8,1),%rdx 261 | 262 | jmpTo = LZVN_0; // jmp Llzvn_l0 263 | break; 264 | 265 | case 8: _LZVN_DEBUG_DUMP("caseTable[8]\n"); 266 | 267 | compBufferPointer &= 15; // and $0xf,%r8 268 | compBuffer = (compBuffer + compBufferPointer + 1); // lea 0x1(%rdx,%r8,1),%rdx 269 | 270 | jmpTo = LZVN_0; // jmp Llzvn_l0 271 | break; 272 | 273 | case 9: _LZVN_DEBUG_DUMP("caseTable[9]\n"); 274 | 275 | compBuffer += 2; // add $0x2,%rdx 276 | 277 | if (compBuffer > compressedSize) // cmp %rcx,%rdx 278 | { 279 | return 0; // ja Llzvn_exit 280 | } 281 | 282 | // Up most significant byte (count) by 16 (0x10/16 - 0x10f/271). 283 | byteCount = compBufferPointer; // mov %r8,%r10 284 | byteCount >>= 8; // shr $0x8,%r10 285 | byteCount &= 255; // and $0xff,%r10 286 | byteCount += 16; // add $0x10,%r10 287 | 288 | jmpTo = LZVN_11; // jmp Llzvn_l11 289 | break; 290 | 291 | case 10:_LZVN_DEBUG_DUMP("caseTable[10]\n"); 292 | 293 | compBuffer++; // add $0x1,%rdx 294 | 295 | if (compBuffer > compressedSize) // cmp %rcx,%rdx 296 | { 297 | return 0; // ja Llzvn_exit 298 | } 299 | 300 | byteCount = compBufferPointer; // mov %r8,%r10 301 | byteCount &= 15; // and $0xf,%r10 302 | 303 | jmpTo = LZVN_11; // jmp Llzvn_l11 304 | break; 305 | #if DEBUG_STATE_ENABLED 306 | default:printf("default() caseTableIndex[%d]\n", (uint8_t)caseTableIndex); 307 | #endif 308 | } // switch (caseTable[caseTableIndex]) 309 | 310 | break; 311 | 312 | case LZVN_0: /**********************************************************/ 313 | 314 | _LZVN_DEBUG_DUMP("jmpTable(0)\n"); 315 | 316 | if (compBuffer > compressedSize) // cmp %rcx,%rdx 317 | { 318 | return 0; // ja Llzvn_exit 319 | } 320 | 321 | currentLength = (length + compBufferPointer); // lea (%rax,%r8,1),%r11 322 | compBufferPointer = -compBufferPointer; // neg %r8 323 | 324 | if (currentLength > decompressedSize) // cmp %rsi,%r11 325 | { 326 | jmpTo = LZVN_2; // ja Llzvn_l2 327 | break; 328 | } 329 | 330 | currentLength = (decompBuffer + currentLength); // lea (%rdi,%r11,1),%r11 331 | 332 | case LZVN_1: /**********************************************************/ 333 | 334 | do // Llzvn_l1: 335 | { 336 | _LZVN_DEBUG_DUMP("jmpTable(1)\n"); 337 | 338 | // caseTableIndex = *(uint64_t *)((uint64_t)compBuffer + compBufferPointer); 339 | 340 | address = (compBuffer + compBufferPointer); // mov (%rdx,%r8,1),%r9 341 | caseTableIndex = *(uint64_t *)address; 342 | 343 | // *(uint64_t *)((uint64_t)currentLength + compBufferPointer) = caseTableIndex; 344 | // or: 345 | // memcpy((void *)currentLength + compBufferPointer, &caseTableIndex, 8); 346 | // or: 347 | address = (currentLength + compBufferPointer); // mov %r9,(%r11,%r8,1) 348 | *(uint64_t *)address = caseTableIndex; 349 | compBufferPointer += 8; // add $0x8,%r8 350 | 351 | } while ((UINT64_MAX - (compBufferPointer - 8)) >= 8); // jae Llzvn_l1 352 | 353 | length = currentLength; // mov %r11,%rax 354 | length -= decompBuffer; // sub %rdi,%rax 355 | 356 | compBufferPointer = *(uint64_t *)compBuffer; // mov (%rdx),%r8 357 | caseTableIndex = (compBufferPointer & 255); // movzbq (%rdx),%r9 358 | 359 | jmpTo = CASE_TABLE; 360 | break; // jmpq *(%rbx,%r9,8) 361 | 362 | case LZVN_2: /**********************************************************/ 363 | 364 | _LZVN_DEBUG_DUMP("jmpTable(2)\n"); 365 | 366 | currentLength = (decompressedSize + 8); // lea 0x8(%rsi),%r11 367 | 368 | case LZVN_3: /***********************************************************/ 369 | 370 | do // Llzvn_l3: (block copy of bytes) 371 | { 372 | _LZVN_DEBUG_DUMP("jmpTable(3)\n"); 373 | 374 | address = (compBuffer + compBufferPointer); // movzbq (%rdx,%r8,1),%r9 375 | caseTableIndex = (*((uint64_t *)address) & 255); 376 | memcpy((void *)decompBuffer + length, &caseTableIndex, 1); 377 | length++; // add $0x1,%rax 378 | 379 | if (currentLength == length) // cmp %rax,%r11 380 | { 381 | return length; // je Llzvn_exit2 382 | } 383 | 384 | compBufferPointer++; // add $0x1,%r8 385 | 386 | } while ((int64_t)compBufferPointer != 0); // jne Llzvn_l3 387 | 388 | compBufferPointer = *(uint64_t *)compBuffer; // mov (%rdx),%r8 389 | caseTableIndex = (compBufferPointer & 255); // movzbq (%rdx),%r9 390 | 391 | jmpTo = CASE_TABLE; 392 | break; // jmpq *(%rbx,%r9,8) 393 | 394 | case LZVN_4: /**********************************************************/ 395 | 396 | _LZVN_DEBUG_DUMP("jmpTable(4)\n"); 397 | 398 | currentLength = (decompressedSize + 8); // lea 0x8(%rsi),%r11 399 | 400 | case LZVN_9: /**********************************************************/ 401 | 402 | do // Llzvn_l9: (block copy of bytes) 403 | { 404 | _LZVN_DEBUG_DUMP("jmpTable(9)\n"); 405 | 406 | address = (decompBuffer + compBufferPointer); // movzbq (%rdi,%r8,1),%r9 407 | caseTableIndex = (*((uint8_t *)address) & 255); 408 | 409 | compBufferPointer++; // add $0x1,%r8 410 | memcpy((void *)decompBuffer + length, &caseTableIndex, 1); // mov %r9,(%rdi,%rax,1) 411 | length++; // add $0x1,%rax 412 | 413 | if (length == currentLength) // cmp %rax,%r11 414 | { 415 | return length; // je Llzvn_exit2 416 | } 417 | 418 | byteCount--; // sub $0x1,%r10 419 | 420 | } while (byteCount); // jne Llzvn_l9 421 | 422 | compBufferPointer = *(uint64_t *)compBuffer; // mov (%rdx),%r8 423 | caseTableIndex = (compBufferPointer & 255); // movzbq (%rdx),%r9 424 | 425 | jmpTo = CASE_TABLE; 426 | break; // jmpq *(%rbx,%r9,8) 427 | 428 | case LZVN_5: /**********************************************************/ 429 | 430 | do // Llzvn_l5: (block copy of qwords) 431 | { 432 | _LZVN_DEBUG_DUMP("jmpTable(5)\n"); 433 | 434 | address = (decompBuffer + compBufferPointer); // mov (%rdi,%r8,1),%r9 435 | caseTableIndex = *((uint64_t *)address); 436 | 437 | compBufferPointer += 8; // add $0x8,%r8 438 | memcpy((void *)decompBuffer + length, &caseTableIndex, 8); // mov %r9,(%rdi,%rax,1) 439 | length += 8; // add $0x8,%rax 440 | byteCount -= 8; // sub $0x8,%r10 441 | 442 | } while ((byteCount + 8) > 8); // ja Llzvn_l5 443 | 444 | length += byteCount; // add %r10,%rax 445 | compBufferPointer = *(uint64_t *)compBuffer; // mov (%rdx),%r8 446 | caseTableIndex = (compBufferPointer & 255); // movzbq (%rdx),%r9 447 | 448 | jmpTo = CASE_TABLE; 449 | break; // jmpq *(%rbx,%r9,8) 450 | 451 | case LZVN_10: /*********************************************************/ 452 | 453 | _LZVN_DEBUG_DUMP("jmpTable(10)\n"); 454 | 455 | currentLength = (length + caseTableIndex); // lea (%rax,%r9,1),%r11 456 | currentLength += byteCount; // add %r10,%r11 457 | 458 | if (currentLength < decompressedSize) // cmp %rsi,%r11 (block_end: jae Llzvn_l8) 459 | { 460 | memcpy((void *)decompBuffer + length, &compBufferPointer, 8); // mov %r8,(%rdi,%rax,1) 461 | length += caseTableIndex; // add %r9,%rax 462 | compBufferPointer = length; // mov %rax,%r8 463 | 464 | if (compBufferPointer < negativeOffset) // jb Llzvn_exit 465 | { 466 | return 0; 467 | } 468 | 469 | compBufferPointer -= negativeOffset; // sub %r12,%r8 470 | 471 | if (negativeOffset < 8) // cmp $0x8,%r12 472 | { 473 | jmpTo = LZVN_4; // jb Llzvn_l4 474 | break; 475 | } 476 | 477 | jmpTo = LZVN_5; // jmpq *(%rbx,%r9,8) 478 | break; 479 | } 480 | 481 | case LZVN_8: /**********************************************************/ 482 | 483 | _LZVN_DEBUG_DUMP("jmpTable(8)\n"); 484 | 485 | if (caseTableIndex == 0) // test %r9,%r9 486 | { 487 | jmpTo = LZVN_7; // jmpq *(%rbx,%r9,8) 488 | break; 489 | } 490 | 491 | currentLength = (decompressedSize + 8); // lea 0x8(%rsi),%r11 492 | 493 | case LZVN_6: /**********************************************************/ 494 | 495 | do 496 | { 497 | _LZVN_DEBUG_DUMP("jmpTable(6)\n"); 498 | 499 | memcpy((void *)decompBuffer + length, &compBufferPointer, 1); // mov %r8b,(%rdi,%rax,1) 500 | length++; // add $0x1,%rax 501 | 502 | if (length == currentLength) // cmp %rax,%r11 503 | { 504 | return length; // je Llzvn_exit2 505 | } 506 | 507 | compBufferPointer >>= 8; // shr $0x8,%r8 508 | caseTableIndex--; // sub $0x1,%r9 509 | 510 | } while (caseTableIndex != 1); // jne Llzvn_l6 511 | 512 | case LZVN_7: /**********************************************************/ 513 | 514 | _LZVN_DEBUG_DUMP("jmpTable(7)\n"); 515 | 516 | compBufferPointer = length; // mov %rax,%r8 517 | compBufferPointer -= negativeOffset; // sub %r12,%r8 518 | 519 | if (compBufferPointer < negativeOffset) // jb Llzvn_exit 520 | { 521 | return 0; 522 | } 523 | 524 | jmpTo = LZVN_4; 525 | break; // jmpq *(%rbx,%r9,8) 526 | 527 | case LZVN_11: /*********************************************************/ 528 | 529 | _LZVN_DEBUG_DUMP("jmpTable(11)\n"); 530 | 531 | compBufferPointer = length; // mov %rax,%r8 532 | compBufferPointer -= negativeOffset; // sub %r12,%r8 533 | currentLength = (length + byteCount); // lea (%rax,%r10,1),%r11 534 | 535 | if (currentLength < decompressedSize) // cmp %rsi,%r11 536 | { 537 | if (negativeOffset >= 8) // cmp $0x8,%r12 538 | { 539 | jmpTo = LZVN_5; // jae Llzvn_l5 540 | break; 541 | } 542 | } 543 | 544 | jmpTo = LZVN_4; // jmp Llzvn_l4 545 | break; 546 | } // switch (jmpq) 547 | 548 | } while (1); 549 | 550 | return 0; 551 | } 552 | 553 | -------------------------------------------------------------------------------- /FastCompression.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Created..: 31 October 2014 3 | * Filename.: FastCompression.h 4 | * Author...: Pike R. Alpha 5 | * Purpose..: Command line tool to LZVN compress a file. 6 | */ 7 | 8 | extern size_t lzvn_encode(void * dst, size_t dst_size, const void * src, size_t src_size, void * work_space); 9 | extern size_t lzvn_decode(void * dst, size_t dst_size, const void * src, size_t src_size); 10 | extern size_t lzvn_encode_work_size(void); 11 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | ## 2 | # 3 | # LZVN encode/decode routines 4 | # 5 | # Intel 64-bit (x86_64) version 6 | # 7 | ## 8 | 9 | PREFIX=/usr/local 10 | 11 | AS=as 12 | AR=ar 13 | CC=cc 14 | RANLIB=ranlib 15 | INSTALL=install 16 | ASFLAGS=-arch x86_64 17 | ARFLAGS=cru 18 | CFLAGS=-arch x86_64 -O2 19 | FRAMEWORKS=-framework IOKit -framework CoreFoundation 20 | 21 | all: clean lzvn 22 | 23 | .s.o: 24 | $(AS) $(ASFLAGS) -o $@ $< 25 | 26 | .c.o: 27 | $(CC) $(CFLAGS) -c $< -o $@ 28 | 29 | libFastCompression.a: lzvn_encode.o lzvn_decode.o 30 | $(AR) $(ARFLAGS) $@ lzvn_encode.o lzvn_decode.o 31 | $(RANLIB) libFastCompression.a 32 | 33 | lzvn: lzvn.o libFastCompression.a 34 | $(CC) $(CFLAGS) -o $@ lzvn.o -L. -lFastCompression $(FRAMEWORKS) 35 | 36 | clean: 37 | clear 38 | rm -f *.o *.a lzvn 39 | 40 | install: lzvn.h 41 | $(INSTALL) lzvn $(PREFIX)/bin 42 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | LZVN 2 | ==== 3 | 4 | You can download the source code of LZVN and pre-compiled copies of libFastCompression.a and libFastCompression-Kernel.a with: 5 | 6 | ``` sh 7 | curl -o LZVN.zip https://codeload.github.com/Piker-Alpha/LZVN/zip/master 8 | ``` 9 | 10 | 11 | Unzip 12 | ----- 13 | 14 | You can unzip the downloaded archive with: 15 | 16 | ``` 17 | unzip -qu LZVN.zip [-d target directory] 18 | ``` 19 | 20 | 21 | Make instructions 22 | ----------------- 23 | 24 | ``` 25 | make 26 | ``` 27 | 28 | Note: You don't need to run: ```make clean``` first because that is done automatically. 29 | 30 | 31 | Installation 32 | ------------ 33 | 34 | You can install the executable with: 35 | 36 | ``` 37 | make install 38 | ``` 39 | 40 | Note: The executable will be copied to: /usr/local/bin 41 | 42 | 43 | Usage 44 | ----- 45 | 46 | ``` 47 | ./lzvn 48 | ./lzvn -d 49 | ./lzvn -d kernel 50 | ./lzvn -d dictionary 51 | ./lzvn -d kexts 52 | ./lzvn -d list 53 | ``` 54 | 55 | The kernel argument will extract the kernel from the given prelinkedkernel. 56 | The dictionary argument will extract the dictionary containing the Info.plist of all kexts. 57 | The kexts argument will extract all kexts to a ./kexts folder. 58 | The list argument will show a list of all the included kexts. 59 | 60 | 61 | Bugs 62 | ---- 63 | 64 | All possible bugs (so called 'issues') should be filed at: 65 | 66 | https://github.com/Piker-Alpha/LZVN/issues 67 | 68 | Please do **not** use my blog for this. Thank you! 69 | -------------------------------------------------------------------------------- /lib/x86_64/libFastCompression-Kernel.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Piker-Alpha/LZVN/ae2acd11127ebc7ebcc7a7da359e9ca73eb169a5/lib/x86_64/libFastCompression-Kernel.a -------------------------------------------------------------------------------- /lib/x86_64/libFastCompression.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Piker-Alpha/LZVN/ae2acd11127ebc7ebcc7a7da359e9ca73eb169a5/lib/x86_64/libFastCompression.a -------------------------------------------------------------------------------- /lzvn.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Created: 31 October 2014 3 | * Name...: lzvn.c 4 | * Author.: Pike R. Alpha 5 | * Purpose: Command line tool to LZVN encode/decode a prelinked kernel/file. 6 | * 7 | * Updates: 8 | * - Support for lzvn_decode() added (Pike R. Alpha, November 2014). 9 | * - Support for prelinkedkernels added (Pike R. Alpha, December 2014). 10 | * - Debug output data added (Pike R. Alpha, July 2015). 11 | * - Prelinkedkerel check added (Pike R. Alpha, August 2015). 12 | * - Mach header injection for prelinkedkernels added (Pike R. Alpha, August 2015). 13 | * - Extract kernel option added (Pike R. Alpha, August 2015). 14 | * - Extract dictionary option added (Pike R. Alpha, September 2015). 15 | * - Extract kexts option added (Pike R. Alpha, September 2015). 16 | * – Function find_load_command() added (Pike R. Alpha, September 2015). 17 | * - Save Dictionary.plist in proper XML format. 18 | * - Show number of signed and unsigned kexts. 19 | * - Usage now shows 'lzvn' once. 20 | * - Show list of kexts added (Pike R. Alpha, Januari 2016). 21 | * - Fixed encoding of files with a FAT header (Pike R. Alpha, July 2017). 22 | */ 23 | 24 | #include "lzvn.h" 25 | 26 | 27 | //============================================================================== 28 | 29 | int main(int argc, const char * argv[]) 30 | { 31 | FILE *fp = NULL; 32 | 33 | unsigned char * fileBuffer = NULL; 34 | unsigned char * workSpaceBuffer = NULL; 35 | unsigned char * bufend = NULL; 36 | unsigned char * buffer = NULL; 37 | 38 | PrelinkedKernelHeader * prelinkHeader = NULL; 39 | struct fat_header * fatHeader = NULL; 40 | struct fat_arch * fatArch = NULL; 41 | 42 | unsigned int offset = 0; 43 | 44 | unsigned long fileLength = 0; 45 | unsigned long byteshandled = 0; 46 | unsigned long file_adler32 = 0; 47 | unsigned long buffer_adler32 = 0; 48 | 49 | size_t compressedSize = 0; 50 | size_t workSpaceSize = 0; 51 | 52 | if (argc < 3 || argc > 4) 53 | { 54 | printf("Usage (encode): lzvn \n"); 55 | printf("Usage (decode): lzvn -d \n"); 56 | printf("Usage (decode): lzvn -d kernel\n"); 57 | printf("Usage (decode): lzvn -d dictionary\n"); 58 | printf("Usage (decode): lzvn -d kexts\n"); 59 | printf("Usage (decode): lzvn -d list\n"); 60 | exit(-1); 61 | } 62 | else 63 | { 64 | // Do we need to decode a file? 65 | if (!strncmp(argv[1], "-d", 2)) 66 | { 67 | // Yes. Try to open the file. 68 | fp = fopen(argv[2], "rb"); 69 | 70 | // Check file pointer. 71 | if (fp == NULL) 72 | { 73 | printf("Error: Opening of %s failed... exiting\nDone.\n", argv[1]); 74 | exit(-1); 75 | } 76 | else 77 | { 78 | fseek(fp, 0, SEEK_END); 79 | fileLength = ftell(fp); 80 | 81 | printf("Filesize: %ld bytes\n", fileLength); 82 | 83 | fseek(fp, 0, SEEK_SET); 84 | fileBuffer = malloc(fileLength); 85 | 86 | if (fileBuffer == NULL) 87 | { 88 | printf("ERROR: Failed to allocate file buffer... exiting\nAborted!\n\n"); 89 | fclose(fp); 90 | exit(-1); 91 | } 92 | else 93 | { 94 | fread(fileBuffer, fileLength, 1, fp); 95 | fclose(fp); 96 | 97 | // Check for a FAT header. 98 | fatHeader = (struct fat_header *) fileBuffer; 99 | 100 | if (fatHeader->magic == FAT_CIGAM) 101 | { 102 | unsigned int i = 1; 103 | fatArch = (struct fat_arch *)(fileBuffer + sizeof(fatHeader)); 104 | prelinkHeader = (PrelinkedKernelHeader *)((unsigned char *)fileBuffer + OSSwapInt32(fatArch->offset)); 105 | 106 | while ((i < OSSwapInt32(fatHeader->nfat_arch)) && (prelinkHeader->signature != OSSwapInt32('comp'))) 107 | { 108 | printf("Scanning ...\n"); 109 | fatArch = (struct fat_arch *)((unsigned char *)fatArch + sizeof(fatArch)); 110 | prelinkHeader = (PrelinkedKernelHeader *)(fileBuffer + OSSwapInt32(fatArch->offset)); 111 | ++i; 112 | } 113 | 114 | // Is this a LZVN compressed file? 115 | if (prelinkHeader->compressType == OSSwapInt32('lzvn')) 116 | { 117 | printf("Prelinkedkernel found!\n"); 118 | fileBuffer = (unsigned char *)prelinkHeader + sizeof(PrelinkedKernelHeader); 119 | workSpaceSize = OSSwapInt32(prelinkHeader->uncompressedSize); 120 | fileLength = OSSwapInt32(prelinkHeader->compressedSize); 121 | } 122 | else 123 | { 124 | printf("ERROR: Unsupported compression format detected!\n"); 125 | exit(-1); 126 | } 127 | } 128 | else 129 | { 130 | prelinkHeader = (PrelinkedKernelHeader *)(unsigned char *)fileBuffer; 131 | 132 | if (prelinkHeader->signature == OSSwapInt32('comp') && prelinkHeader->compressType == OSSwapInt32('lzvn')) 133 | { 134 | fileBuffer = (unsigned char *)prelinkHeader + sizeof(PrelinkedKernelHeader); 135 | workSpaceSize = OSSwapInt32(prelinkHeader->uncompressedSize); 136 | fileLength = OSSwapInt32(prelinkHeader->compressedSize); 137 | } 138 | else 139 | { 140 | // printf("Getting WorkSpaceSize\n"); 141 | workSpaceSize = lzvn_encode_work_size(); 142 | } 143 | } 144 | 145 | // printf("workSpaceSize: %ld \n", workSpaceSize); 146 | workSpaceBuffer = malloc(workSpaceSize); 147 | 148 | if (workSpaceBuffer == NULL) 149 | { 150 | printf("ERROR: Failed to allocate workSpaceBuffer ... exiting\nAborted!\n\n"); 151 | exit(-1); 152 | } 153 | else 154 | { 155 | /* if (workSpaceSize > 0x80000) 156 | { */ 157 | compressedSize = lzvn_decode(workSpaceBuffer, workSpaceSize, fileBuffer, fileLength); 158 | 159 | if (compressedSize > 0) 160 | { 161 | // Are we unpacking a prelinkerkernel? 162 | if (is_prelinkedkernel(workSpaceBuffer)) 163 | { 164 | printf("Checking adler32 ... "); 165 | 166 | // Yes. Check adler32. 167 | if (OSSwapInt32(prelinkHeader->adler32) != local_adler32(workSpaceBuffer, workSpaceSize)) 168 | { 169 | printf("ERROR: Adler32 mismatch!\n"); 170 | free(workSpaceBuffer); 171 | fclose(fp); 172 | exit(-1); 173 | } 174 | else 175 | { 176 | printf("OK (0x%08x)\n", OSSwapInt32(prelinkHeader->adler32)); 177 | 178 | // Do we need to write the _PrelinkInfoDictionary to disk? 179 | if (strstr(argv[3], "dictionary") || strstr(argv[3], "kexts")) 180 | { 181 | printf("Extracting dictionary ...\n"); 182 | saveDictionary(workSpaceBuffer); 183 | } 184 | 185 | if (strstr(argv[3], "kexts")) 186 | { 187 | printf("Extracting kexts ...\n"); 188 | saveKexts(workSpaceBuffer); 189 | } 190 | 191 | if (strstr(argv[3], "list")) 192 | { 193 | printf("Getting list of kexts ...\n"); 194 | listKexts(workSpaceBuffer); 195 | } 196 | 197 | // Do we need to write the kernel to disk? 198 | if (strcmp(argv[3], "kernel") == 0) 199 | { 200 | printf("Extracting kernel ...\n"); 201 | saveKernel(workSpaceBuffer); 202 | } 203 | 204 | if (gSaveAll) 205 | { 206 | openFile((char *)argv[3]); 207 | printf("Decoding prelinkedkernel ...\nWriting data to: %s\n", argv[3]); 208 | fwrite(workSpaceBuffer, 1, compressedSize, fp); 209 | printf("%ld bytes written\n", ftell(fp)); 210 | fclose(fp); 211 | } 212 | } 213 | } 214 | else 215 | { 216 | printf("Decoding data ...\nWriting data to: %s\n", argv[3]); 217 | fwrite(workSpaceBuffer, 1, compressedSize, fp); 218 | printf("%ld bytes written\n", ftell(fp)); 219 | fclose(fp); 220 | } 221 | } 222 | /* } 223 | else 224 | { 225 | while ((compressedSize = lzvn_decode(workSpaceBuffer, workSpaceSize, fileBuffer, fileLength)) > 0) 226 | { 227 | printf("compressedSize: %ld\n", compressedSize); 228 | fwrite(workSpaceBuffer, 1, compressedSize, fp); 229 | fileBuffer += workSpaceSize; 230 | byteshandled += workSpaceSize; 231 | } 232 | 233 | fileBuffer -= byteshandled; 234 | } */ 235 | 236 | free(workSpaceBuffer); 237 | 238 | printf("\nDone.\n"); 239 | exit(0); 240 | } 241 | } 242 | } 243 | } 244 | else // Do we need to encode a file? 245 | { 246 | fp = fopen(argv[1], "rb"); 247 | 248 | if (fp == NULL) 249 | { 250 | printf("Error: Opening of %s failed... exiting\nDone.\n", argv[1]); 251 | exit(-1); 252 | } 253 | else 254 | { 255 | fseek(fp, 0, SEEK_END); 256 | fileLength = ftell(fp); 257 | printf("fileLength...: %ld/0x%08lx - %s\n", fileLength, fileLength, argv[1]); 258 | fseek(fp, 0, SEEK_SET); 259 | 260 | fileBuffer = malloc(fileLength); 261 | 262 | if (fileBuffer == NULL) 263 | { 264 | printf("ERROR: Failed to allocate file buffer... exiting\nAborted!\n\n"); 265 | fclose(fp); 266 | exit(-1); 267 | } 268 | else 269 | { 270 | fread(fileBuffer, fileLength, 1, fp); 271 | fclose(fp); 272 | 273 | size_t workSpaceSize = lzvn_encode_work_size(); 274 | void * workSpace = malloc(workSpaceSize); 275 | 276 | if (workSpace == NULL) 277 | { 278 | printf("\nERROR: Failed to allocate workspace... exiting\nAborted!\n\n"); 279 | exit(-1); 280 | } 281 | else 282 | { 283 | printf("workSpaceSize: %ld/0x%08lx\n", workSpaceSize, workSpaceSize); 284 | 285 | if (fileLength > workSpaceSize) 286 | { 287 | workSpaceSize = fileLength; 288 | } 289 | 290 | workSpaceBuffer = (void *)malloc(workSpaceSize); 291 | 292 | if (workSpaceBuffer == NULL) 293 | { 294 | printf("ERROR: Failed to allocate workSpaceBuffer ... exiting\nAborted!\n\n"); 295 | exit(-1); 296 | } 297 | else 298 | { 299 | // Check for a FAT header. 300 | fatHeader = (struct fat_header *) fileBuffer; 301 | 302 | if (fatHeader->magic == FAT_CIGAM) 303 | { 304 | fatArch = (struct fat_arch *)(fileBuffer + sizeof(fatHeader)); 305 | offset = OSSwapInt32(fatArch->offset); 306 | } 307 | 308 | file_adler32 = local_adler32((fileBuffer + offset), fileLength); 309 | printf("adler32......: 0x%08lx\n", file_adler32); 310 | 311 | 312 | size_t outSize = lzvn_encode(workSpaceBuffer, workSpaceSize, (u_int8_t *)(fileBuffer + offset), (size_t)fileLength, workSpace); 313 | printf("outSize......: %ld/0x%08lx\n", outSize, outSize); 314 | 315 | free(workSpace); 316 | 317 | if (outSize != 0) 318 | { 319 | bufend = workSpaceBuffer + outSize; 320 | compressedSize = bufend - workSpaceBuffer; 321 | printf("compressedSize.....: %ld/0x%08lx\n", compressedSize, compressedSize); 322 | 323 | fp = fopen (argv[2], "wb"); 324 | 325 | // Do we need to inject the mach header? 326 | if (is_prelinkedkernel(fileBuffer + offset)) 327 | { 328 | printf("Fixing file header for prelinkedkernel ...\n"); 329 | 330 | // Inject arch offset into the header. 331 | gFileHeader[5] = OSSwapInt32(sizeof(gFileHeader) + outSize - 28); 332 | // Inject the value of file_adler32 into the header. 333 | gFileHeader[9] = OSSwapInt32(file_adler32); 334 | // Inject the uncompressed size into the header. 335 | gFileHeader[10] = OSSwapInt32(fileLength); 336 | // Inject the compressed size into the header. 337 | gFileHeader[11] = OSSwapInt32(compressedSize); 338 | 339 | printf("Writing fixed up file header ...\n"); 340 | 341 | fwrite(gFileHeader, (sizeof(gFileHeader) / sizeof(u_int32_t)), 4, fp); 342 | } 343 | 344 | printf("Writing workspace buffer ...\n"); 345 | 346 | fwrite(workSpaceBuffer, outSize, 1, fp); 347 | fclose(fp); 348 | printf("Done.\n"); 349 | } 350 | } 351 | 352 | free(fileBuffer); 353 | free(workSpaceBuffer); 354 | 355 | exit(0); 356 | 357 | } 358 | } 359 | } 360 | } 361 | } 362 | 363 | exit(-1); 364 | } 365 | -------------------------------------------------------------------------------- /lzvn.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Created..: 31 October 2014 3 | * Filename.: lzvn.c 4 | * Author...: Pike R. Alpha 5 | * Purpose..: Command line tool to LZVN encode/decode a file. 6 | * 7 | * Updates: 8 | * - Prelinkedkerel check added (Pike R. Alpha, August 2015). 9 | * - Mach header injection for prelinkedkernels added (Pike R. Alpha, August 2015). 10 | * - Extract kernel option added (Pike R. Alpha, August 2015). 11 | * - Extract dictionary option added (Pike R. Alpha, September 2015). 12 | * - Extract kexts option added (Pike R. Alpha, September 2015). 13 | * – Function find_load_command() added (Pike R. Alpha, September 2015). 14 | * - Save Dictionary.plist in proper XML format. 15 | * - Show number of signed and unsigned kexts. 16 | */ 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #include 24 | #include 25 | #include 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | #include 33 | 34 | #include 35 | #include 36 | 37 | #include "FastCompression.h" 38 | #include "prelink.h" 39 | 40 | /* 41 | * Copied from: kext_tools/kext_tools-326.95.1/kernelcache.h 42 | */ 43 | 44 | #define PLATFORM_NAME_LEN (64) 45 | #define ROOT_PATH_LEN (256) 46 | 47 | typedef struct prelinked_kernel_header 48 | { 49 | uint32_t signature; 50 | uint32_t compressType; 51 | uint32_t adler32; 52 | uint32_t uncompressedSize; 53 | uint32_t compressedSize; 54 | uint32_t prelinkVersion; // value >= 1 means KASLR supported 55 | uint32_t reserved[10]; 56 | char platformName[PLATFORM_NAME_LEN]; // unused 57 | char rootPath[ROOT_PATH_LEN]; // unused 58 | char data[0]; 59 | } PrelinkedKernelHeader; 60 | 61 | static u_int32_t gFileHeader[ 103 ] = 62 | { 63 | 0xBEBAFECA, 0x01000000, 0x07000001, 0x03000000, 0x1C000000, 0xFFFFFFFF, 0x00000000, 0x706D6F63, 64 | 0x6E767A6C, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x01000000, 0x00000000, 0x00000000, 0x00000000, 65 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 66 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 67 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 68 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 69 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 70 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 71 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 72 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 73 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 74 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 75 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 76 | }; 77 | 78 | boolean_t gSaveAll = TRUE; 79 | 80 | /*============================================================================== 81 | * Copied from: kext_tools/kext_tools-326.95.1/kernelcache.c 82 | */ 83 | 84 | u_int32_t local_adler32(u_int8_t * buffer, int32_t length) 85 | { 86 | int32_t cnt; 87 | u_int32_t result, lowHalf, highHalf; 88 | 89 | lowHalf = 1; 90 | highHalf = 0; 91 | 92 | for (cnt = 0; cnt < length; cnt++) { 93 | if ((cnt % 5000) == 0) { 94 | lowHalf %= 65521L; 95 | highHalf %= 65521L; 96 | } 97 | 98 | lowHalf += buffer[cnt]; 99 | highHalf += lowHalf; 100 | } 101 | 102 | lowHalf %= 65521L; 103 | highHalf %= 65521L; 104 | 105 | result = (highHalf << 16) | lowHalf; 106 | 107 | return result; 108 | } 109 | 110 | 111 | //============================================================================== 112 | 113 | struct load_command * find_load_command(struct mach_header_64 *machHeader, uint32_t targetCmd) 114 | { 115 | struct load_command *loadCommand; 116 | 117 | // First LOAD_COMMAND begins after the mach header. 118 | loadCommand = (struct load_command *)((uint64_t)machHeader + sizeof(struct mach_header_64)); 119 | 120 | while ((uint64_t)loadCommand < (uint64_t)machHeader + (uint64_t)machHeader->sizeofcmds + sizeof(struct mach_header_64)) 121 | { 122 | if (loadCommand->cmd == targetCmd) 123 | { 124 | return (struct load_command *)loadCommand; 125 | } 126 | 127 | // Next load command. 128 | loadCommand = (struct load_command *)((uint64_t)loadCommand + (uint64_t)loadCommand->cmdsize); 129 | } 130 | 131 | // Return NULL on failure (not found). 132 | return NULL; 133 | } 134 | 135 | 136 | //============================================================================== 137 | 138 | struct segment_command_64 * find_segment_64(struct mach_header_64 * aMachHeader, const char * aSegmentName) 139 | { 140 | struct load_command *loadCommand; 141 | struct segment_command_64 *segment; 142 | 143 | // First LOAD_COMMAND begins straight after the mach header. 144 | loadCommand = (struct load_command *)((uint64_t)aMachHeader + sizeof(struct mach_header_64)); 145 | 146 | while ((uint64_t)loadCommand < (uint64_t)aMachHeader + (uint64_t)aMachHeader->sizeofcmds + sizeof(struct mach_header_64)) 147 | { 148 | if (loadCommand->cmd == LC_SEGMENT_64) 149 | { 150 | // Check load command's segment name. 151 | segment = (struct segment_command_64 *)loadCommand; 152 | 153 | if (strcmp(segment->segname, aSegmentName) == 0) 154 | { 155 | return segment; 156 | } 157 | } 158 | 159 | // Next load command. 160 | loadCommand = (struct load_command *)((uint64_t)loadCommand + (uint64_t)loadCommand->cmdsize); 161 | } 162 | 163 | // Return NULL on failure (segment not found). 164 | return NULL; 165 | } 166 | 167 | 168 | //============================================================================== 169 | 170 | uint8_t is_prelinkedkernel(unsigned char * aFileBuffer) 171 | { 172 | struct segment_command_64 * prelinkTextSegment = NULL; 173 | struct segment_command_64 * prelinkInfoSegment = NULL; 174 | 175 | struct mach_header_64 * machHeader = (struct mach_header_64 *)((unsigned char *)aFileBuffer); 176 | 177 | prelinkTextSegment = find_segment_64(machHeader, "__PRELINK_TEXT"); 178 | prelinkInfoSegment = find_segment_64(machHeader, "__PRELINK_INFO"); 179 | 180 | if ((prelinkTextSegment && prelinkInfoSegment->filesize) && 181 | (prelinkTextSegment && prelinkTextSegment->filesize)) 182 | { 183 | return 1; 184 | } 185 | 186 | return 0; 187 | } 188 | 189 | 190 | //============================================================================== 191 | 192 | uint8_t saveKernel(unsigned char * aFileBuffer) 193 | { 194 | struct segment_command_64 * lastSegment = NULL; 195 | struct segment_command_64 * prelinkTextSegment = NULL; 196 | struct segment_command_64 * prelinkInfoSegment = NULL; 197 | struct segment_command_64 * linkeditSegment = NULL; 198 | 199 | struct section_64 * prelinkTextSection = NULL; 200 | struct section_64 * prelinkInfoSection = NULL; 201 | 202 | struct mach_header_64 * machHeader = (struct mach_header_64 *)((unsigned char *)aFileBuffer); 203 | 204 | if ((lastSegment = find_segment_64(machHeader, "__LAST")) == NULL) 205 | { 206 | printf("ERROR: find_segment_64(\"__LAST\") failed!\n"); 207 | return -1; 208 | } 209 | 210 | if ((prelinkTextSegment = find_segment_64(machHeader, "__PRELINK_TEXT")) == NULL) 211 | { 212 | printf("ERROR: find_segment_64(\"__PRELINK_TEXT\") failed!\n"); 213 | return -1; 214 | } 215 | 216 | if ((prelinkInfoSegment = find_segment_64(machHeader, "__PRELINK_INFO")) == NULL) 217 | { 218 | printf("ERROR: find_segment_64(\"__PRELINK_INFO\") failed!\n"); 219 | return -1; 220 | } 221 | 222 | if ((linkeditSegment = find_segment_64(machHeader, SEG_LINKEDIT)) == NULL) 223 | { 224 | printf("ERROR: find_segment_64(\"__LINKEDIT\") failed!\n"); 225 | return -1; 226 | } 227 | 228 | prelinkTextSegment->vmaddr = linkeditSegment->vmaddr; 229 | prelinkTextSegment->vmsize = 0; 230 | prelinkTextSegment->fileoff = (lastSegment->fileoff + lastSegment->filesize); 231 | prelinkTextSegment->filesize = 0; 232 | 233 | prelinkTextSection = (struct section_64 *)((uint64_t)prelinkTextSegment + sizeof(struct segment_command_64)); 234 | 235 | prelinkTextSection->addr = prelinkTextSegment->vmaddr; 236 | prelinkTextSection->size = 0; 237 | prelinkTextSection->offset = prelinkTextSegment->fileoff; 238 | 239 | prelinkInfoSegment->vmaddr = linkeditSegment->vmaddr; 240 | prelinkInfoSegment->vmsize = 0; 241 | prelinkInfoSegment->fileoff = (lastSegment->fileoff + lastSegment->filesize); 242 | prelinkInfoSegment->filesize = 0; 243 | 244 | prelinkInfoSection = (struct section_64 *)((uint64_t)prelinkInfoSegment + sizeof(struct segment_command_64)); 245 | 246 | prelinkInfoSection->addr = prelinkTextSegment->vmaddr; 247 | prelinkInfoSection->size = 0; 248 | prelinkInfoSection->offset = prelinkInfoSegment->fileoff; 249 | 250 | FILE *fp = fopen("kernel", "wb"); 251 | fwrite(aFileBuffer, 1, (long)(linkeditSegment->fileoff + linkeditSegment->filesize), fp); 252 | printf("%ld bytes written\n", ftell(fp)); 253 | fclose(fp); 254 | 255 | gSaveAll = FALSE; 256 | 257 | return 0; 258 | } 259 | 260 | 261 | //============================================================================== 262 | 263 | uint8_t saveDictionary(unsigned char * aFileBuffer) 264 | { 265 | struct segment_command_64 * prelinkInfoSegment = NULL; 266 | struct mach_header_64 * machHeader = (struct mach_header_64 *)((unsigned char *)aFileBuffer); 267 | 268 | if ((prelinkInfoSegment = find_segment_64(machHeader, "__PRELINK_INFO")) == NULL) 269 | { 270 | printf("ERROR: find_segment_64(\"__PRELINK_INFO\") failed!\n"); 271 | return -1; 272 | } 273 | 274 | const char * prelinkInfoBytes = (const char *)aFileBuffer + prelinkInfoSegment->fileoff; 275 | 276 | CFPropertyListRef prelinkInfoPlist = (CFPropertyListRef)IOCFUnserialize(prelinkInfoBytes, kCFAllocatorDefault, /* options */ 0, /* errorString */ NULL); 277 | 278 | if (prelinkInfoPlist) 279 | { 280 | printf("NOTICE: Unserialized _PrelinkInfoDictionary\n"); 281 | 282 | CFErrorRef xmlError = NULL; 283 | CFDataRef xmlData = CFPropertyListCreateData(kCFAllocatorDefault, prelinkInfoPlist, kCFPropertyListXMLFormat_v1_0, 0, &xmlError); 284 | 285 | if (xmlError == NULL) 286 | { 287 | const unsigned char * buffer = CFDataGetBytePtr(xmlData); 288 | long xmlLength = CFDataGetLength(xmlData); 289 | 290 | FILE *fp = fopen("Dictionary.plist", "w"); 291 | fwrite(buffer, 1, xmlLength, fp); 292 | printf("%ld bytes written\n", ftell(fp)); 293 | fclose(fp); 294 | } 295 | } 296 | 297 | gSaveAll = FALSE; 298 | 299 | return 0; 300 | } 301 | 302 | 303 | //============================================================================== 304 | 305 | int _mkdir(char * aDirectory, mode_t aMode) 306 | { 307 | char * p = aDirectory; 308 | 309 | struct stat sb; 310 | 311 | // Skip leading slashes. 312 | while (*p == '/') 313 | { 314 | p++; 315 | } 316 | 317 | while ((p = strchr(p, '/'))) 318 | { 319 | *p = '\0'; 320 | 321 | if (stat(aDirectory, &sb) != 0) 322 | { 323 | if (mkdir(aDirectory, aMode)) 324 | { 325 | printf("Error: cannot create directory: %s\n", aDirectory); 326 | return 1; 327 | } 328 | } 329 | 330 | // Restore slash. 331 | *p++ = '/'; 332 | 333 | while (*p == '/') 334 | { 335 | p++; 336 | } 337 | } 338 | 339 | // Create the final directory component. 340 | if (stat(aDirectory, &sb) && mkdir(aDirectory, aMode)) 341 | { 342 | printf("Error: cannot create directory: %s", aDirectory); 343 | return 1; 344 | } 345 | 346 | return 0; 347 | } 348 | 349 | 350 | //============================================================================== 351 | 352 | uint8_t saveKexts(unsigned char * aFileBuffer) 353 | { 354 | int signedKexts = 0; 355 | 356 | struct segment_command_64 * prelinkTextSegment = NULL; 357 | struct segment_command_64 * prelinkInfoSegment = NULL; 358 | struct mach_header_64 * machHeader = (struct mach_header_64 *)((unsigned char *)aFileBuffer); 359 | struct linkedit_data_command *codeSignature = NULL; 360 | 361 | prelinkTextSegment = find_segment_64(machHeader, "__PRELINK_TEXT"); 362 | prelinkInfoSegment = find_segment_64(machHeader, "__PRELINK_INFO"); 363 | 364 | if (prelinkTextSegment && prelinkInfoSegment) 365 | { 366 | printf("prelinkInfoSegment->vmaddr..: 0x%llx\n", prelinkInfoSegment->vmaddr); 367 | printf("prelinkInfoSegment->fileoff.: 0x%llx\n", prelinkInfoSegment->fileoff); 368 | printf("prelinkInfoSegment->filesize: 0x%llx\n", prelinkInfoSegment->filesize); 369 | 370 | const char * prelinkInfoBytes = (const char *)aFileBuffer + prelinkInfoSegment->fileoff; 371 | 372 | CFPropertyListRef prelinkInfoPlist = (CFPropertyListRef)IOCFUnserialize(prelinkInfoBytes, kCFAllocatorDefault, /* options */ 0, /* errorString */ NULL); 373 | 374 | if (prelinkInfoPlist) 375 | { 376 | printf("NOTICE: Unserialized prelink info\n"); 377 | 378 | CFArrayRef kextPlistArray = NULL; 379 | kextPlistArray = (CFArrayRef)CFDictionaryGetValue(prelinkInfoPlist, CFSTR("_PrelinkInfoDictionary")); 380 | CFIndex i = 0; 381 | CFIndex kextCount = CFArrayGetCount(kextPlistArray); 382 | printf("kextCount: %ld\n", kextCount); 383 | 384 | char kextIdentifierBuffer[64]; // KMOD_MAX_NAME = 64 385 | char kextBundlePathBuffer[PATH_MAX]; 386 | char kextPath[PATH_MAX]; 387 | char kextPlistPath[PATH_MAX]; 388 | char kextExecutablePath[PATH_MAX]; 389 | 390 | struct stat st = {0}; 391 | 392 | if (kextCount && stat("kexts", &st) == -1) 393 | { 394 | mkdir("kexts", 0755); 395 | } 396 | 397 | for (i = 0; i < kextCount; i++) 398 | { 399 | // printf("kextPlist: 0x%llx\n", (int64_t)kextPlist - (int64_t)fileBuffer - prelinkInfoSegment->fileoff); 400 | CFDictionaryRef kextPlist = (CFDictionaryRef)CFArrayGetValueAtIndex(kextPlistArray, i); 401 | CFStringRef kextIdentifier = (CFStringRef)CFDictionaryGetValue(kextPlist, kCFBundleIdentifierKey); 402 | 403 | if (kextIdentifier) 404 | { 405 | CFStringGetCString(kextIdentifier, kextIdentifierBuffer, sizeof(kextIdentifierBuffer), kCFStringEncodingUTF8); 406 | printf("\nCFBundleIdentifier[%3ld].......: %s\n", i, kextIdentifierBuffer); 407 | } 408 | 409 | CFStringRef bundlePath = (CFStringRef)CFDictionaryGetValue(kextPlist, CFSTR(kPrelinkBundlePathKey)); 410 | 411 | if (bundlePath) 412 | { 413 | CFStringGetCString(bundlePath, kextBundlePathBuffer, sizeof(kextBundlePathBuffer), kCFStringEncodingUTF8); 414 | printf("_PrelinkBundlePath............: %s\n", kextBundlePathBuffer); 415 | 416 | sprintf(kextPath, "kexts%s", kextBundlePathBuffer); 417 | printf("kextPath......................: %s\n", kextPath); 418 | 419 | if (stat(kextPath, &st) == -1) 420 | { 421 | printf("_mkdir(%s, 755)\n", kextPath); 422 | _mkdir(kextPath, 0755); 423 | } 424 | } 425 | 426 | CFStringRef executableRelativePath = (CFStringRef)CFDictionaryGetValue(kextPlist, CFSTR(kPrelinkExecutableRelativePathKey)); 427 | 428 | if (executableRelativePath) 429 | { 430 | CFStringGetCString(executableRelativePath, kextBundlePathBuffer, sizeof(kextBundlePathBuffer), kCFStringEncodingUTF8); 431 | printf("_PrelinkExecutableRelativePath: %s\n", kextBundlePathBuffer); 432 | 433 | if (strncmp(kextBundlePathBuffer, "Contents/MacOS/", 15) == 0) 434 | { 435 | sprintf(kextExecutablePath, "%s/Contents/MacOS", kextPath); 436 | printf("kextExecutablePath............: %s\n", kextExecutablePath); 437 | 438 | if (stat(kextExecutablePath, &st) == -1) 439 | { 440 | _mkdir(kextExecutablePath, 0755); 441 | printf("_mkdir(%s, 755)\n", kextExecutablePath); 442 | } 443 | } 444 | else 445 | { 446 | sprintf(kextExecutablePath, "%s", kextPath); 447 | printf("kextExecutablePath............: %s\n", kextExecutablePath); 448 | } 449 | } 450 | 451 | CFStringRef executableName = (CFStringRef)CFDictionaryGetValue(kextPlist, kCFBundleExecutableKey); 452 | 453 | if (executableName) 454 | { 455 | uint64_t offset = 0; 456 | uint64_t sourceAddress = 0; 457 | uint64_t sourceSize = 0; 458 | 459 | CFStringGetCString(executableName, kextIdentifierBuffer, sizeof(kextIdentifierBuffer), kCFStringEncodingUTF8); 460 | printf("CFBundleIdentifier............: %s\n", kextIdentifierBuffer); 461 | 462 | CFNumberRef kextSourceAddress = (CFNumberRef)CFDictionaryGetValue(kextPlist, CFSTR(kPrelinkExecutableSourceKey)); 463 | 464 | if (kextSourceAddress) 465 | { 466 | CFNumberGetValue(kextSourceAddress, kCFNumberSInt64Type, &sourceAddress); 467 | offset = ((sourceAddress - prelinkTextSegment->vmaddr) + prelinkTextSegment->fileoff); 468 | printf("_PrelinkExecutableSourceAddr..: 0x%llx -> 0x%llx/%lld (offset)\n", sourceAddress, offset, offset); 469 | } 470 | 471 | CFNumberRef kextSourceSize = (CFNumberRef)CFDictionaryGetValue(kextPlist, CFSTR(kPrelinkExecutableSizeKey)); 472 | 473 | if (kextSourceSize) 474 | { 475 | CFNumberGetValue(kextSourceSize, kCFNumberSInt64Type, &sourceSize); 476 | printf("_PrelinkExecutableSize........: 0x%llx/%lld\n", sourceSize, sourceSize); 477 | } 478 | 479 | machHeader = (struct mach_header_64 *)((unsigned char *)(uint64_t)aFileBuffer + offset); 480 | codeSignature = (struct linkedit_data_command *)find_load_command(machHeader, LC_CODE_SIGNATURE); 481 | 482 | if (codeSignature) 483 | { 484 | printf("Signed kext...................: Yes\n"); 485 | signedKexts++; 486 | } 487 | 488 | if (offset && sourceSize) 489 | { 490 | char executablePath[PATH_MAX]; 491 | sprintf(executablePath, "%s/%s", kextExecutablePath, kextIdentifierBuffer); 492 | printf("executablePath................: %s\n", executablePath); 493 | 494 | FILE *executable = fopen(executablePath, "w"); 495 | fwrite((aFileBuffer + offset), 1, sourceSize, executable); 496 | printf("Executable....................: %s (%ld bytes written)\n", kextIdentifierBuffer, ftell(executable)); 497 | fclose(executable); 498 | } 499 | } 500 | 501 | CFErrorRef xmlError = NULL; 502 | CFDataRef xmlData = CFPropertyListCreateData(kCFAllocatorDefault, kextPlist, kCFPropertyListXMLFormat_v1_0, 0, &xmlError); 503 | 504 | if (xmlError == NULL) 505 | { 506 | const unsigned char * buffer = CFDataGetBytePtr(xmlData); 507 | long xmlLength = CFDataGetLength(xmlData); 508 | 509 | sprintf(kextPlistPath, "%s/Info.plist", kextPath); 510 | printf("kextPlistPath.................: %s\n", kextPlistPath); 511 | 512 | FILE *infoPlist = fopen(kextPlistPath, "w"); 513 | fwrite(buffer, 1, xmlLength, infoPlist); 514 | printf("Info.plist....................: %ld bytes written\n", ftell(infoPlist)); 515 | fclose(infoPlist); 516 | } 517 | else 518 | { 519 | printf("ERROR: Failed to convert/write Info.plist\n"); 520 | } 521 | } 522 | 523 | printf("\n%ld kexts extracted (%d signed and %ld unsigned)\n", kextCount, signedKexts, (kextCount - signedKexts)); 524 | } 525 | else 526 | { 527 | printf("ERROR: Can't unserialize _PrelinkInfoDictionary!\n"); 528 | return -1; 529 | } 530 | } 531 | else 532 | { 533 | printf("ERROR: find_segment_64(\"__PRELINK_TEXT/__PRELINK_INFO\") failed!\n"); 534 | return -1; 535 | } 536 | 537 | return 0; 538 | } 539 | 540 | //============================================================================== 541 | 542 | uint8_t listKexts(unsigned char * aFileBuffer) 543 | { 544 | struct segment_command_64 * prelinkTextSegment = NULL; 545 | struct segment_command_64 * prelinkInfoSegment = NULL; 546 | struct mach_header_64 * machHeader = (struct mach_header_64 *)((unsigned char *)aFileBuffer); 547 | struct linkedit_data_command *codeSignature = NULL; 548 | 549 | prelinkTextSegment = find_segment_64(machHeader, "__PRELINK_TEXT"); 550 | prelinkInfoSegment = find_segment_64(machHeader, "__PRELINK_INFO"); 551 | 552 | if (prelinkTextSegment && prelinkInfoSegment) 553 | { 554 | const char * prelinkInfoBytes = (const char *)aFileBuffer + prelinkInfoSegment->fileoff; 555 | 556 | CFPropertyListRef prelinkInfoPlist = (CFPropertyListRef)IOCFUnserialize(prelinkInfoBytes, kCFAllocatorDefault, /* options */ 0, /* errorString */ NULL); 557 | 558 | if (prelinkInfoPlist) 559 | { 560 | printf("NOTICE: Unserialized prelink info\n"); 561 | 562 | CFArrayRef kextPlistArray = NULL; 563 | kextPlistArray = (CFArrayRef)CFDictionaryGetValue(prelinkInfoPlist, CFSTR("_PrelinkInfoDictionary")); 564 | CFIndex i = 0; 565 | CFIndex kextCount = CFArrayGetCount(kextPlistArray); 566 | printf("kextCount: %ld\n", kextCount); 567 | 568 | char kextIdentifierBuffer[64]; // KMOD_MAX_NAME = 64 569 | char kextBundlePathBuffer[PATH_MAX]; 570 | char kextPath[PATH_MAX]; 571 | char kextPlistPath[PATH_MAX]; 572 | char kextExecutablePath[PATH_MAX]; 573 | 574 | struct stat st = {0}; 575 | 576 | for (i = 0; i < kextCount; i++) 577 | { 578 | CFDictionaryRef kextPlist = (CFDictionaryRef)CFArrayGetValueAtIndex(kextPlistArray, i); 579 | CFStringRef bundlePath = (CFStringRef)CFDictionaryGetValue(kextPlist, CFSTR(kPrelinkBundlePathKey)); 580 | 581 | if (bundlePath) 582 | { 583 | CFStringGetCString(bundlePath, kextBundlePathBuffer, sizeof(kextBundlePathBuffer), kCFStringEncodingUTF8); 584 | printf("%s\n", kextBundlePathBuffer); 585 | } 586 | } 587 | } 588 | else 589 | { 590 | printf("ERROR: Can't unserialize _PrelinkInfoDictionary!\n"); 591 | return -1; 592 | } 593 | } 594 | else 595 | { 596 | printf("ERROR: find_segment_64(\"__PRELINK_TEXT/__PRELINK_INFO\") failed!\n"); 597 | return -1; 598 | } 599 | 600 | gSaveAll = FALSE; 601 | 602 | return 0; 603 | } 604 | 605 | //============================================================================== 606 | 607 | void openFile(char * aFilename) 608 | { 609 | FILE * fp = fopen(aFilename, "wb"); 610 | 611 | if (fp == NULL) 612 | { 613 | printf("Error: Opening of %s failed... exiting\nDone.\n", aFilename); 614 | exit(-1); 615 | } 616 | } 617 | -------------------------------------------------------------------------------- /lzvn_decode.s: -------------------------------------------------------------------------------- 1 | .text 2 | 3 | .globl _lzvn_decode 4 | 5 | _lzvn_decode: 6 | pushq %rbp 7 | movq %rsp, %rbp 8 | pushq %rbx 9 | pushq %r12 10 | leaq Lzvn_decode.opcode_table(%rip), %rbx 11 | # leaq 0x2f2(%rip), %rbx 12 | xorq %rax, %rax 13 | xorq %r12, %r12 14 | subq $8, %rsi 15 | jb L_0x2b4 16 | leaq -8(%rdx,%rcx), %rcx 17 | cmpq %rcx, %rdx 18 | ja L_0x2b4 19 | movzbq (%rdx), %r9 20 | movq (%rdx), %r8 21 | jmpq *(%rbx,%r9,8) 22 | 23 | L_0x037: 24 | addq $1, %rdx 25 | cmpq %rcx, %rdx 26 | ja L_0x2b4 27 | movzbq (%rdx), %r9 28 | movq (%rdx), %r8 29 | jmpq *(%rbx,%r9,8) 30 | nopw %cs:(%rax,%rax) 31 | nop 32 | 33 | L_0x056: 34 | shrq $6, %r9 35 | leaq 2(%rdx,%r9), %rdx 36 | cmpq %rcx, %rdx 37 | ja L_0x2b4 38 | movq %r8, %r12 39 | bswapq %r12 40 | movq %r12, %r10 41 | shlq $5, %r12 42 | shlq $2, %r10 43 | shrq $53, %r12 44 | shrq $61, %r10 45 | shrq $16, %r8 46 | addq $3, %r10 47 | 48 | L_0x089: 49 | leaq (%rax,%r9), %r11 50 | addq %r10, %r11 51 | cmpq %rsi, %r11 52 | jae L_0x0d2 53 | movq %r8, (%rdi,%rax) 54 | addq %r9, %rax 55 | movq %rax, %r8 56 | subq %r12, %r8 57 | jb L_0x2b4 58 | cmpq $8, %r12 59 | jb L_0x102 60 | 61 | L_0x0ae: 62 | movq (%rdi,%r8), %r9 63 | addq $8, %r8 64 | movq %r9, (%rdi,%rax) 65 | addq $8, %rax 66 | subq $8, %r10 67 | ja L_0x0ae 68 | addq %r10, %rax 69 | movzbq (%rdx), %r9 70 | movq (%rdx), %r8 71 | jmpq *(%rbx,%r9,8) 72 | 73 | L_0x0d2: 74 | testq %r9, %r9 75 | je L_0x0f6 76 | leaq 8(%rsi), %r11 77 | 78 | L_0x0db: 79 | movb %r8b, (%rdi,%rax) 80 | addq $1, %rax 81 | cmpq %rax, %r11 82 | je L_0x2b7 83 | shrq $8, %r8 84 | subq $1, %r9 85 | jne L_0x0db 86 | 87 | L_0x0f6: 88 | movq %rax, %r8 89 | subq %r12, %r8 90 | jb L_0x2b4 91 | 92 | L_0x102: 93 | leaq 8(%rsi), %r11 94 | 95 | L_0x106: 96 | movzbq (%rdi,%r8), %r9 97 | addq $1, %r8 98 | movb %r9b, (%rdi,%rax) 99 | addq $1, %rax 100 | cmpq %rax, %r11 101 | je L_0x2b7 102 | subq $1, %r10 103 | jne L_0x106 104 | movzbq (%rdx), %r9 105 | movq (%rdx), %r8 106 | jmpq *(%rbx,%r9,8) 107 | 108 | L_0x131: 109 | shrq $6, %r9 110 | leaq 1(%rdx,%r9), %rdx 111 | cmpq %rcx, %rdx 112 | ja L_0x2b4 113 | movq $56, %r10 114 | andq %r8, %r10 115 | shrq $8, %r8 116 | shrq $3, %r10 117 | addq $3, %r10 118 | jmp L_0x089 119 | 120 | L_0x15e: 121 | shrq $6, %r9 122 | leaq 3(%rdx,%r9), %rdx 123 | cmpq %rcx, %rdx 124 | ja L_0x2b4 125 | movq $56, %r10 126 | movq $65535, %r12 127 | andq %r8, %r10 128 | shrq $8, %r8 129 | shrq $3, %r10 130 | andq %r8, %r12 131 | shrq $16, %r8 132 | addq $3, %r10 133 | jmp L_0x089 134 | 135 | L_0x199: 136 | shrq $3, %r9 137 | andq $3, %r9 138 | leaq 3(%rdx,%r9), %rdx 139 | cmpq %rcx, %rdx 140 | ja L_0x2b4 141 | movq %r8, %r10 142 | andq $775, %r10 143 | shrq $10, %r8 144 | movzbq %r10b, %r12 145 | shrq $8, %r10 146 | shlq $2, %r12 147 | orq %r12, %r10 148 | movq $16383, %r12 149 | addq $3, %r10 150 | andq %r8, %r12 151 | shrq $14, %r8 152 | jmp L_0x089 153 | 154 | L_0x1e3: 155 | addq $1, %rdx 156 | cmpq %rcx, %rdx 157 | ja L_0x2b4 158 | movq %r8, %r10 159 | andq $15, %r10 160 | jmp L_0x218 161 | 162 | L_0x1f9: 163 | addq $2, %rdx 164 | cmpq %rcx, %rdx 165 | ja L_0x2b4 166 | movq %r8, %r10 167 | shrq $8, %r10 168 | andq $255, %r10 169 | addq $16, %r10 170 | 171 | L_0x218: 172 | movq %rax, %r8 173 | subq %r12, %r8 174 | leaq (%rax,%r10), %r11 175 | cmpq %rsi, %r11 176 | jae L_0x102 177 | cmpq $8, %r12 178 | jae L_0x0ae 179 | jmp L_0x102 180 | 181 | L_0x23a: 182 | andq $15, %r8 183 | leaq 1(%rdx,%r8), %rdx 184 | jmp L_0x259 185 | 186 | L_0x245: 187 | shrq $8, %r8 188 | andq $255, %r8 189 | addq $16, %r8 190 | leaq 2(%rdx,%r8), %rdx 191 | 192 | L_0x259: 193 | cmpq %rcx, %rdx 194 | ja L_0x2b4 195 | leaq (%rax,%r8), %r11 196 | negq %r8 197 | cmpq %rsi, %r11 198 | ja L_0x28d 199 | leaq (%rdi,%r11), %r11 200 | 201 | L_0x26e: 202 | movq (%rdx,%r8), %r9 203 | movq %r9, (%r11,%r8) 204 | addq $8, %r8 205 | jae L_0x26e 206 | movq %r11, %rax 207 | subq %rdi, %rax 208 | movzbq (%rdx), %r9 209 | movq (%rdx), %r8 210 | jmpq *(%rbx,%r9,8) 211 | 212 | L_0x28d: 213 | leaq 8(%rsi), %r11 214 | 215 | L_0x291: 216 | movzbq (%rdx,%r8), %r9 217 | movb %r9b, (%rdi,%rax) 218 | addq $1, %rax 219 | cmpq %rax, %r11 220 | je L_0x2b7 221 | addq $1, %r8 222 | jne L_0x291 223 | movzbq (%rdx), %r9 224 | movq (%rdx), %r8 225 | jmpq *(%rbx,%r9,8) 226 | 227 | L_0x2b4: 228 | xorq %rax, %rax 229 | 230 | L_0x2b7: 231 | popq %r12 232 | popq %rbx 233 | popq %rbp 234 | ret 235 | 236 | .data 237 | .align 8 238 | Lzvn_decode.opcode_table: 239 | .quad L_0x056 240 | .quad L_0x056 241 | .quad L_0x056 242 | .quad L_0x056 243 | .quad L_0x056 244 | .quad L_0x056 245 | .quad L_0x2b7 246 | .quad L_0x15e 247 | .quad L_0x056 248 | .quad L_0x056 249 | .quad L_0x056 250 | .quad L_0x056 251 | .quad L_0x056 252 | .quad L_0x056 253 | .quad L_0x037 254 | .quad L_0x15e 255 | .quad L_0x056 256 | .quad L_0x056 257 | .quad L_0x056 258 | .quad L_0x056 259 | .quad L_0x056 260 | .quad L_0x056 261 | .quad L_0x037 262 | .quad L_0x15e 263 | .quad L_0x056 264 | .quad L_0x056 265 | .quad L_0x056 266 | .quad L_0x056 267 | .quad L_0x056 268 | .quad L_0x056 269 | .quad L_0x2b4 270 | .quad L_0x15e 271 | .quad L_0x056 272 | .quad L_0x056 273 | .quad L_0x056 274 | .quad L_0x056 275 | .quad L_0x056 276 | .quad L_0x056 277 | .quad L_0x2b4 278 | .quad L_0x15e 279 | .quad L_0x056 280 | .quad L_0x056 281 | .quad L_0x056 282 | .quad L_0x056 283 | .quad L_0x056 284 | .quad L_0x056 285 | .quad L_0x2b4 286 | .quad L_0x15e 287 | .quad L_0x056 288 | .quad L_0x056 289 | .quad L_0x056 290 | .quad L_0x056 291 | .quad L_0x056 292 | .quad L_0x056 293 | .quad L_0x2b4 294 | .quad L_0x15e 295 | .quad L_0x056 296 | .quad L_0x056 297 | .quad L_0x056 298 | .quad L_0x056 299 | .quad L_0x056 300 | .quad L_0x056 301 | .quad L_0x2b4 302 | .quad L_0x15e 303 | .quad L_0x056 304 | .quad L_0x056 305 | .quad L_0x056 306 | .quad L_0x056 307 | .quad L_0x056 308 | .quad L_0x056 309 | .quad L_0x131 310 | .quad L_0x15e 311 | .quad L_0x056 312 | .quad L_0x056 313 | .quad L_0x056 314 | .quad L_0x056 315 | .quad L_0x056 316 | .quad L_0x056 317 | .quad L_0x131 318 | .quad L_0x15e 319 | .quad L_0x056 320 | .quad L_0x056 321 | .quad L_0x056 322 | .quad L_0x056 323 | .quad L_0x056 324 | .quad L_0x056 325 | .quad L_0x131 326 | .quad L_0x15e 327 | .quad L_0x056 328 | .quad L_0x056 329 | .quad L_0x056 330 | .quad L_0x056 331 | .quad L_0x056 332 | .quad L_0x056 333 | .quad L_0x131 334 | .quad L_0x15e 335 | .quad L_0x056 336 | .quad L_0x056 337 | .quad L_0x056 338 | .quad L_0x056 339 | .quad L_0x056 340 | .quad L_0x056 341 | .quad L_0x131 342 | .quad L_0x15e 343 | .quad L_0x056 344 | .quad L_0x056 345 | .quad L_0x056 346 | .quad L_0x056 347 | .quad L_0x056 348 | .quad L_0x056 349 | .quad L_0x131 350 | .quad L_0x15e 351 | .quad L_0x2b4 352 | .quad L_0x2b4 353 | .quad L_0x2b4 354 | .quad L_0x2b4 355 | .quad L_0x2b4 356 | .quad L_0x2b4 357 | .quad L_0x2b4 358 | .quad L_0x2b4 359 | .quad L_0x2b4 360 | .quad L_0x2b4 361 | .quad L_0x2b4 362 | .quad L_0x2b4 363 | .quad L_0x2b4 364 | .quad L_0x2b4 365 | .quad L_0x2b4 366 | .quad L_0x2b4 367 | .quad L_0x056 368 | .quad L_0x056 369 | .quad L_0x056 370 | .quad L_0x056 371 | .quad L_0x056 372 | .quad L_0x056 373 | .quad L_0x131 374 | .quad L_0x15e 375 | .quad L_0x056 376 | .quad L_0x056 377 | .quad L_0x056 378 | .quad L_0x056 379 | .quad L_0x056 380 | .quad L_0x056 381 | .quad L_0x131 382 | .quad L_0x15e 383 | .quad L_0x056 384 | .quad L_0x056 385 | .quad L_0x056 386 | .quad L_0x056 387 | .quad L_0x056 388 | .quad L_0x056 389 | .quad L_0x131 390 | .quad L_0x15e 391 | .quad L_0x056 392 | .quad L_0x056 393 | .quad L_0x056 394 | .quad L_0x056 395 | .quad L_0x056 396 | .quad L_0x056 397 | .quad L_0x131 398 | .quad L_0x15e 399 | .quad L_0x199 400 | .quad L_0x199 401 | .quad L_0x199 402 | .quad L_0x199 403 | .quad L_0x199 404 | .quad L_0x199 405 | .quad L_0x199 406 | .quad L_0x199 407 | .quad L_0x199 408 | .quad L_0x199 409 | .quad L_0x199 410 | .quad L_0x199 411 | .quad L_0x199 412 | .quad L_0x199 413 | .quad L_0x199 414 | .quad L_0x199 415 | .quad L_0x199 416 | .quad L_0x199 417 | .quad L_0x199 418 | .quad L_0x199 419 | .quad L_0x199 420 | .quad L_0x199 421 | .quad L_0x199 422 | .quad L_0x199 423 | .quad L_0x199 424 | .quad L_0x199 425 | .quad L_0x199 426 | .quad L_0x199 427 | .quad L_0x199 428 | .quad L_0x199 429 | .quad L_0x199 430 | .quad L_0x199 431 | .quad L_0x056 432 | .quad L_0x056 433 | .quad L_0x056 434 | .quad L_0x056 435 | .quad L_0x056 436 | .quad L_0x056 437 | .quad L_0x131 438 | .quad L_0x15e 439 | .quad L_0x056 440 | .quad L_0x056 441 | .quad L_0x056 442 | .quad L_0x056 443 | .quad L_0x056 444 | .quad L_0x056 445 | .quad L_0x131 446 | .quad L_0x15e 447 | .quad L_0x2b4 448 | .quad L_0x2b4 449 | .quad L_0x2b4 450 | .quad L_0x2b4 451 | .quad L_0x2b4 452 | .quad L_0x2b4 453 | .quad L_0x2b4 454 | .quad L_0x2b4 455 | .quad L_0x2b4 456 | .quad L_0x2b4 457 | .quad L_0x2b4 458 | .quad L_0x2b4 459 | .quad L_0x2b4 460 | .quad L_0x2b4 461 | .quad L_0x2b4 462 | .quad L_0x2b4 463 | .quad L_0x245 464 | .quad L_0x23a 465 | .quad L_0x23a 466 | .quad L_0x23a 467 | .quad L_0x23a 468 | .quad L_0x23a 469 | .quad L_0x23a 470 | .quad L_0x23a 471 | .quad L_0x23a 472 | .quad L_0x23a 473 | .quad L_0x23a 474 | .quad L_0x23a 475 | .quad L_0x23a 476 | .quad L_0x23a 477 | .quad L_0x23a 478 | .quad L_0x23a 479 | .quad L_0x1f9 480 | .quad L_0x1e3 481 | .quad L_0x1e3 482 | .quad L_0x1e3 483 | .quad L_0x1e3 484 | .quad L_0x1e3 485 | .quad L_0x1e3 486 | .quad L_0x1e3 487 | .quad L_0x1e3 488 | .quad L_0x1e3 489 | .quad L_0x1e3 490 | .quad L_0x1e3 491 | .quad L_0x1e3 492 | .quad L_0x1e3 493 | .quad L_0x1e3 494 | .quad L_0x1e3 495 | -------------------------------------------------------------------------------- /lzvn_encode.s: -------------------------------------------------------------------------------- 1 | .text 2 | 3 | .globl _lzvn_encode 4 | .globl _lzvn_encode_work_size 5 | 6 | _lzvn_encode: 7 | pushq %rbp 8 | movq %rsp, %rbp 9 | pushq %rbx 10 | pushq %rax 11 | movq %r8, %rax 12 | movq %rcx, %rbx 13 | movq $0x0, -0x10(%rbp) 14 | leaq -0x10(%rbp), %r8 15 | movq %rax, %r9 16 | callq _lzvn_encode_partial 17 | xorl %ecx, %ecx 18 | cmpq %rbx, -0x10(%rbp) 19 | cmoveq %rax, %rcx 20 | movq %rcx, %rax 21 | addq $0x8, %rsp 22 | popq %rbx 23 | popq %rbp 24 | retq 25 | 26 | _lzvn_encode_partial: 27 | pushq %rbp 28 | movq %rsp, %rbp 29 | pushq %r15 30 | pushq %r14 31 | pushq %r13 32 | pushq %r12 33 | pushq %rbx 34 | subq $0xc8, %rsp 35 | movq %r9, -0xc0(%rbp) 36 | movq %r8, -0xe8(%rbp) 37 | movq %rdx, %r12 38 | movq %r12, -0xb0(%rbp) 39 | movq %rdi, -0xd8(%rbp) 40 | xorl %edx, %edx 41 | cmpq $0x8, %rsi 42 | jb Lzvn_807d1 43 | cmpq $0x8, %rcx 44 | movl $0x0, %ebx 45 | jb Lzvn_8092c 46 | movl $0xffffffff, %eax 47 | addq $-0x8, %rsi 48 | movl (%r12), %r10d 49 | movd %r10d, %xmm0 50 | pshufd $0x0, %xmm0, %xmm0 51 | pxor %xmm1, %xmm1 52 | xorl %edx, %edx 53 | 54 | Lzvn_7fa2a: 55 | movdqa %xmm1, (%r9,%rdx) 56 | movdqa %xmm0, 0x10(%r9,%rdx) 57 | addq $0x20, %rdx 58 | cmpq $0x80000, %rdx 59 | jne Lzvn_7fa2a 60 | cmpq %rax, %rcx 61 | cmovaq %rax, %rcx 62 | movq %rcx, -0x68(%rbp) 63 | leaq (%rdi,%rsi), %r11 64 | movq %r11, -0xc8(%rbp) 65 | xorl %eax, %eax 66 | cmpq $0x9, %rcx 67 | jb Lzvn_807d8 68 | testq %rsi, %rsi 69 | movq %rdi, %r8 70 | jle Lzvn_807db 71 | movq %r11, %r14 72 | movq %rcx, -0x68(%rbp) 73 | leaq -0x1(%r12), %rax 74 | movq %rax, -0xe0(%rbp) 75 | xorl %eax, %eax 76 | movq %rax, -0x90(%rbp) 77 | movq %rdi, -0x78(%rbp) 78 | xorl %r13d, %r13d 79 | xorl %esi, %esi 80 | xorl %eax, %eax 81 | movq %rax, -0x50(%rbp) 82 | xorl %eax, %eax 83 | movq %rax, -0xb8(%rbp) 84 | movq %rdi, -0xd0(%rbp) 85 | movq %rdi, -0xd8(%rbp) 86 | xorl %edi, %edi 87 | xorl %r8d, %r8d 88 | xorl %r11d, %r11d 89 | xorl %edx, %edx 90 | xorl %ecx, %ecx 91 | movl %r10d, %eax 92 | jmp Lzvn_7faed 93 | 94 | Lzvn_7fac5: 95 | movq %r11, %r14 96 | incq %rsi 97 | movl (%r12,%rsi), %eax 98 | decq -0x90(%rbp) 99 | movq %rdi, %rcx 100 | movq %rcx, -0x50(%rbp) 101 | movq %rdx, %rdi 102 | movq -0x40(%rbp), %r8 103 | movq %rbx, %r11 104 | movq %r10, %rdx 105 | movq %r15, %rcx 106 | 107 | Lzvn_7faed: 108 | movl %eax, -0x84(%rbp) 109 | movl %eax, %ebx 110 | andl $0xffffff, %eax 111 | imull $0x1041, %eax, %eax 112 | shrl $0xc, %eax 113 | andl $0x3fff, %eax 114 | shlq $0x5, %rax 115 | movdqa (%r9,%rax), %xmm0 116 | movdqa 0x10(%r9,%rax), %xmm1 117 | pshufd $-0x70, %xmm1, %xmm3 118 | pshufd $-0x70, %xmm0, %xmm4 119 | movd %esi, %xmm2 120 | movss %xmm2, %xmm4 121 | movd %ebx, %xmm2 122 | movss %xmm2, %xmm3 123 | movaps %xmm3, 0x10(%r9,%rax) 124 | movaps %xmm4, (%r9,%rax) 125 | testq %rsi, %rsi 126 | je Lzvn_7fc0f 127 | cmpq %r13, %rsi 128 | jb Lzvn_7fc0f 129 | movq %rdi, -0xa8(%rbp) 130 | movq %rcx, -0x80(%rbp) 131 | movq %r11, -0xa0(%rbp) 132 | movq -0x68(%rbp), %r10 133 | pshufd $0x0, %xmm2, %xmm2 134 | pxor %xmm2, %xmm1 135 | movd %xmm1, %ecx 136 | testl %ecx, %ecx 137 | movl $0x4, %eax 138 | je Lzvn_7fbba 139 | movq %rdx, -0x70(%rbp) 140 | movl %ecx, %eax 141 | bsfq %rax, %rax 142 | cmpq $0x18, %rax 143 | movl $0x0, %ecx 144 | movq %rcx, -0x48(%rbp) 145 | movl $0x0, %ecx 146 | movq %rcx, -0x60(%rbp) 147 | movl $0x0, %edi 148 | movl $0x0, %r11d 149 | movl $0x0, %ecx 150 | jb Lzvn_7fd23 151 | shrq $0x3, %rax 152 | movq -0x70(%rbp), %rdx 153 | 154 | Lzvn_7fbba: 155 | movq %rdx, -0x70(%rbp) 156 | movd %xmm0, %ecx 157 | movl %ecx, %r14d 158 | movq %rsi, %r15 159 | subq %r14, %r15 160 | cmpq $0xffff, %r15 161 | movl $0x0, %ecx 162 | movq %rcx, -0x48(%rbp) 163 | movl $0x0, %ecx 164 | movq %rcx, -0x60(%rbp) 165 | movl $0x0, %edi 166 | movl $0x0, %r11d 167 | movl $0x0, %ecx 168 | ja Lzvn_7fd23 169 | leaq (%rax,%rsi), %r11 170 | cmpq $0x4, %rax 171 | jne Lzvn_7fc6c 172 | movq %r8, -0x40(%rbp) 173 | leaq 0x4(%rax,%rsi), %rax 174 | jmp Lzvn_7fc37 175 | 176 | Lzvn_7fc0f: 177 | movq %rcx, %r15 178 | movq %rdx, %r10 179 | movq %r11, %rbx 180 | movq %r8, -0x40(%rbp) 181 | movq %rdi, %rdx 182 | movq -0x50(%rbp), %rcx 183 | movq %rcx, %rdi 184 | movq -0x68(%rbp), %rcx 185 | movq %r14, %r11 186 | jmp Lzvn_807a7 187 | 188 | Lzvn_7fc32: 189 | leaq 0x4(%rdx,%rax), %rax 190 | 191 | Lzvn_7fc37: 192 | cmpq %r10, %rax 193 | movq %r11, %rax 194 | jae Lzvn_7fc70 195 | movq %rax, %rdx 196 | subq %r15, %rdx 197 | movl (%r12,%rax), %ebx 198 | movl (%r12,%rdx), %edi 199 | cmpl %edi, %ebx 200 | movl $0x4, %edx 201 | je Lzvn_7fc60 202 | xorl %ebx, %edi 203 | bsfq %rdi, %rdx 204 | shrq $0x3, %rdx 205 | 206 | Lzvn_7fc60: 207 | leaq (%rdx,%rax), %r11 208 | cmpq $0x4, %rdx 209 | je Lzvn_7fc32 210 | jmp Lzvn_7fc70 211 | 212 | Lzvn_7fc6c: 213 | movq %r8, -0x40(%rbp) 214 | 215 | Lzvn_7fc70: 216 | movq -0xe0(%rbp), %rax 217 | leaq (%rax,%rsi), %rdx 218 | leaq (%rax,%r14), %rdi 219 | xorl %ebx, %ebx 220 | 221 | Lzvn_7fc81: 222 | movq %rbx, %rax 223 | leaq (%rsi,%rax), %rcx 224 | movq %r14, %rbx 225 | addq %rax, %rbx 226 | je Lzvn_7fcb3 227 | cmpq %r13, %rcx 228 | jbe Lzvn_7fcb3 229 | movq %rcx, %r8 230 | movq %rsi, %rcx 231 | movzbl (%rdi,%rax), %esi 232 | movzbl (%rdx,%rax), %r9d 233 | leaq -0x1(%rax), %rbx 234 | cmpl %esi, %r9d 235 | movq %rcx, %rsi 236 | movq %r8, %rcx 237 | je Lzvn_7fc81 238 | 239 | Lzvn_7fcb3: 240 | cmpq $0x5ff, %r15 241 | seta %dl 242 | movzbl %dl, %r8d 243 | movq %rsi, %r9 244 | leaq 0x2(%r8,%r9), %rsi 245 | subq %r11, %rsi 246 | addq %rax, %rsi 247 | setne %sil 248 | cmpq $0x1, %r11 249 | seta %bl 250 | movq -0x90(%rbp), %rdi 251 | leaq (%r11,%rdi), %rdi 252 | movq $-0x2, %rdx 253 | subq %r8, %rdx 254 | addq %rdi, %rdx 255 | subq %rax, %rdx 256 | subq %rax, %rdi 257 | orb %sil, %bl 258 | movq %r9, %rsi 259 | movl $0x0, %eax 260 | cmoveq %rax, %rdx 261 | movq %rdx, -0x48(%rbp) 262 | cmoveq %rax, %r15 263 | cmoveq %rax, %rdi 264 | cmoveq %rax, %r11 265 | cmoveq %rax, %rcx 266 | movq %r15, -0x60(%rbp) 267 | movq -0x40(%rbp), %r8 268 | 269 | Lzvn_7fd23: 270 | movq %rdi, -0x58(%rbp) 271 | movq %rcx, -0x40(%rbp) 272 | pshufd $0x1, %xmm1, %xmm2 273 | movd %xmm2, %eax 274 | testl %eax, %eax 275 | movl $0x4, %edx 276 | je Lzvn_7fd4d 277 | movl %eax, %eax 278 | bsfq %rax, %rdx 279 | cmpq $0x18, %rdx 280 | jb Lzvn_7fd67 281 | shrq $0x3, %rdx 282 | 283 | Lzvn_7fd4d: 284 | pshufd $0x1, %xmm0, %xmm2 285 | movd %xmm2, %eax 286 | movl %eax, %eax 287 | movq %rsi, %rcx 288 | subq %rax, %rcx 289 | cmpq $0xffff, %rcx 290 | jbe Lzvn_7fd72 291 | 292 | Lzvn_7fd67: 293 | movq %rsi, %r15 294 | movq %r10, %r9 295 | jmp Lzvn_7fe35 296 | 297 | Lzvn_7fd72: 298 | movq %rsi, %rdi 299 | leaq (%rdx,%rdi), %rsi 300 | cmpq $0x4, %rdx 301 | jne Lzvn_7fdc3 302 | leaq 0x4(%rdx,%rdi), %rdx 303 | movq %rdi, %r15 304 | jmp Lzvn_7fd8e 305 | 306 | Lzvn_7fd89: 307 | leaq 0x4(%rdi,%rdx), %rdx 308 | 309 | Lzvn_7fd8e: 310 | cmpq %r10, %rdx 311 | movq %rsi, %rdx 312 | jae Lzvn_7fdc6 313 | movq %rdx, %rsi 314 | subq %rcx, %rsi 315 | movl (%r12,%rdx), %ebx 316 | movl (%r12,%rsi), %esi 317 | cmpl %esi, %ebx 318 | movl $0x4, %edi 319 | je Lzvn_7fdb7 320 | xorl %ebx, %esi 321 | bsfq %rsi, %rdi 322 | shrq $0x3, %rdi 323 | 324 | Lzvn_7fdb7: 325 | leaq (%rdi,%rdx), %rsi 326 | cmpq $0x4, %rdi 327 | je Lzvn_7fd89 328 | jmp Lzvn_7fdc6 329 | 330 | Lzvn_7fdc3: 331 | movq %rdi, %r15 332 | 333 | Lzvn_7fdc6: 334 | movq %r10, %r9 335 | movq %r15, %rdx 336 | 337 | Lzvn_7fdcc: 338 | movq %rdx, %r14 339 | testq %rax, %rax 340 | je Lzvn_7fdf0 341 | cmpq %r13, %r14 342 | jbe Lzvn_7fdf0 343 | leaq -0x1(%r14), %rdx 344 | movzbl -0x1(%r12,%rax), %edi 345 | decq %rax 346 | movzbl -0x1(%r12,%r14), %ebx 347 | cmpl %edi, %ebx 348 | je Lzvn_7fdcc 349 | 350 | Lzvn_7fdf0: 351 | movq %rsi, %rax 352 | subq %r14, %rax 353 | cmpq $0x5ff, %rcx 354 | seta %dl 355 | movzbl %dl, %edi 356 | orq $0x2, %rdi 357 | movq %rax, %rdx 358 | subq %rdi, %rdx 359 | cmpq -0x48(%rbp), %rdx 360 | ja Lzvn_7fe22 361 | cmpq -0x48(%rbp), %rdx 362 | jne Lzvn_7fe35 363 | leaq 0x1(%r11), %rdi 364 | cmpq %rdi, %rsi 365 | jbe Lzvn_7fe35 366 | 367 | Lzvn_7fe22: 368 | movq %rdx, -0x48(%rbp) 369 | movq %rcx, -0x60(%rbp) 370 | movq %rax, -0x58(%rbp) 371 | movq %rsi, %r11 372 | movq %r14, -0x40(%rbp) 373 | 374 | Lzvn_7fe35: 375 | movdqa %xmm1, %xmm2 376 | punpckhdq %xmm2, %xmm2 377 | movd %xmm2, %eax 378 | testl %eax, %eax 379 | movl $0x4, %edx 380 | movq %r9, %r14 381 | je Lzvn_7fe5d 382 | movl %eax, %eax 383 | bsfq %rax, %rdx 384 | cmpq $0x18, %rdx 385 | jb Lzvn_7fe7a 386 | shrq $0x3, %rdx 387 | 388 | Lzvn_7fe5d: 389 | movdqa %xmm0, %xmm2 390 | punpckhdq %xmm2, %xmm2 391 | movd %xmm2, %eax 392 | movl %eax, %eax 393 | movq %r15, %r9 394 | subq %rax, %r9 395 | cmpq $0xffff, %r9 396 | jbe Lzvn_7fe86 397 | 398 | Lzvn_7fe7a: 399 | movq %r15, %r10 400 | movq -0x70(%rbp), %r15 401 | jmp Lzvn_7ff47 402 | 403 | Lzvn_7fe86: 404 | leaq (%rdx,%r15), %rsi 405 | cmpq $0x4, %rdx 406 | jne Lzvn_7fed4 407 | leaq 0x4(%rdx,%r15), %rdx 408 | movq %r15, %r10 409 | jmp Lzvn_7fe9f 410 | 411 | Lzvn_7fe9a: 412 | leaq 0x4(%rdi,%rdx), %rdx 413 | 414 | Lzvn_7fe9f: 415 | cmpq %r14, %rdx 416 | movq %rsi, %rdx 417 | jae Lzvn_7fed7 418 | movq %rdx, %rsi 419 | subq %r9, %rsi 420 | movl (%r12,%rdx), %ebx 421 | movl (%r12,%rsi), %esi 422 | cmpl %esi, %ebx 423 | movl $0x4, %edi 424 | je Lzvn_7fec8 425 | xorl %ebx, %esi 426 | bsfq %rsi, %rdi 427 | shrq $0x3, %rdi 428 | 429 | Lzvn_7fec8: 430 | leaq (%rdi,%rdx), %rsi 431 | cmpq $0x4, %rdi 432 | je Lzvn_7fe9a 433 | jmp Lzvn_7fed7 434 | 435 | Lzvn_7fed4: 436 | movq %r15, %r10 437 | 438 | Lzvn_7fed7: 439 | movq %r10, %rdi 440 | movq -0x70(%rbp), %r15 441 | 442 | Lzvn_7fede: 443 | movq %rdi, %rdx 444 | testq %rax, %rax 445 | je Lzvn_7ff02 446 | cmpq %r13, %rdx 447 | jbe Lzvn_7ff02 448 | leaq -0x1(%rdx), %rdi 449 | movzbl -0x1(%r12,%rax), %ebx 450 | decq %rax 451 | movzbl -0x1(%r12,%rdx), %ecx 452 | cmpl %ebx, %ecx 453 | je Lzvn_7fede 454 | 455 | Lzvn_7ff02: 456 | movq %rsi, %rax 457 | subq %rdx, %rax 458 | cmpq $0x5ff, %r9 459 | seta %cl 460 | movzbl %cl, %ecx 461 | orq $0x2, %rcx 462 | movq %rax, %rdi 463 | subq %rcx, %rdi 464 | cmpq -0x48(%rbp), %rdi 465 | ja Lzvn_7ff34 466 | cmpq -0x48(%rbp), %rdi 467 | jne Lzvn_7ff47 468 | leaq 0x1(%r11), %rcx 469 | cmpq %rcx, %rsi 470 | jbe Lzvn_7ff47 471 | 472 | Lzvn_7ff34: 473 | movq %rdi, -0x48(%rbp) 474 | movq %r9, -0x60(%rbp) 475 | movq %rax, -0x58(%rbp) 476 | movq %rsi, %r11 477 | movq %rdx, -0x40(%rbp) 478 | 479 | Lzvn_7ff47: 480 | movq %r11, -0x98(%rbp) 481 | pshufd $0x3, %xmm1, %xmm1 482 | movd %xmm1, %eax 483 | testl %eax, %eax 484 | movl $0x4, %edx 485 | je Lzvn_7ff70 486 | movl %eax, %eax 487 | bsfq %rax, %rdx 488 | cmpq $0x18, %rdx 489 | jb Lzvn_7ff8a 490 | shrq $0x3, %rdx 491 | 492 | Lzvn_7ff70: 493 | pshufd $0x3, %xmm0, %xmm0 494 | movd %xmm0, %eax 495 | movl %eax, %eax 496 | movq %r10, %r9 497 | subq %rax, %r9 498 | cmpq $0xffff, %r9 499 | jbe Lzvn_7ff93 500 | 501 | Lzvn_7ff8a: 502 | movq %r10, -0x38(%rbp) 503 | jmp Lzvn_8005e 504 | 505 | Lzvn_7ff93: 506 | leaq (%rdx,%r10), %rsi 507 | cmpq $0x4, %rdx 508 | jne Lzvn_7ffe2 509 | leaq 0x4(%rdx,%r10), %rdx 510 | movq %r10, -0x38(%rbp) 511 | jmp Lzvn_7ffad 512 | 513 | Lzvn_7ffa8: 514 | leaq 0x4(%rdi,%rdx), %rdx 515 | 516 | Lzvn_7ffad: 517 | cmpq %r14, %rdx 518 | movq %rsi, %rdx 519 | jae Lzvn_7ffe6 520 | movq %rdx, %rsi 521 | subq %r9, %rsi 522 | movl (%r12,%rdx), %ebx 523 | movl (%r12,%rsi), %esi 524 | cmpl %esi, %ebx 525 | movl $0x4, %edi 526 | je Lzvn_7ffd6 527 | xorl %ebx, %esi 528 | bsfq %rsi, %rdi 529 | shrq $0x3, %rdi 530 | 531 | Lzvn_7ffd6: 532 | leaq (%rdi,%rdx), %rsi 533 | cmpq $0x4, %rdi 534 | je Lzvn_7ffa8 535 | jmp Lzvn_7ffe6 536 | 537 | Lzvn_7ffe2: 538 | movq %r10, -0x38(%rbp) 539 | 540 | Lzvn_7ffe6: 541 | movq -0x38(%rbp), %rdi 542 | 543 | Lzvn_7ffea: 544 | movq %rdi, %rdx 545 | testq %rax, %rax 546 | je Lzvn_8000e 547 | cmpq %r13, %rdx 548 | jbe Lzvn_8000e 549 | leaq -0x1(%rdx), %rdi 550 | movzbl -0x1(%r12,%rax), %ebx 551 | decq %rax 552 | movzbl -0x1(%r12,%rdx), %ecx 553 | cmpl %ebx, %ecx 554 | je Lzvn_7ffea 555 | 556 | Lzvn_8000e: 557 | movq %rsi, %rax 558 | subq %rdx, %rax 559 | cmpq $0x5ff, %r9 560 | seta %cl 561 | movzbl %cl, %ecx 562 | orq $0x2, %rcx 563 | movq %rax, %rdi 564 | subq %rcx, %rdi 565 | cmpq -0x48(%rbp), %rdi 566 | ja Lzvn_80047 567 | cmpq -0x48(%rbp), %rdi 568 | jne Lzvn_8005e 569 | movq -0x98(%rbp), %rcx 570 | leaq 0x1(%rcx), %rcx 571 | cmpq %rcx, %rsi 572 | jbe Lzvn_8005e 573 | 574 | Lzvn_80047: 575 | movq %rdi, -0x48(%rbp) 576 | movq %r9, -0x60(%rbp) 577 | movq %rax, -0x58(%rbp) 578 | movq %rsi, -0x98(%rbp) 579 | movq %rdx, -0x40(%rbp) 580 | 581 | Lzvn_8005e: 582 | movq %r14, %r11 583 | movq -0x50(%rbp), %rbx 584 | testq %rbx, %rbx 585 | je Lzvn_800bc 586 | movq -0x38(%rbp), %rcx 587 | movq %rcx, %r14 588 | subq %rbx, %r14 589 | movl (%r12,%r14), %edx 590 | movl -0x84(%rbp), %esi 591 | cmpl %edx, %esi 592 | movl $0x4, %eax 593 | movq -0x58(%rbp), %r10 594 | je Lzvn_8009e 595 | xorl %esi, %edx 596 | bsfq %rdx, %rax 597 | cmpl $0x18, %eax 598 | jb Lzvn_801a7 599 | shrq $0x3, %rax 600 | 601 | Lzvn_8009e: 602 | cmpq $0xffff, %rbx 603 | ja Lzvn_801a7 604 | leaq (%rax,%rcx), %rsi 605 | cmpq $0x4, %rax 606 | jne Lzvn_800fd 607 | leaq 0x4(%rax,%rcx), %rax 608 | jmp Lzvn_800ca 609 | 610 | Lzvn_800bc: 611 | movq -0x58(%rbp), %r10 612 | jmp Lzvn_801a7 613 | 614 | Lzvn_800c5: 615 | leaq 0x4(%rdx,%rax), %rax 616 | 617 | Lzvn_800ca: 618 | cmpq %r11, %rax 619 | movq %rsi, %rax 620 | jae Lzvn_800fd 621 | movq %rax, %rcx 622 | subq %rbx, %rcx 623 | movl (%r12,%rax), %edi 624 | movl (%r12,%rcx), %esi 625 | cmpl %esi, %edi 626 | movl $0x4, %edx 627 | je Lzvn_800f3 628 | xorl %edi, %esi 629 | bsfq %rsi, %rdx 630 | shrq $0x3, %rdx 631 | 632 | Lzvn_800f3: 633 | leaq (%rdx,%rax), %rsi 634 | cmpq $0x4, %rdx 635 | je Lzvn_800c5 636 | 637 | Lzvn_800fd: 638 | movq -0xe0(%rbp), %rax 639 | movq -0x38(%rbp), %rcx 640 | leaq (%rax,%rcx), %r9 641 | leaq (%rax,%r14), %rbx 642 | xorl %ecx, %ecx 643 | 644 | Lzvn_80112: 645 | movq %rcx, %rdx 646 | movq -0x38(%rbp), %rax 647 | leaq (%rax,%rdx), %rax 648 | movq %r14, %rcx 649 | addq %rdx, %rcx 650 | je Lzvn_8013c 651 | cmpq %r13, %rax 652 | jbe Lzvn_8013c 653 | movzbl (%rbx,%rdx), %edi 654 | movzbl (%r9,%rdx), %r15d 655 | leaq -0x1(%rdx), %rcx 656 | cmpl %edi, %r15d 657 | je Lzvn_80112 658 | 659 | Lzvn_8013c: 660 | movq -0x90(%rbp), %rcx 661 | leaq (%rcx,%rsi), %rcx 662 | subq %rdx, %rcx 663 | leaq -0x1(%rcx), %r14 664 | cmpq -0x48(%rbp), %r14 665 | movq -0x70(%rbp), %r15 666 | movq -0x50(%rbp), %rbx 667 | movq -0x58(%rbp), %rdi 668 | ja Lzvn_8018e 669 | movq %rdi, %r9 670 | movq -0x48(%rbp), %rdi 671 | leaq 0x1(%rdi), %rdi 672 | subq %rsi, %rdi 673 | addq -0x38(%rbp), %rdi 674 | addq %rdx, %rdi 675 | jne Lzvn_804a5 676 | movq -0x98(%rbp), %rdx 677 | leaq 0x1(%rdx), %rdx 678 | cmpq %rdx, %rsi 679 | movq %r9, %r10 680 | jbe Lzvn_801a7 681 | 682 | Lzvn_8018e: 683 | movq %r14, -0x48(%rbp) 684 | movq %rbx, %rdx 685 | movq %rdx, -0x60(%rbp) 686 | movq %rcx, %r10 687 | movq %rsi, -0x98(%rbp) 688 | movq %rax, -0x40(%rbp) 689 | 690 | Lzvn_801a7: 691 | testq %r10, %r10 692 | je Lzvn_80323 693 | testq %r15, %r15 694 | movq -0x38(%rbp), %rsi 695 | movq -0xa0(%rbp), %rax 696 | movq -0x80(%rbp), %rcx 697 | je Lzvn_8035f 698 | movq -0x40(%rbp), %rdx 699 | cmpq %rdx, %rax 700 | movq -0xc8(%rbp), %r11 701 | movq -0x98(%rbp), %rbx 702 | jbe Lzvn_80384 703 | movq -0xa8(%rbp), %rsi 704 | cmpq %rsi, -0x48(%rbp) 705 | cmovaq -0x60(%rbp), %rcx 706 | movq %rcx, -0x80(%rbp) 707 | cmovaq %r10, %r15 708 | cmovaq %rbx, %rax 709 | movq %rax, %r10 710 | cmovaq %rdx, %r8 711 | leaq (%r12,%r13), %rsi 712 | subq %r13, %r8 713 | cmpq $0x10, %r8 714 | movq -0xc0(%rbp), %r9 715 | movq -0x78(%rbp), %r13 716 | jb Lzvn_8027f 717 | 718 | Lzvn_8021e: 719 | cmpq $0x10f, %r8 720 | movl $0x10f, %eax 721 | cmovbq %r8, %rax 722 | leaq 0xa(%rax,%r13), %rcx 723 | cmpq %r11, %rcx 724 | jae Lzvn_80681 725 | movq %rax, %rcx 726 | shlq $0x8, %rcx 727 | addl $0xf0e0, %ecx 728 | movw %cx, (%r13) 729 | testq %rax, %rax 730 | je Lzvn_8026e 731 | leaq 0x2(%r13), %rcx 732 | xorl %edx, %edx 733 | 734 | Lzvn_80259: 735 | movq (%rsi,%rdx), %rdi 736 | movq %rdi, -0x30(%rbp) 737 | movq %rdi, (%rcx,%rdx) 738 | addq $0x8, %rdx 739 | cmpq %rax, %rdx 740 | jb Lzvn_80259 741 | 742 | Lzvn_8026e: 743 | subq %rax, %r8 744 | leaq 0x2(%rax,%r13), %r13 745 | addq %rax, %rsi 746 | cmpq $0xf, %r8 747 | ja Lzvn_8021e 748 | 749 | Lzvn_8027f: 750 | cmpq $0x4, %r8 751 | jb Lzvn_802cc 752 | leaq 0xa(%r8,%r13), %rax 753 | cmpq %r11, %rax 754 | movq %r11, %rbx 755 | jae Lzvn_80689 756 | leal 0xe0(%r8), %eax 757 | movb %al, (%r13) 758 | testq %r8, %r8 759 | je Lzvn_802c1 760 | leaq 0x1(%r13), %rax 761 | xorl %ecx, %ecx 762 | 763 | Lzvn_802ac: 764 | movq (%rsi,%rcx), %rdx 765 | movq %rdx, -0x30(%rbp) 766 | movq %rdx, (%rax,%rcx) 767 | addq $0x8, %rcx 768 | cmpq %r8, %rcx 769 | jb Lzvn_802ac 770 | 771 | Lzvn_802c1: 772 | leaq 0x1(%r8,%r13), %r13 773 | addq %r8, %rsi 774 | xorl %r8d, %r8d 775 | 776 | Lzvn_802cc: 777 | leaq (%r8,%r8), %rax 778 | movl $0xa, %edi 779 | subq %rax, %rdi 780 | cmpq %r15, %rdi 781 | cmovaeq %r15, %rdi 782 | leaq 0x8(%r13), %rax 783 | cmpq %r11, %rax 784 | movq %r11, %rbx 785 | jae Lzvn_80689 786 | movq %r15, %rcx 787 | subq %rdi, %rcx 788 | leaq -0x3(%rdi), %rax 789 | movl (%rsi), %ebx 790 | movq -0x80(%rbp), %rsi 791 | cmpq -0x50(%rbp), %rsi 792 | jne Lzvn_804ad 793 | testq %r8, %r8 794 | je Lzvn_805d8 795 | movq %r8, %rdx 796 | shlq $0x6, %rdx 797 | leaq 0x6(%rdx,%rax,8), %rdi 798 | jmp Lzvn_805df 799 | 800 | Lzvn_80323: 801 | movq -0x80(%rbp), %rax 802 | movq %r15, %r10 803 | movq %rax, %r15 804 | movq -0xa0(%rbp), %rax 805 | movq %r8, -0x40(%rbp) 806 | movq -0xa8(%rbp), %rdx 807 | movq %rbx, %rdi 808 | movq %r11, %rcx 809 | movq %rax, %rbx 810 | movq -0xc8(%rbp), %r11 811 | movq -0xc0(%rbp), %r9 812 | movq -0x38(%rbp), %rsi 813 | jmp Lzvn_807a7 814 | 815 | Lzvn_8035f: 816 | movq %rbx, %rdi 817 | movq -0xc8(%rbp), %r11 818 | movq -0xc0(%rbp), %r9 819 | movq -0x48(%rbp), %rdx 820 | movq -0x60(%rbp), %r15 821 | movq -0x98(%rbp), %rbx 822 | jmp Lzvn_807a3 823 | 824 | Lzvn_80384: 825 | movq %r10, -0x58(%rbp) 826 | leaq (%r12,%r13), %rsi 827 | subq %r13, %r8 828 | cmpq $0x10, %r8 829 | movq -0xc0(%rbp), %r9 830 | movq -0x78(%rbp), %r13 831 | jb Lzvn_80401 832 | 833 | Lzvn_803a0: 834 | cmpq $0x10f, %r8 835 | movl $0x10f, %eax 836 | cmovbq %r8, %rax 837 | leaq 0xa(%rax,%r13), %rcx 838 | cmpq %r11, %rcx 839 | jae Lzvn_80752 840 | movq %rax, %rcx 841 | shlq $0x8, %rcx 842 | addl $0xf0e0, %ecx 843 | movw %cx, (%r13) 844 | testq %rax, %rax 845 | je Lzvn_803f0 846 | leaq 0x2(%r13), %rcx 847 | xorl %edx, %edx 848 | 849 | Lzvn_803db: 850 | movq (%rsi,%rdx), %rdi 851 | movq %rdi, -0x30(%rbp) 852 | movq %rdi, (%rcx,%rdx) 853 | addq $0x8, %rdx 854 | cmpq %rax, %rdx 855 | jb Lzvn_803db 856 | 857 | Lzvn_803f0: 858 | subq %rax, %r8 859 | leaq 0x2(%rax,%r13), %r13 860 | addq %rax, %rsi 861 | cmpq $0xf, %r8 862 | ja Lzvn_803a0 863 | 864 | Lzvn_80401: 865 | cmpq $0x4, %r8 866 | jb Lzvn_8044e 867 | leaq 0xa(%r8,%r13), %rax 868 | cmpq %r11, %rax 869 | movq %r11, %rdx 870 | jae Lzvn_8075a 871 | leal 0xe0(%r8), %eax 872 | movb %al, (%r13) 873 | testq %r8, %r8 874 | je Lzvn_80443 875 | leaq 0x1(%r13), %rax 876 | xorl %ecx, %ecx 877 | 878 | Lzvn_8042e: 879 | movq (%rsi,%rcx), %rdx 880 | movq %rdx, -0x30(%rbp) 881 | movq %rdx, (%rax,%rcx) 882 | addq $0x8, %rcx 883 | cmpq %r8, %rcx 884 | jb Lzvn_8042e 885 | 886 | Lzvn_80443: 887 | leaq 0x1(%r8,%r13), %r13 888 | addq %r8, %rsi 889 | xorl %r8d, %r8d 890 | 891 | Lzvn_8044e: 892 | leaq (%r8,%r8), %rcx 893 | movl $0xa, %eax 894 | subq %rcx, %rax 895 | cmpq %r15, %rax 896 | cmovaeq %r15, %rax 897 | movq %r15, %rdi 898 | leaq 0x8(%r13), %rcx 899 | cmpq %r11, %rcx 900 | movq %r11, %rdx 901 | jae Lzvn_8075a 902 | movq %rdi, %rcx 903 | subq %rax, %rcx 904 | leaq -0x3(%rax), %rdx 905 | movl (%rsi), %r15d 906 | movq -0x80(%rbp), %rsi 907 | cmpq -0x50(%rbp), %rsi 908 | jne Lzvn_804e0 909 | testq %r8, %r8 910 | je Lzvn_805ee 911 | movq %r8, %rax 912 | shlq $0x6, %rax 913 | leaq 0x6(%rax,%rdx,8), %rax 914 | jmp Lzvn_805f4 915 | 916 | Lzvn_804a5: 917 | movq %r9, %r10 918 | jmp Lzvn_801a7 919 | 920 | Lzvn_804ad: 921 | cmpq $0x5ff, %rsi 922 | ja Lzvn_80517 923 | movq %r8, %rdx 924 | shlq $0x6, %rdx 925 | movl %esi, %edi 926 | shrl $0x8, %edi 927 | addl %edi, %edx 928 | shlq $0x3, %rax 929 | addl %edx, %eax 930 | movb %al, (%r13) 931 | movb %sil, 0x1(%r13) 932 | movl %ebx, 0x2(%r13) 933 | leaq 0x2(%r8,%r13), %rax 934 | jmp Lzvn_8062b 935 | 936 | Lzvn_804e0: 937 | cmpq $0x5ff, %rsi 938 | ja Lzvn_80579 939 | movq %r8, %rax 940 | shlq $0x6, %rax 941 | movl %esi, %edi 942 | shrl $0x8, %edi 943 | addl %edi, %eax 944 | shlq $0x3, %rdx 945 | addl %eax, %edx 946 | movb %dl, (%r13) 947 | movb %sil, 0x1(%r13) 948 | movl %r15d, 0x2(%r13) 949 | leaq 0x2(%r8,%r13), %rax 950 | jmp Lzvn_806fc 951 | 952 | Lzvn_80517: 953 | cmpq $0x3fff, %rsi 954 | movq %r15, %rdx 955 | ja Lzvn_80606 956 | cmpq %rdi, %rdx 957 | je Lzvn_80606 958 | cmpq $0x23, %rdx 959 | jae Lzvn_80606 960 | addl $-0x3, %edx 961 | movl %edx, %eax 962 | shrl $0x2, %eax 963 | leaq (,%r8,8), %rcx 964 | leal 0xa0(%rax,%rcx), %eax 965 | movb %al, (%r13) 966 | movq -0x80(%rbp), %rax 967 | leaq (,%rax,4), %rax 968 | andl $0x3, %edx 969 | orl %edx, %eax 970 | movw %ax, 0x1(%r13) 971 | movl %ebx, 0x3(%r13) 972 | leaq 0x3(%r8,%r13), %rbx 973 | jmp Lzvn_80689 974 | 975 | Lzvn_80579: 976 | cmpq $0x3fff, %rsi 977 | ja Lzvn_806d7 978 | cmpq %rax, %rdi 979 | je Lzvn_806d7 980 | cmpq $0x23, %rdi 981 | jae Lzvn_806d7 982 | addl $-0x3, %edi 983 | movl %edi, %eax 984 | shrl $0x2, %eax 985 | leaq (,%r8,8), %rcx 986 | leal 0xa0(%rax,%rcx), %eax 987 | movb %al, (%r13) 988 | movq -0x80(%rbp), %rax 989 | leaq (,%rax,4), %rax 990 | andl $0x3, %edi 991 | orl %edi, %eax 992 | movw %ax, 0x1(%r13) 993 | movl %r15d, 0x3(%r13) 994 | leaq 0x3(%r8,%r13), %rdx 995 | jmp Lzvn_8075a 996 | 997 | Lzvn_805d8: 998 | addq $0xf0, %rdi 999 | 1000 | Lzvn_805df: 1001 | movb %dil, (%r13) 1002 | movl %ebx, 0x1(%r13) 1003 | leaq 0x1(%r8,%r13), %rax 1004 | jmp Lzvn_8062b 1005 | 1006 | Lzvn_805ee: 1007 | addq $0xf0, %rax 1008 | 1009 | Lzvn_805f4: 1010 | movb %al, (%r13) 1011 | movl %r15d, 0x1(%r13) 1012 | leaq 0x1(%r8,%r13), %rax 1013 | jmp Lzvn_806fc 1014 | 1015 | Lzvn_80606: 1016 | movq %r8, %rdx 1017 | shlq $0x6, %rdx 1018 | shlq $0x3, %rax 1019 | leal 0x7(%rax,%rdx), %eax 1020 | movb %al, (%r13) 1021 | movq -0x80(%rbp), %rax 1022 | movw %ax, 0x1(%r13) 1023 | movl %ebx, 0x3(%r13) 1024 | leaq 0x3(%r8,%r13), %rax 1025 | 1026 | Lzvn_8062b: 1027 | cmpq $0x10, %rcx 1028 | jb Lzvn_80663 1029 | 1030 | Lzvn_80631: 1031 | leaq 0x2(%rax), %rdx 1032 | cmpq %r11, %rdx 1033 | jae Lzvn_80681 1034 | cmpq $0x10f, %rcx 1035 | movl $0x10f, %esi 1036 | cmovbq %rcx, %rsi 1037 | subq %rsi, %rcx 1038 | shlq $0x8, %rsi 1039 | addl $0xf0f0, %esi 1040 | movw %si, (%rax) 1041 | cmpq $0xf, %rcx 1042 | movq %rdx, %rax 1043 | ja Lzvn_80631 1044 | 1045 | Lzvn_80663: 1046 | testq %rcx, %rcx 1047 | je Lzvn_80686 1048 | leaq 0x1(%rax), %rsi 1049 | cmpq %r11, %rsi 1050 | movq %r11, %rbx 1051 | jae Lzvn_80689 1052 | addl $0xf0, %ecx 1053 | movb %cl, (%rax) 1054 | movq %rsi, %rbx 1055 | jmp Lzvn_80689 1056 | 1057 | Lzvn_80681: 1058 | movq %r11, %rbx 1059 | jmp Lzvn_80689 1060 | 1061 | Lzvn_80686: 1062 | movq %rax, %rbx 1063 | 1064 | Lzvn_80689: 1065 | cmpq %r11, %rbx 1066 | movq -0xd0(%rbp), %rax 1067 | cmovbq %rbx, %rax 1068 | movq %rax, -0xd0(%rbp) 1069 | movq -0xb8(%rbp), %rax 1070 | movq %r10, %r13 1071 | cmovbq %r13, %rax 1072 | movq %rax, -0xb8(%rbp) 1073 | xorl %r15d, %r15d 1074 | xorl %r10d, %r10d 1075 | xorl %eax, %eax 1076 | movq %rax, -0x40(%rbp) 1077 | xorl %edx, %edx 1078 | movq %rbx, -0x78(%rbp) 1079 | xorl %ebx, %ebx 1080 | movq -0x38(%rbp), %rsi 1081 | movq -0x80(%rbp), %rcx 1082 | movq %rcx, %rdi 1083 | jmp Lzvn_807a3 1084 | 1085 | Lzvn_806d7: 1086 | movq %r8, %rax 1087 | shlq $0x6, %rax 1088 | shlq $0x3, %rdx 1089 | leal 0x7(%rdx,%rax), %eax 1090 | movb %al, (%r13) 1091 | movq -0x80(%rbp), %rax 1092 | movw %ax, 0x1(%r13) 1093 | movl %r15d, 0x3(%r13) 1094 | leaq 0x3(%r8,%r13), %rax 1095 | 1096 | Lzvn_806fc: 1097 | cmpq $0x10, %rcx 1098 | jb Lzvn_80734 1099 | 1100 | Lzvn_80702: 1101 | leaq 0x2(%rax), %rdx 1102 | cmpq %r11, %rdx 1103 | jae Lzvn_80752 1104 | cmpq $0x10f, %rcx 1105 | movl $0x10f, %esi 1106 | cmovbq %rcx, %rsi 1107 | subq %rsi, %rcx 1108 | shlq $0x8, %rsi 1109 | addl $0xf0f0, %esi 1110 | movw %si, (%rax) 1111 | cmpq $0xf, %rcx 1112 | movq %rdx, %rax 1113 | ja Lzvn_80702 1114 | 1115 | Lzvn_80734: 1116 | testq %rcx, %rcx 1117 | je Lzvn_80757 1118 | leaq 0x1(%rax), %rsi 1119 | cmpq %r11, %rsi 1120 | movq %r11, %rdx 1121 | jae Lzvn_8075a 1122 | addl $0xf0, %ecx 1123 | movb %cl, (%rax) 1124 | movq %rsi, %rdx 1125 | jmp Lzvn_8075a 1126 | 1127 | Lzvn_80752: 1128 | movq %r11, %rdx 1129 | jmp Lzvn_8075a 1130 | 1131 | Lzvn_80757: 1132 | movq %rax, %rdx 1133 | 1134 | Lzvn_8075a: 1135 | cmpq %r11, %rdx 1136 | movq -0xd0(%rbp), %rax 1137 | cmovbq %rdx, %rax 1138 | movq %rax, -0xd0(%rbp) 1139 | movq -0xb8(%rbp), %rax 1140 | movq -0xa0(%rbp), %r13 1141 | cmovbq %r13, %rax 1142 | movq %rax, -0xb8(%rbp) 1143 | movq %rdx, -0x78(%rbp) 1144 | movq -0x38(%rbp), %rsi 1145 | movq -0x80(%rbp), %rcx 1146 | movq %rcx, %rdi 1147 | movq -0x58(%rbp), %r10 1148 | movq -0x48(%rbp), %rdx 1149 | movq -0x60(%rbp), %r15 1150 | 1151 | Lzvn_807a3: 1152 | movq -0x68(%rbp), %rcx 1153 | 1154 | Lzvn_807a7: 1155 | leaq 0x9(%rsi), %rax 1156 | cmpq %rcx, %rax 1157 | jae Lzvn_807ba 1158 | cmpq %r11, -0x78(%rbp) 1159 | jb Lzvn_7fac5 1160 | 1161 | Lzvn_807ba: 1162 | movq -0xb8(%rbp), %rax 1163 | movq -0xd0(%rbp), %r8 1164 | movq -0xd8(%rbp), %rdi 1165 | jmp Lzvn_807db 1166 | 1167 | Lzvn_807d1: 1168 | xorl %ebx, %ebx 1169 | jmp Lzvn_8092c 1170 | 1171 | Lzvn_807d8: 1172 | movq %rdi, %r8 1173 | 1174 | Lzvn_807db: 1175 | movq %rdi, -0xd8(%rbp) 1176 | cmpq %rax, %rcx 1177 | jbe Lzvn_80902 1178 | cmpq %r11, %r8 1179 | jae Lzvn_80902 1180 | movq %rax, %rdx 1181 | movq %r8, %rbx 1182 | 1183 | Lzvn_807fa: 1184 | movq %rbx, -0x40(%rbp) 1185 | movq %rdx, -0x38(%rbp) 1186 | movq %rax, -0xb8(%rbp) 1187 | movq %rcx, %rdx 1188 | subq %rax, %rdx 1189 | cmpq $0x10f, %rdx 1190 | movl $0x10f, %ecx 1191 | cmovaq %rcx, %rdx 1192 | movq %rdx, -0x48(%rbp) 1193 | leaq (%r12,%rax), %r15 1194 | cmpq $0x10, %rdx 1195 | movq %rdx, %r14 1196 | jb Lzvn_80897 1197 | 1198 | Lzvn_80830: 1199 | cmpq $0x10f, %r14 1200 | movl $0x10f, %r13d 1201 | cmovbq %r14, %r13 1202 | leaq 0xa(%r13,%r8), %rax 1203 | cmpq %r11, %rax 1204 | jae Lzvn_8090a 1205 | movq %r13, %rax 1206 | shlq $0x8, %rax 1207 | addl $0xf0e0, %eax 1208 | movw %ax, (%r8) 1209 | subq %r13, %r14 1210 | testq %r13, %r13 1211 | je Lzvn_80889 1212 | leaq 0x2(%r8), %rdi 1213 | movq %r15, %rsi 1214 | movq %r13, %rdx 1215 | movq %r11, %rbx 1216 | movq %r8, %r12 1217 | callq _memcpy 1218 | movq %r12, %r8 1219 | movq -0xb0(%rbp), %r12 1220 | movq %rbx, %r11 1221 | 1222 | Lzvn_80889: 1223 | leaq 0x2(%r13,%r8), %r8 1224 | addq %r13, %r15 1225 | cmpq $0xf, %r14 1226 | ja Lzvn_80830 1227 | 1228 | Lzvn_80897: 1229 | testq %r14, %r14 1230 | je Lzvn_808d0 1231 | leaq 0xa(%r14,%r8), %rax 1232 | cmpq %r11, %rax 1233 | jae Lzvn_8090a 1234 | leal 0xe0(%r14), %eax 1235 | leaq 0x1(%r8), %rdi 1236 | movb %al, (%r8) 1237 | movq %r15, %rsi 1238 | movq %r14, %rdx 1239 | movq %r11, %r15 1240 | movq %r8, %rbx 1241 | callq _memcpy 1242 | movq %rbx, %r8 1243 | movq %r15, %r11 1244 | leaq 0x1(%r14,%r8), %r8 1245 | 1246 | Lzvn_808d0: 1247 | movq -0xb8(%rbp), %rax 1248 | addq -0x48(%rbp), %rax 1249 | cmpq %r11, %r8 1250 | movq -0x40(%rbp), %rbx 1251 | cmovbq %r8, %rbx 1252 | movq -0x38(%rbp), %rdx 1253 | cmovbq %rax, %rdx 1254 | movq -0x68(%rbp), %rcx 1255 | cmpq %rax, %rcx 1256 | jbe Lzvn_80912 1257 | cmpq %r11, %r8 1258 | jb Lzvn_807fa 1259 | jmp Lzvn_80912 1260 | 1261 | Lzvn_80902: 1262 | movq %rax, %rdx 1263 | movq %r8, %rbx 1264 | jmp Lzvn_80912 1265 | 1266 | Lzvn_8090a: 1267 | movq -0x38(%rbp), %rdx 1268 | movq -0x40(%rbp), %rbx 1269 | 1270 | Lzvn_80912: 1271 | movq $0x6, -0x30(%rbp) 1272 | movq $0x6, (%rbx) 1273 | addq $0x8, %rbx 1274 | subq -0xd8(%rbp), %rbx 1275 | 1276 | Lzvn_8092c: 1277 | movq -0xe8(%rbp), %rax 1278 | movq %rdx, (%rax) 1279 | movq %rbx, %rax 1280 | addq $0xc8, %rsp 1281 | popq %rbx 1282 | popq %r12 1283 | popq %r13 1284 | popq %r14 1285 | popq %r15 1286 | popq %rbp 1287 | retq 1288 | 1289 | _lzvn_encode_work_size: 1290 | pushq %rbp 1291 | movq %rsp, %rbp 1292 | movl $0x80000, %eax 1293 | popq %rbp 1294 | retq 1295 | -------------------------------------------------------------------------------- /prelink.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2008 Apple Computer, Inc. All rights reserved. 3 | * 4 | * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5 | * 6 | * This file contains Original Code and/or Modifications of Original Code 7 | * as defined in and that are subject to the Apple Public Source License 8 | * Version 2.0 (the 'License'). You may not use this file except in 9 | * compliance with the License. The rights granted to you under the License 10 | * may not be used to create, or enable the creation or redistribution of, 11 | * unlawful or unlicensed copies of an Apple operating system, or to 12 | * circumvent, violate, or enable the circumvention or violation of, any 13 | * terms of an Apple operating system software license agreement. 14 | * 15 | * Please obtain a copy of the License at 16 | * http://www.opensource.apple.com/apsl/ and read it before using this file. 17 | * 18 | * The Original Code and all software distributed under the License are 19 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23 | * Please see the License for the specific language governing rights and 24 | * limitations under the License. 25 | * 26 | * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27 | */ 28 | 29 | #ifndef _PRELINK_H_ 30 | #define _PRELINK_H_ 31 | 32 | #define kPrelinkTextSegment "__PRELINK_TEXT" 33 | #define kPrelinkTextSection "__text" 34 | 35 | #define kPrelinkLinkStateSegment "__PRELINK_STATE" 36 | #define kPrelinkKernelLinkStateSection "__kernel" 37 | #define kPrelinkKextsLinkStateSection "__kexts" 38 | 39 | #define kPrelinkInfoSegment "__PRELINK_INFO" 40 | #define kPrelinkInfoSection "__info" 41 | 42 | #define kPrelinkBundlePathKey "_PrelinkBundlePath" 43 | #define kPrelinkExecutableRelativePathKey "_PrelinkExecutableRelativePath" 44 | #define kPrelinkExecutableLoadKey "_PrelinkExecutableLoadAddr" 45 | #define kPrelinkExecutableSourceKey "_PrelinkExecutableSourceAddr" 46 | #define kPrelinkExecutableSizeKey "_PrelinkExecutableSize" 47 | #define kPrelinkInfoDictionaryKey "_PrelinkInfoDictionary" 48 | #define kPrelinkInterfaceUUIDKey "_PrelinkInterfaceUUID" 49 | #define kPrelinkKmodInfoKey "_PrelinkKmodInfo" 50 | #define kPrelinkLinkStateKey "_PrelinkLinkState" 51 | #define kPrelinkLinkStateSizeKey "_PrelinkLinkStateSize" 52 | 53 | #endif /* _PRELINK_H_ */ 54 | 55 | --------------------------------------------------------------------------------