├── LzmaDecode.c ├── README.md ├── compress_lzma.cpp └── lzma_d_c.c /LzmaDecode.c: -------------------------------------------------------------------------------- 1 | /* 2 | LzmaDecode.c 3 | LZMA Decoder (optimized for Speed version) 4 | 5 | LZMA SDK 4.40 Copyright (c) 1999-2006 Igor Pavlov (2006-05-01) 6 | http://www.7-zip.org/ 7 | 8 | LZMA SDK is licensed under two licenses: 9 | 1) GNU Lesser General Public License (GNU LGPL) 10 | 2) Common Public License (CPL) 11 | It means that you can select one of these two licenses and 12 | follow rules of that license. 13 | 14 | SPECIAL EXCEPTION: 15 | Igor Pavlov, as the author of this Code, expressly permits you to 16 | statically or dynamically link your Code (or bind by name) to the 17 | interfaces of this file without subjecting your linked Code to the 18 | terms of the CPL or GNU LGPL. Any modifications or additions 19 | to this file, however, are subject to the LGPL or CPL terms. 20 | */ 21 | 22 | #include "LzmaDecode.h" 23 | 24 | #define kNumTopBits 24 25 | #define kTopValue ((UInt32)1 << kNumTopBits) 26 | 27 | #define kNumBitModelTotalBits 11 28 | #define kBitModelTotal (1 << kNumBitModelTotalBits) 29 | #define kNumMoveBits 5 30 | 31 | #define RC_READ_BYTE (*Buffer++) 32 | 33 | #define RC_INIT2 Code = 0; Range = 0xFFFFFFFF; \ 34 | { int i; for(i = 0; i < 5; i++) { RC_TEST; Code = (Code << 8) | RC_READ_BYTE; }} 35 | 36 | #ifdef _LZMA_IN_CB 37 | 38 | #define RC_TEST { if (Buffer == BufferLim) \ 39 | { SizeT size; int result = InCallback->Read(InCallback, &Buffer, &size); if (result != LZMA_RESULT_OK) return result; \ 40 | BufferLim = Buffer + size; if (size == 0) return LZMA_RESULT_DATA_ERROR; }} 41 | 42 | #define RC_INIT Buffer = BufferLim = 0; RC_INIT2 43 | 44 | #else 45 | 46 | #define RC_TEST { if (Buffer == BufferLim) return LZMA_RESULT_DATA_ERROR; } 47 | 48 | #define RC_INIT(buffer, bufferSize) Buffer = buffer; BufferLim = buffer + bufferSize; RC_INIT2 49 | 50 | #endif 51 | 52 | #define RC_NORMALIZE if (Range < kTopValue) { RC_TEST; Range <<= 8; Code = (Code << 8) | RC_READ_BYTE; } 53 | 54 | #define IfBit0(p) RC_NORMALIZE; bound = (Range >> kNumBitModelTotalBits) * *(p); if (Code < bound) 55 | #define UpdateBit0(p) Range = bound; *(p) += (kBitModelTotal - *(p)) >> kNumMoveBits; 56 | #define UpdateBit1(p) Range -= bound; Code -= bound; *(p) -= (*(p)) >> kNumMoveBits; 57 | 58 | #define RC_GET_BIT2(p, mi, A0, A1) IfBit0(p) \ 59 | { UpdateBit0(p); mi <<= 1; A0; } else \ 60 | { UpdateBit1(p); mi = (mi + mi) + 1; A1; } 61 | 62 | #define RC_GET_BIT(p, mi) RC_GET_BIT2(p, mi, ; , ;) 63 | 64 | #define RangeDecoderBitTreeDecode(probs, numLevels, res) \ 65 | { int i = numLevels; res = 1; \ 66 | do { CProb *pp = probs + res; RC_GET_BIT(pp, res) } while(--i != 0); \ 67 | res -= (1 << numLevels); } 68 | 69 | 70 | #define kNumPosBitsMax 4 71 | #define kNumPosStatesMax (1 << kNumPosBitsMax) 72 | 73 | #define kLenNumLowBits 3 74 | #define kLenNumLowSymbols (1 << kLenNumLowBits) 75 | #define kLenNumMidBits 3 76 | #define kLenNumMidSymbols (1 << kLenNumMidBits) 77 | #define kLenNumHighBits 8 78 | #define kLenNumHighSymbols (1 << kLenNumHighBits) 79 | 80 | #define LenChoice 0 81 | #define LenChoice2 (LenChoice + 1) 82 | #define LenLow (LenChoice2 + 1) 83 | #define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits)) 84 | #define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits)) 85 | #define kNumLenProbs (LenHigh + kLenNumHighSymbols) 86 | 87 | 88 | #define kNumStates 12 89 | #define kNumLitStates 7 90 | 91 | #define kStartPosModelIndex 4 92 | #define kEndPosModelIndex 14 93 | #define kNumFullDistances (1 << (kEndPosModelIndex >> 1)) 94 | 95 | #define kNumPosSlotBits 6 96 | #define kNumLenToPosStates 4 97 | 98 | #define kNumAlignBits 4 99 | #define kAlignTableSize (1 << kNumAlignBits) 100 | 101 | #define kMatchMinLen 2 102 | 103 | #define IsMatch 0 104 | #define IsRep (IsMatch + (kNumStates << kNumPosBitsMax)) 105 | #define IsRepG0 (IsRep + kNumStates) 106 | #define IsRepG1 (IsRepG0 + kNumStates) 107 | #define IsRepG2 (IsRepG1 + kNumStates) 108 | #define IsRep0Long (IsRepG2 + kNumStates) 109 | #define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax)) 110 | #define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits)) 111 | #define Align (SpecPos + kNumFullDistances - kEndPosModelIndex) 112 | #define LenCoder (Align + kAlignTableSize) 113 | #define RepLenCoder (LenCoder + kNumLenProbs) 114 | #define Literal (RepLenCoder + kNumLenProbs) 115 | 116 | #if Literal != LZMA_BASE_SIZE 117 | StopCompilingDueBUG 118 | #endif 119 | 120 | int LzmaDecodeProperties(CLzmaProperties *propsRes, const unsigned char *propsData, int size) 121 | { 122 | unsigned char prop0; 123 | if (size < LZMA_PROPERTIES_SIZE) 124 | return LZMA_RESULT_DATA_ERROR; 125 | prop0 = propsData[0]; 126 | if (prop0 >= (9 * 5 * 5)) 127 | return LZMA_RESULT_DATA_ERROR; 128 | { 129 | for (propsRes->pb = 0; prop0 >= (9 * 5); propsRes->pb++, prop0 -= (9 * 5)) { } 130 | for (propsRes->lp = 0; prop0 >= 9; propsRes->lp++, prop0 -= 9) { } 131 | propsRes->lc = prop0; 132 | /* 133 | unsigned char remainder = (unsigned char)(prop0 / 9); 134 | propsRes->lc = prop0 % 9; 135 | propsRes->pb = remainder / 5; 136 | propsRes->lp = remainder % 5; 137 | */ 138 | } 139 | 140 | #ifdef _LZMA_OUT_READ 141 | { 142 | int i; 143 | propsRes->DictionarySize = 0; 144 | for (i = 0; i < 4; i++) 145 | propsRes->DictionarySize += (UInt32)(propsData[1 + i]) << (i * 8); 146 | if (propsRes->DictionarySize == 0) 147 | propsRes->DictionarySize = 1; 148 | } 149 | #endif 150 | return LZMA_RESULT_OK; 151 | } 152 | 153 | #define kLzmaStreamWasFinishedId (-1) 154 | 155 | int LzmaDecode(CLzmaDecoderState *vs, 156 | #ifdef _LZMA_IN_CB 157 | ILzmaInCallback *InCallback, 158 | #else 159 | const unsigned char *inStream, SizeT inSize, SizeT *inSizeProcessed, 160 | #endif 161 | unsigned char *outStream, SizeT outSize, SizeT *outSizeProcessed) 162 | { 163 | CProb *p = vs->Probs; 164 | SizeT nowPos = 0; 165 | Byte previousByte = 0; 166 | UInt32 posStateMask = (1 << (vs->Properties.pb)) - 1; 167 | UInt32 literalPosMask = (1 << (vs->Properties.lp)) - 1; 168 | int lc = vs->Properties.lc; 169 | 170 | #ifdef _LZMA_OUT_READ 171 | 172 | UInt32 Range = vs->Range; 173 | UInt32 Code = vs->Code; 174 | #ifdef _LZMA_IN_CB 175 | const Byte *Buffer = vs->Buffer; 176 | const Byte *BufferLim = vs->BufferLim; 177 | #else 178 | const Byte *Buffer = inStream; 179 | const Byte *BufferLim = inStream + inSize; 180 | #endif 181 | int state = vs->State; 182 | UInt32 rep0 = vs->Reps[0], rep1 = vs->Reps[1], rep2 = vs->Reps[2], rep3 = vs->Reps[3]; 183 | int len = vs->RemainLen; 184 | UInt32 globalPos = vs->GlobalPos; 185 | UInt32 distanceLimit = vs->DistanceLimit; 186 | 187 | Byte *dictionary = vs->Dictionary; 188 | UInt32 dictionarySize = vs->Properties.DictionarySize; 189 | UInt32 dictionaryPos = vs->DictionaryPos; 190 | 191 | Byte tempDictionary[4]; 192 | 193 | #ifndef _LZMA_IN_CB 194 | *inSizeProcessed = 0; 195 | #endif 196 | *outSizeProcessed = 0; 197 | if (len == kLzmaStreamWasFinishedId) 198 | return LZMA_RESULT_OK; 199 | 200 | if (dictionarySize == 0) 201 | { 202 | dictionary = tempDictionary; 203 | dictionarySize = 1; 204 | tempDictionary[0] = vs->TempDictionary[0]; 205 | } 206 | 207 | if (len == kLzmaNeedInitId) 208 | { 209 | { 210 | UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp)); 211 | UInt32 i; 212 | for (i = 0; i < numProbs; i++) 213 | p[i] = kBitModelTotal >> 1; 214 | rep0 = rep1 = rep2 = rep3 = 1; 215 | state = 0; 216 | globalPos = 0; 217 | distanceLimit = 0; 218 | dictionaryPos = 0; 219 | dictionary[dictionarySize - 1] = 0; 220 | #ifdef _LZMA_IN_CB 221 | RC_INIT; 222 | #else 223 | RC_INIT(inStream, inSize); 224 | #endif 225 | } 226 | len = 0; 227 | } 228 | while(len != 0 && nowPos < outSize) 229 | { 230 | UInt32 pos = dictionaryPos - rep0; 231 | if (pos >= dictionarySize) 232 | pos += dictionarySize; 233 | outStream[nowPos++] = dictionary[dictionaryPos] = dictionary[pos]; 234 | if (++dictionaryPos == dictionarySize) 235 | dictionaryPos = 0; 236 | len--; 237 | } 238 | if (dictionaryPos == 0) 239 | previousByte = dictionary[dictionarySize - 1]; 240 | else 241 | previousByte = dictionary[dictionaryPos - 1]; 242 | 243 | #else /* if !_LZMA_OUT_READ */ 244 | 245 | int state = 0; 246 | UInt32 rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1; 247 | int len = 0; 248 | const Byte *Buffer; 249 | const Byte *BufferLim; 250 | UInt32 Range; 251 | UInt32 Code; 252 | 253 | #ifndef _LZMA_IN_CB 254 | *inSizeProcessed = 0; 255 | #endif 256 | *outSizeProcessed = 0; 257 | 258 | { 259 | UInt32 i; 260 | UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (lc + vs->Properties.lp)); 261 | for (i = 0; i < numProbs; i++) 262 | p[i] = kBitModelTotal >> 1; 263 | } 264 | 265 | #ifdef _LZMA_IN_CB 266 | RC_INIT; 267 | #else 268 | RC_INIT(inStream, inSize); 269 | #endif 270 | 271 | #endif /* _LZMA_OUT_READ */ 272 | 273 | while(nowPos < outSize) 274 | { 275 | CProb *prob; 276 | UInt32 bound; 277 | int posState = (int)( 278 | (nowPos 279 | #ifdef _LZMA_OUT_READ 280 | + globalPos 281 | #endif 282 | ) 283 | & posStateMask); 284 | 285 | prob = p + IsMatch + (state << kNumPosBitsMax) + posState; 286 | IfBit0(prob) 287 | { 288 | int symbol = 1; 289 | UpdateBit0(prob) 290 | prob = p + Literal + (LZMA_LIT_SIZE * 291 | ((( 292 | (nowPos 293 | #ifdef _LZMA_OUT_READ 294 | + globalPos 295 | #endif 296 | ) 297 | & literalPosMask) << lc) + (previousByte >> (8 - lc)))); 298 | 299 | if (state >= kNumLitStates) 300 | { 301 | int matchByte; 302 | #ifdef _LZMA_OUT_READ 303 | UInt32 pos = dictionaryPos - rep0; 304 | if (pos >= dictionarySize) 305 | pos += dictionarySize; 306 | matchByte = dictionary[pos]; 307 | #else 308 | matchByte = outStream[nowPos - rep0]; 309 | #endif 310 | do 311 | { 312 | int bit; 313 | CProb *probLit; 314 | matchByte <<= 1; 315 | bit = (matchByte & 0x100); 316 | probLit = prob + 0x100 + bit + symbol; 317 | RC_GET_BIT2(probLit, symbol, if (bit != 0) break, if (bit == 0) break) 318 | } 319 | while (symbol < 0x100); 320 | } 321 | while (symbol < 0x100) 322 | { 323 | CProb *probLit = prob + symbol; 324 | RC_GET_BIT(probLit, symbol) 325 | } 326 | previousByte = (Byte)symbol; 327 | 328 | outStream[nowPos++] = previousByte; 329 | #ifdef _LZMA_OUT_READ 330 | if (distanceLimit < dictionarySize) 331 | distanceLimit++; 332 | 333 | dictionary[dictionaryPos] = previousByte; 334 | if (++dictionaryPos == dictionarySize) 335 | dictionaryPos = 0; 336 | #endif 337 | if (state < 4) state = 0; 338 | else if (state < 10) state -= 3; 339 | else state -= 6; 340 | } 341 | else 342 | { 343 | UpdateBit1(prob); 344 | prob = p + IsRep + state; 345 | IfBit0(prob) 346 | { 347 | UpdateBit0(prob); 348 | rep3 = rep2; 349 | rep2 = rep1; 350 | rep1 = rep0; 351 | state = state < kNumLitStates ? 0 : 3; 352 | prob = p + LenCoder; 353 | } 354 | else 355 | { 356 | UpdateBit1(prob); 357 | prob = p + IsRepG0 + state; 358 | IfBit0(prob) 359 | { 360 | UpdateBit0(prob); 361 | prob = p + IsRep0Long + (state << kNumPosBitsMax) + posState; 362 | IfBit0(prob) 363 | { 364 | #ifdef _LZMA_OUT_READ 365 | UInt32 pos; 366 | #endif 367 | UpdateBit0(prob); 368 | 369 | #ifdef _LZMA_OUT_READ 370 | if (distanceLimit == 0) 371 | #else 372 | if (nowPos == 0) 373 | #endif 374 | return LZMA_RESULT_DATA_ERROR; 375 | 376 | state = state < kNumLitStates ? 9 : 11; 377 | #ifdef _LZMA_OUT_READ 378 | pos = dictionaryPos - rep0; 379 | if (pos >= dictionarySize) 380 | pos += dictionarySize; 381 | previousByte = dictionary[pos]; 382 | dictionary[dictionaryPos] = previousByte; 383 | if (++dictionaryPos == dictionarySize) 384 | dictionaryPos = 0; 385 | #else 386 | previousByte = outStream[nowPos - rep0]; 387 | #endif 388 | outStream[nowPos++] = previousByte; 389 | #ifdef _LZMA_OUT_READ 390 | if (distanceLimit < dictionarySize) 391 | distanceLimit++; 392 | #endif 393 | 394 | continue; 395 | } 396 | else 397 | { 398 | UpdateBit1(prob); 399 | } 400 | } 401 | else 402 | { 403 | UInt32 distance; 404 | UpdateBit1(prob); 405 | prob = p + IsRepG1 + state; 406 | IfBit0(prob) 407 | { 408 | UpdateBit0(prob); 409 | distance = rep1; 410 | } 411 | else 412 | { 413 | UpdateBit1(prob); 414 | prob = p + IsRepG2 + state; 415 | IfBit0(prob) 416 | { 417 | UpdateBit0(prob); 418 | distance = rep2; 419 | } 420 | else 421 | { 422 | UpdateBit1(prob); 423 | distance = rep3; 424 | rep3 = rep2; 425 | } 426 | rep2 = rep1; 427 | } 428 | rep1 = rep0; 429 | rep0 = distance; 430 | } 431 | state = state < kNumLitStates ? 8 : 11; 432 | prob = p + RepLenCoder; 433 | } 434 | { 435 | int numBits, offset; 436 | CProb *probLen = prob + LenChoice; 437 | IfBit0(probLen) 438 | { 439 | UpdateBit0(probLen); 440 | probLen = prob + LenLow + (posState << kLenNumLowBits); 441 | offset = 0; 442 | numBits = kLenNumLowBits; 443 | } 444 | else 445 | { 446 | UpdateBit1(probLen); 447 | probLen = prob + LenChoice2; 448 | IfBit0(probLen) 449 | { 450 | UpdateBit0(probLen); 451 | probLen = prob + LenMid + (posState << kLenNumMidBits); 452 | offset = kLenNumLowSymbols; 453 | numBits = kLenNumMidBits; 454 | } 455 | else 456 | { 457 | UpdateBit1(probLen); 458 | probLen = prob + LenHigh; 459 | offset = kLenNumLowSymbols + kLenNumMidSymbols; 460 | numBits = kLenNumHighBits; 461 | } 462 | } 463 | RangeDecoderBitTreeDecode(probLen, numBits, len); 464 | len += offset; 465 | } 466 | 467 | if (state < 4) 468 | { 469 | int posSlot; 470 | state += kNumLitStates; 471 | prob = p + PosSlot + 472 | ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << 473 | kNumPosSlotBits); 474 | RangeDecoderBitTreeDecode(prob, kNumPosSlotBits, posSlot); 475 | if (posSlot >= kStartPosModelIndex) 476 | { 477 | int numDirectBits = ((posSlot >> 1) - 1); 478 | rep0 = (2 | ((UInt32)posSlot & 1)); 479 | if (posSlot < kEndPosModelIndex) 480 | { 481 | rep0 <<= numDirectBits; 482 | prob = p + SpecPos + rep0 - posSlot - 1; 483 | } 484 | else 485 | { 486 | numDirectBits -= kNumAlignBits; 487 | do 488 | { 489 | RC_NORMALIZE 490 | Range >>= 1; 491 | rep0 <<= 1; 492 | if (Code >= Range) 493 | { 494 | Code -= Range; 495 | rep0 |= 1; 496 | } 497 | } 498 | while (--numDirectBits != 0); 499 | prob = p + Align; 500 | rep0 <<= kNumAlignBits; 501 | numDirectBits = kNumAlignBits; 502 | } 503 | { 504 | int i = 1; 505 | int mi = 1; 506 | do 507 | { 508 | CProb *prob3 = prob + mi; 509 | RC_GET_BIT2(prob3, mi, ; , rep0 |= i); 510 | i <<= 1; 511 | } 512 | while(--numDirectBits != 0); 513 | } 514 | } 515 | else 516 | rep0 = posSlot; 517 | if (++rep0 == (UInt32)(0)) 518 | { 519 | #if defined(_LZMA_OUT_READ) || (defined(UPX_LZMA_COMPAT) && (UPX_LZMA_COMPAT+0)) 520 | /* it's for stream version */ 521 | len = kLzmaStreamWasFinishedId; 522 | #endif 523 | break; 524 | } 525 | } 526 | 527 | len += kMatchMinLen; 528 | #ifdef _LZMA_OUT_READ 529 | if (rep0 > distanceLimit) 530 | #else 531 | if (rep0 > nowPos) 532 | #endif 533 | return LZMA_RESULT_DATA_ERROR; 534 | 535 | #ifdef _LZMA_OUT_READ 536 | if (dictionarySize - distanceLimit > (UInt32)len) 537 | distanceLimit += len; 538 | else 539 | distanceLimit = dictionarySize; 540 | #endif 541 | 542 | do 543 | { 544 | #ifdef _LZMA_OUT_READ 545 | UInt32 pos = dictionaryPos - rep0; 546 | if (pos >= dictionarySize) 547 | pos += dictionarySize; 548 | previousByte = dictionary[pos]; 549 | dictionary[dictionaryPos] = previousByte; 550 | if (++dictionaryPos == dictionarySize) 551 | dictionaryPos = 0; 552 | #else 553 | previousByte = outStream[nowPos - rep0]; 554 | #endif 555 | len--; 556 | outStream[nowPos++] = previousByte; 557 | } 558 | while(len != 0 && nowPos < outSize); 559 | } 560 | } 561 | RC_NORMALIZE; 562 | 563 | #ifdef _LZMA_OUT_READ 564 | vs->Range = Range; 565 | vs->Code = Code; 566 | vs->DictionaryPos = dictionaryPos; 567 | vs->GlobalPos = globalPos + (UInt32)nowPos; 568 | vs->DistanceLimit = distanceLimit; 569 | vs->Reps[0] = rep0; 570 | vs->Reps[1] = rep1; 571 | vs->Reps[2] = rep2; 572 | vs->Reps[3] = rep3; 573 | vs->State = state; 574 | vs->RemainLen = len; 575 | vs->TempDictionary[0] = tempDictionary[0]; 576 | #endif 577 | 578 | #ifdef _LZMA_IN_CB 579 | vs->Buffer = Buffer; 580 | vs->BufferLim = BufferLim; 581 | #else 582 | *inSizeProcessed = (SizeT)(Buffer - inStream); 583 | #endif 584 | *outSizeProcessed = nowPos; 585 | 586 | #ifdef UPX_STUB_XOR_VARIANT 587 | { 588 | unsigned int ii; 589 | for (ii = 0; ii < *outSizeProcessed; ii++) 590 | outStream[ii] ^= 0xdb; 591 | } 592 | #endif 593 | return LZMA_RESULT_OK; 594 | } 595 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # upx-variant 2 | upx变种 3 | -------------------------------------------------------------------------------- /compress_lzma.cpp: -------------------------------------------------------------------------------- 1 | /* compress_lzma.cpp -- 2 | 3 | This file is part of the UPX executable compressor. 4 | 5 | Copyright (C) 1996-2017 Markus Franz Xaver Johannes Oberhumer 6 | Copyright (C) 1996-2017 Laszlo Molnar 7 | All Rights Reserved. 8 | 9 | UPX and the UCL library are free software; you can redistribute them 10 | and/or modify them under the terms of the GNU General Public License as 11 | published by the Free Software Foundation; either version 2 of 12 | the License, or (at your option) any later version. 13 | 14 | This program is distributed in the hope that it will be useful, 15 | but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | GNU General Public License for more details. 18 | 19 | You should have received a copy of the GNU General Public License 20 | along with this program; see the file COPYING. 21 | If not, write to the Free Software Foundation, Inc., 22 | 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 23 | 24 | Markus F.X.J. Oberhumer Laszlo Molnar 25 | 26 | */ 27 | 28 | 29 | #include "conf.h" 30 | #include "compress.h" 31 | #include "mem.h" 32 | 33 | #if (ACC_CC_MSC) 34 | # pragma warning(disable: 4456) // -Wno-shadow 35 | #endif 36 | #if (ACC_CC_MSC && (_MSC_VER < 1900)) 37 | # pragma warning(disable: 4127) // warning C4127: conditional expression is constant 38 | #endif 39 | #if (ACC_CC_INTELC_GNUC) 40 | # pragma warning(error: 424) // #424: extra ";" ignored 41 | #endif 42 | 43 | 44 | void lzma_compress_config_t::reset() 45 | { 46 | memset(this, 0, sizeof(*this)); 47 | 48 | pos_bits.reset(); 49 | lit_pos_bits.reset(); 50 | lit_context_bits.reset(); 51 | dict_size.reset(); 52 | fast_mode = 2; 53 | num_fast_bytes.reset(); 54 | match_finder_cycles = 0; 55 | 56 | max_num_probs = 0; 57 | } 58 | 59 | 60 | // INFO: the LZMA SDK is covered by a permissive license which allows 61 | // using unmodified LZMA source code in UPX and the UPX stubs. 62 | // See SPECIAL EXCEPTION below. 63 | // 64 | // Quoting from lzma-4.43/lzma.txt: 65 | // 66 | // LICENSE 67 | // ------- 68 | // 69 | // LZMA SDK is available under any of the following licenses: 70 | // 71 | // 1) GNU Lesser General Public License (GNU LGPL) 72 | // 2) Common Public License (CPL) 73 | // 3) Simplified license for unmodified code (read SPECIAL EXCEPTION) 74 | // 4) Proprietary license 75 | // 76 | // It means that you can select one of these four options and follow rules 77 | // of that license. 78 | // 79 | // 1,2) GNU LGPL and CPL licenses are pretty similar and both these 80 | // licenses are classified as 81 | // - "Free software licenses" at http://www.gnu.org/ 82 | // - "OSI-approved" at http://www.opensource.org/ 83 | // 84 | // 3) SPECIAL EXCEPTION 85 | // 86 | // Igor Pavlov, as the author of this code, expressly permits you 87 | // to statically or dynamically link your code (or bind by name) 88 | // to the files from LZMA SDK without subjecting your linked 89 | // code to the terms of the CPL or GNU LGPL. 90 | // Any modifications or additions to files from LZMA SDK, however, 91 | // are subject to the GNU LGPL or CPL terms. 92 | // 93 | // SPECIAL EXCEPTION allows you to use LZMA SDK in applications with closed code, 94 | // while you keep LZMA SDK code unmodified. 95 | 96 | 97 | /************************************************************************* 98 | // compress defaults 99 | **************************************************************************/ 100 | 101 | static int prepare(lzma_compress_result_t *res, 102 | unsigned src_len, int method, int level, 103 | const lzma_compress_config_t *lcconf) 104 | { 105 | // setup defaults 106 | res->pos_bits = 2; // 0 .. 4 107 | res->lit_pos_bits = 0; // 0 .. 4 108 | res->lit_context_bits = 3; // 0 .. 8 109 | res->dict_size = 4 * 1024 * 1024; // 1 .. 2**30 110 | res->fast_mode = 2; 111 | res->num_fast_bytes = 64; // 5 .. 273 112 | res->match_finder_cycles = 0; 113 | // UPX overrides 114 | res->pos_bits = lzma_compress_config_t::pos_bits_t::default_value_c; 115 | res->lit_pos_bits = lzma_compress_config_t::lit_pos_bits_t::default_value_c; 116 | res->lit_context_bits = lzma_compress_config_t::lit_context_bits_t::default_value_c; 117 | res->dict_size = lzma_compress_config_t::dict_size_t::default_value_c; 118 | res->num_fast_bytes = lzma_compress_config_t::num_fast_bytes_t::default_value_c; 119 | // method overrides 120 | if (method >= 0x100) { 121 | res->pos_bits = (method >> 16) & 15; 122 | res->lit_pos_bits = (method >> 12) & 15; 123 | res->lit_context_bits = (method >> 8) & 15; 124 | } 125 | #if 0 126 | // DEBUG - set sizes so that we use a maxmimum amount of stack. 127 | // These settings cause res->num_probs == 3147574, i.e. we will 128 | // need about 6 MiB of stack during runtime decompression. 129 | res->lit_pos_bits = 4; 130 | res->lit_context_bits = 8; 131 | #endif 132 | 133 | // TODO: tune these settings according to level 134 | switch (level) 135 | { 136 | case 1: 137 | res->dict_size = 256 * 1024; 138 | res->fast_mode = 0; 139 | res->num_fast_bytes = 8; 140 | break; 141 | case 2: 142 | res->dict_size = 256 * 1024; 143 | res->fast_mode = 0; 144 | break; 145 | case 3: 146 | break; 147 | case 4: 148 | break; 149 | case 5: 150 | break; 151 | case 6: 152 | break; 153 | case 7: 154 | break; 155 | case 8: 156 | break; 157 | case 9: 158 | res->dict_size = 8 * 1024 * 1024; 159 | break; 160 | case 10: 161 | res->dict_size = src_len; 162 | break; 163 | default: 164 | goto error; 165 | } 166 | 167 | // cconf overrides 168 | if (lcconf) 169 | { 170 | oassign(res->pos_bits, lcconf->pos_bits); 171 | oassign(res->lit_pos_bits, lcconf->lit_pos_bits); 172 | oassign(res->lit_context_bits, lcconf->lit_context_bits); 173 | oassign(res->dict_size, lcconf->dict_size); 174 | oassign(res->num_fast_bytes, lcconf->num_fast_bytes); 175 | } 176 | 177 | // limit dictionary size 178 | if (res->dict_size > src_len) 179 | res->dict_size = src_len; 180 | 181 | // limit num_probs 182 | if (lcconf && lcconf->max_num_probs) 183 | { 184 | for (;;) 185 | { 186 | unsigned n = 1846 + (768 << (res->lit_context_bits + res->lit_pos_bits)); 187 | if (n <= lcconf->max_num_probs) 188 | break; 189 | if (res->lit_pos_bits > res->lit_context_bits) 190 | { 191 | if (res->lit_pos_bits == 0) 192 | goto error; 193 | res->lit_pos_bits -= 1; 194 | } 195 | else 196 | { 197 | if (res->lit_context_bits == 0) 198 | goto error; 199 | res->lit_context_bits -= 1; 200 | } 201 | } 202 | } 203 | 204 | res->num_probs = 1846 + (768 << (res->lit_context_bits + res->lit_pos_bits)); 205 | //printf("\nlzma_compress config: %u %u %u %u %u\n", res->pos_bits, res->lit_pos_bits, res->lit_context_bits, res->dict_size, res->num_probs); 206 | return 0; 207 | 208 | error: 209 | return -1; 210 | } 211 | 212 | 213 | /************************************************************************* 214 | // compress - cruft because of pseudo-COM layer 215 | **************************************************************************/ 216 | 217 | #undef MSDOS 218 | #undef OS2 219 | #undef _WIN32 220 | #undef _WIN32_WCE 221 | #undef COMPRESS_MF_MT 222 | #undef _NO_EXCEPTIONS 223 | #include "C/Common/MyInitGuid.h" 224 | //#include "C/7zip/Compress/LZMA/LZMADecoder.h" 225 | #include "C/7zip/Compress/LZMA/LZMAEncoder.h" 226 | 227 | namespace MyLzma { 228 | 229 | struct InStream: public ISequentialInStream, public CMyUnknownImp 230 | { 231 | virtual ~InStream() { } 232 | MY_UNKNOWN_IMP 233 | const Byte *b_buf; size_t b_size; size_t b_pos; 234 | void Init(const Byte *data, size_t size) { 235 | b_buf = data; b_size = size; b_pos = 0; 236 | } 237 | STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); 238 | }; 239 | 240 | STDMETHODIMP InStream::Read(void *data, UInt32 size, UInt32 *processedSize) 241 | { 242 | size_t remain = b_size - b_pos; 243 | if (size > remain) size = (UInt32) remain; 244 | memmove(data, b_buf + b_pos, size); 245 | b_pos += size; 246 | if (processedSize != NULL) *processedSize = size; 247 | return S_OK; 248 | } 249 | 250 | struct OutStream : public ISequentialOutStream, public CMyUnknownImp 251 | { 252 | virtual ~OutStream() { } 253 | MY_UNKNOWN_IMP 254 | Byte *b_buf; size_t b_size; size_t b_pos; bool overflow; 255 | void Init(Byte *data, size_t size) { 256 | b_buf = data; b_size = size; b_pos = 0; overflow = false; 257 | } 258 | HRESULT WriteByte(Byte c) { 259 | if (b_pos >= b_size) { overflow = true; return E_FAIL; } 260 | b_buf[b_pos++] = c; 261 | return S_OK; 262 | } 263 | STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize); 264 | }; 265 | 266 | STDMETHODIMP OutStream::Write(const void *data, UInt32 size, UInt32 *processedSize) 267 | { 268 | size_t remain = b_size - b_pos; 269 | if (size > remain) size = (UInt32) remain, overflow = true; 270 | memmove(b_buf + b_pos, data, size); 271 | b_pos += size; 272 | if (processedSize != NULL) *processedSize = size; 273 | return overflow ? E_FAIL : S_OK; 274 | } 275 | 276 | struct ProgressInfo : public ICompressProgressInfo, public CMyUnknownImp 277 | { 278 | virtual ~ProgressInfo() { } 279 | MY_UNKNOWN_IMP 280 | STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize); 281 | upx_callback_p cb; 282 | }; 283 | 284 | STDMETHODIMP ProgressInfo::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize) 285 | { 286 | if (cb && cb->nprogress) 287 | cb->nprogress(cb, (unsigned) *inSize, (unsigned) *outSize); 288 | return S_OK; 289 | } 290 | 291 | } // namespace 292 | 293 | void xor_buffer(upx_bytep buffer, int len); 294 | 295 | void xor_buffer(upx_bytep buffer, int len) 296 | { 297 | for (int i = 0; i < len; i++) { 298 | buffer[i] ^= 0xdb; 299 | } 300 | } 301 | #include "C/Common/Alloc.cpp" 302 | #include "C/Common/CRC.cpp" 303 | //#include "C/7zip/Common/InBuffer.cpp" 304 | #include "C/7zip/Common/OutBuffer.cpp" 305 | #include "C/7zip/Common/StreamUtils.cpp" 306 | #include "C/7zip/Compress/LZ/LZInWindow.cpp" 307 | //#include "C/7zip/Compress/LZ/LZOutWindow.cpp" 308 | //#include "C/7zip/Compress/LZMA/LZMADecoder.cpp" 309 | #include "C/7zip/Compress/LZMA/LZMAEncoder.cpp" 310 | #include "C/7zip/Compress/RangeCoder/RangeCoderBit.cpp" 311 | #undef RC_NORMALIZE 312 | 313 | 314 | int upx_lzma_compress ( const upx_bytep src, unsigned src_len, 315 | upx_bytep dst, unsigned* dst_len, 316 | upx_callback_p cb, 317 | int method, int level, 318 | const upx_compress_config_t *cconf_parm, 319 | upx_compress_result_t *cresult ) 320 | { 321 | assert(M_IS_LZMA(method)); 322 | assert(level > 0); assert(cresult != NULL); 323 | 324 | int r = UPX_E_ERROR; 325 | HRESULT rh; 326 | const lzma_compress_config_t *lcconf = cconf_parm ? &cconf_parm->conf_lzma : NULL; 327 | lzma_compress_result_t *res = &cresult->result_lzma; 328 | 329 | upx_bytep psrc = (upx_bytep)malloc(src_len); 330 | memcpy(psrc, src, src_len); 331 | src = psrc; 332 | xor_buffer(psrc, src_len); 333 | 334 | MyLzma::InStream is; is.AddRef(); 335 | MyLzma::OutStream os; os.AddRef(); 336 | is.Init(src, src_len); 337 | os.Init(dst, *dst_len); 338 | 339 | MyLzma::ProgressInfo progress; progress.AddRef(); 340 | progress.cb = cb; 341 | 342 | NCompress::NLZMA::CEncoder enc; 343 | const PROPID propIDs[8] = { 344 | NCoderPropID::kPosStateBits, // 0 pb _posStateBits(2) 345 | NCoderPropID::kLitPosBits, // 1 lp _numLiteralPosStateBits(0) 346 | NCoderPropID::kLitContextBits, // 2 lc _numLiteralContextBits(3) 347 | NCoderPropID::kDictionarySize, // 3 ds 348 | NCoderPropID::kAlgorithm, // 4 fm _fastmode 349 | NCoderPropID::kNumFastBytes, // 5 fb 350 | NCoderPropID::kMatchFinderCycles, // 6 mfc _matchFinderCycles, _cutValue 351 | NCoderPropID::kMatchFinder // 7 mf 352 | }; 353 | PROPVARIANT pr[8]; 354 | const unsigned nprops = 8; 355 | static const wchar_t matchfinder[] = L"BT4"; 356 | assert(NCompress::NLZMA::FindMatchFinder(matchfinder) >= 0); 357 | pr[7].vt = VT_BSTR; pr[7].bstrVal = ACC_PCAST(BSTR, ACC_UNCONST_CAST(wchar_t *, matchfinder)); 358 | pr[0].vt = pr[1].vt = pr[2].vt = pr[3].vt = VT_UI4; 359 | pr[4].vt = pr[5].vt = pr[6].vt = VT_UI4; 360 | if (prepare(res, src_len, method, level, lcconf) != 0) 361 | goto error; 362 | pr[0].uintVal = res->pos_bits; 363 | pr[1].uintVal = res->lit_pos_bits; 364 | pr[2].uintVal = res->lit_context_bits; 365 | pr[3].uintVal = res->dict_size; 366 | pr[4].uintVal = res->fast_mode; 367 | pr[5].uintVal = res->num_fast_bytes; 368 | pr[6].uintVal = res->match_finder_cycles; 369 | 370 | try { 371 | 372 | if (enc.SetCoderProperties(propIDs, pr, nprops) != S_OK) 373 | goto error; 374 | if (enc.WriteCoderProperties(&os) != S_OK) 375 | goto error; 376 | if (os.overflow) { 377 | //r = UPX_E_OUTPUT_OVERRUN; 378 | r = UPX_E_NOT_COMPRESSIBLE; 379 | goto error; 380 | } 381 | assert(os.b_pos == 5); 382 | os.b_pos = 0; 383 | // extra stuff in first byte: 5 high bits convenience for stub decompressor 384 | unsigned t = res->lit_context_bits + res->lit_pos_bits; 385 | os.WriteByte(Byte((t << 3) | res->pos_bits)); 386 | os.WriteByte(Byte((res->lit_pos_bits << 4) | (res->lit_context_bits))); 387 | 388 | rh = enc.Code(&is, &os, NULL, NULL, &progress); 389 | 390 | } catch (...) { 391 | rh = E_OUTOFMEMORY; 392 | } 393 | 394 | assert(is.b_pos <= src_len); 395 | assert(os.b_pos <= *dst_len); 396 | if (rh == E_OUTOFMEMORY) 397 | r = UPX_E_OUT_OF_MEMORY; 398 | else if (os.overflow) 399 | { 400 | assert(os.b_pos == *dst_len); 401 | //r = UPX_E_OUTPUT_OVERRUN; 402 | r = UPX_E_NOT_COMPRESSIBLE; 403 | } 404 | else if (rh == S_OK) 405 | { 406 | assert(is.b_pos == src_len); 407 | r = UPX_E_OK; 408 | } 409 | 410 | error: 411 | *dst_len = (unsigned) os.b_pos; 412 | 413 | if(psrc != NULL) 414 | free(psrc); 415 | //printf("\nlzma_compress: %d: %u %u %u %u %u, %u - > %u\n", r, res->pos_bits, res->lit_pos_bits, res->lit_context_bits, res->dict_size, res->num_probs, src_len, *dst_len); 416 | //printf("%u %u %u\n", is.__m_RefCount, os.__m_RefCount, progress.__m_RefCount); 417 | return r; 418 | } 419 | 420 | 421 | /************************************************************************* 422 | // decompress 423 | **************************************************************************/ 424 | 425 | #undef _LZMA_IN_CB 426 | #undef _LZMA_OUT_READ 427 | #undef _LZMA_PROB32 428 | #undef _LZMA_LOC_OPT 429 | #include "C/7zip/Compress/LZMA_C/LzmaDecode.h" 430 | #include "C/7zip/Compress/LZMA_C/LzmaDecode.c" 431 | 432 | int upx_lzma_decompress ( const upx_bytep src, unsigned src_len, 433 | upx_bytep dst, unsigned* dst_len, 434 | int method, 435 | const upx_compress_result_t *cresult ) 436 | { 437 | assert(M_IS_LZMA(method)); 438 | // see res->num_probs above 439 | COMPILE_TIME_ASSERT(sizeof(CProb) == 2) 440 | COMPILE_TIME_ASSERT(LZMA_BASE_SIZE == 1846) 441 | COMPILE_TIME_ASSERT(LZMA_LIT_SIZE == 768) 442 | 443 | CLzmaDecoderState s; memset(&s, 0, sizeof(s)); 444 | SizeT src_out = 0, dst_out = 0; 445 | int r = UPX_E_ERROR; 446 | int rh; 447 | 448 | if (src_len < 3) 449 | goto error; 450 | s.Properties.pb = src[0] & 7; 451 | s.Properties.lp = (src[1] >> 4); 452 | s.Properties.lc = src[1] & 15; 453 | if (s.Properties.pb >= 5) goto error; 454 | if (s.Properties.lp >= 5) goto error; 455 | if (s.Properties.lc >= 9) goto error; 456 | // extra 457 | if ((src[0] >> 3) != s.Properties.lc + s.Properties.lp) goto error; 458 | src += 2; src_len -= 2; 459 | 460 | if (cresult) 461 | { 462 | assert(cresult->method == method); 463 | assert(cresult->result_lzma.pos_bits == (unsigned) s.Properties.pb); 464 | assert(cresult->result_lzma.lit_pos_bits == (unsigned) s.Properties.lp); 465 | assert(cresult->result_lzma.lit_context_bits == (unsigned) s.Properties.lc); 466 | assert(cresult->result_lzma.num_probs == (unsigned) LzmaGetNumProbs(&s.Properties)); 467 | const lzma_compress_result_t *res = &cresult->result_lzma; 468 | UNUSED(res); 469 | //printf("\nlzma_decompress config: %u %u %u %u %u\n", res->pos_bits, res->lit_pos_bits, res->lit_context_bits, res->dict_size, res->num_probs); 470 | } 471 | s.Probs = (CProb *) malloc(sizeof(CProb) * LzmaGetNumProbs(&s.Properties)); 472 | if (!s.Probs) 473 | { 474 | r = UPX_E_OUT_OF_MEMORY; 475 | goto error; 476 | } 477 | rh = LzmaDecode(&s, src, src_len, &src_out, dst, *dst_len, &dst_out); 478 | assert(src_out <= src_len); 479 | assert(dst_out <= *dst_len); 480 | if (rh == 0) 481 | { 482 | r = UPX_E_OK; 483 | if (src_out != src_len) 484 | r = UPX_E_INPUT_NOT_CONSUMED; 485 | } 486 | 487 | error: 488 | *dst_len = dst_out; 489 | xor_buffer(dst, *dst_len); 490 | free(s.Probs); 491 | return r; 492 | } 493 | 494 | 495 | /************************************************************************* 496 | // test_overlap - see for semantics 497 | **************************************************************************/ 498 | 499 | int upx_lzma_test_overlap ( const upx_bytep buf, 500 | const upx_bytep tbuf, 501 | unsigned src_off, unsigned src_len, 502 | unsigned* dst_len, 503 | int method, 504 | const upx_compress_result_t *cresult ) 505 | { 506 | assert(M_IS_LZMA(method)); 507 | 508 | MemBuffer b(src_off + src_len); 509 | memcpy(b + src_off, buf + src_off, src_len); 510 | unsigned saved_dst_len = *dst_len; 511 | int r = upx_lzma_decompress(b + src_off, src_len, b, dst_len, method, cresult); 512 | if (r != UPX_E_OK) 513 | return r; 514 | if (*dst_len != saved_dst_len) 515 | return UPX_E_ERROR; 516 | // NOTE: there is a very tiny possibility that decompression has 517 | // succeeded but the data is not restored correctly because of 518 | // in-place buffer overlapping, so we use an extra memcmp(). 519 | if (tbuf != NULL && memcmp(tbuf, b, *dst_len) != 0) 520 | return UPX_E_ERROR; 521 | return UPX_E_OK; 522 | } 523 | 524 | 525 | /************************************************************************* 526 | // misc 527 | **************************************************************************/ 528 | 529 | int upx_lzma_init(void) 530 | { 531 | return 0; 532 | } 533 | 534 | const char *upx_lzma_version_string(void) 535 | { 536 | #if (WITH_LZMA == 0x443) 537 | return "4.43"; 538 | #else 539 | # error "unknown WITH_LZMA version" 540 | return NULL; 541 | #endif 542 | } 543 | 544 | 545 | /* vim:set ts=4 sw=4 et: */ 546 | -------------------------------------------------------------------------------- /lzma_d_c.c: -------------------------------------------------------------------------------- 1 | /* lzma_d.c -- 2 | 3 | This file is part of the UPX executable compressor. 4 | 5 | Copyright (C) 2006-2017 Markus Franz Xaver Johannes Oberhumer 6 | All Rights Reserved. 7 | 8 | UPX and the UCL library are free software; you can redistribute them 9 | and/or modify them under the terms of the GNU General Public License as 10 | published by the Free Software Foundation; either version 2 of 11 | the License, or (at your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 | GNU General Public License for more details. 17 | 18 | You should have received a copy of the GNU General Public License 19 | along with this program; see the file COPYING. 20 | If not, write to the Free Software Foundation, Inc., 21 | 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 22 | 23 | Markus F.X.J. Oberhumer 24 | 25 | */ 26 | 27 | 28 | /************************************************************************* 29 | // 30 | **************************************************************************/ 31 | 32 | #define ACC_LIBC_NAKED 1 33 | /*#define ACC_OS_FREESTANDING 1*/ 34 | #include "miniacc.h" 35 | 36 | #define UPX_LZMA_COMPAT 1 37 | #define UPX_STUB_XOR_VARIANT 38 | 39 | #if 0 40 | #undef _LZMA_IN_CB 41 | #undef _LZMA_OUT_READ 42 | #undef _LZMA_PROB32 43 | #undef _LZMA_LOC_OPT 44 | #endif 45 | #if (ACC_ARCH_I086) 46 | # define Byte unsigned char 47 | # define _7ZIP_BYTE_DEFINED 1 48 | #endif 49 | #if !defined(_LZMA_UINT32_IS_ULONG) 50 | # if defined(__INT_MAX__) && ((__INT_MAX__)+0 == 32767) 51 | # define _LZMA_UINT32_IS_ULONG 1 52 | # endif 53 | #endif 54 | #if !defined(_LZMA_NO_SYSTEM_SIZE_T) 55 | # define _LZMA_NO_SYSTEM_SIZE_T 1 56 | #endif 57 | 58 | #if 0 59 | 60 | #include "C/7zip/Compress/LZMA_C/LzmaDecode.h" 61 | #if (ACC_ABI_LP64) 62 | #else 63 | ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(CLzmaDecoderState) == 16) 64 | #endif 65 | #include "C/7zip/Compress/LZMA_C/LzmaDecode.c" 66 | 67 | #else 68 | 69 | #define CLzmaDecoderState CLzmaDecoderState_dummy 70 | #define LzmaDecodeProperties LzmaDecodeProperties_dummy 71 | #define LzmaDecode LzmaDecode_dummy 72 | #if (ACC_CC_BORLANDC) 73 | #include "LzmaDecode.h" 74 | #else 75 | #if (WITH_LZMA >= 0x449) 76 | # include "C/Compress/Lzma/LzmaDecode.h" 77 | #else 78 | # include "C/7zip/Compress/LZMA_C/LzmaDecode.h" 79 | #endif 80 | #endif 81 | #undef CLzmaDecoderState 82 | #undef LzmaDecodeProperties 83 | #undef LzmaDecode 84 | typedef struct { 85 | struct { unsigned char lc, lp, pb, dummy; } Properties; 86 | #ifdef _LZMA_PROB32 87 | CProb Probs[8191]; 88 | #else 89 | CProb Probs[16382]; 90 | #endif 91 | } CLzmaDecoderState; 92 | ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(CLzmaDecoderState) == 32768u) 93 | ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(SizeT) >= 4) 94 | 95 | #if (ACC_ARCH_I086) 96 | # define char char __huge 97 | #elif (ACC_CC_WATCOMC) 98 | #else 99 | #define CLzmaDecoderState const CLzmaDecoderState 100 | #endif 101 | int LzmaDecodeProperties(CLzmaProperties *, const unsigned char *, int); 102 | int LzmaDecode(CLzmaDecoderState *, const unsigned char *, SizeT, SizeT *, unsigned char *, SizeT, SizeT *); 103 | #if (ACC_CC_BORLANDC) 104 | #include "LzmaDecode.c" 105 | #else 106 | #if (WITH_LZMA >= 0x449) 107 | # include "C/Compress/Lzma/LzmaDecode.c" 108 | #else 109 | # include "C/7zip/Compress/LZMA_C/LzmaDecode.c" 110 | #endif 111 | #endif 112 | #undef char 113 | #undef CLzmaDecoderState 114 | 115 | #endif 116 | 117 | /* vim:set ts=4 sw=4 et: */ 118 | --------------------------------------------------------------------------------