pedump 0.4.5 → 0.4.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env ruby
2
+ # coding: binary
3
+ require 'pedump/loader'
4
+ require 'pedump/cli'
5
+
6
+ module PEdump::Unpacker; end
7
+
8
+ class PEdump::Unpacker::UPX
9
+ def self.unpack src_fname, dst_fname, log = ''
10
+ log << `upx -dqq #{src_fname} -o #{dst_fname} 2>&1`
11
+ $?.success?
12
+ end
13
+ end
@@ -2,7 +2,7 @@ class PEdump
2
2
  module Version
3
3
  MAJOR = 0
4
4
  MINOR = 4
5
- PATCH = 5
5
+ PATCH = 6
6
6
  BUILD = nil
7
7
 
8
8
  STRING = [MAJOR, MINOR, PATCH, BUILD].compact.join('.')
@@ -116,16 +116,21 @@ class PEdump
116
116
  :Value # A zero-terminated string. See the szKey member description for more information
117
117
  )
118
118
  def self.read f, size = SIZE
119
+ pos = f.tell
119
120
  super.tap do |x|
120
121
  x.szKey = ''
121
122
  x.szKey << f.read(2) until x.szKey[-2..-1] == "\x00\x00" || f.eof?
122
123
  x.Padding = f.tell%4 > 0 ? f.read(4 - f.tell%4) : nil
123
- x.Value = f.read(x.wValueLength*2)
124
+
125
+ value_len = [x.wValueLength*2, x.wLength - (f.tell-pos)].min
126
+ value_len = 0 if value_len < 0
127
+
128
+ x.Value = f.read(value_len)
124
129
  if f.tell%4 > 0
125
130
  f.read(4-f.tell%4) # undoc padding?
126
131
  end
127
- x.szKey.force_encoding('UTF-16LE').encode!('UTF-8').sub!(/\u0000$/,'') rescue nil
128
- x.Value.force_encoding('UTF-16LE').encode!('UTF-8').sub!(/\u0000$/,'') rescue nil
132
+ x.szKey.force_encoding('UTF-16LE').encode!('UTF-8').sub!(/\u0000+$/,'') rescue nil
133
+ x.Value.force_encoding('UTF-16LE').encode!('UTF-8').sub!(/\u0000+$/,'') rescue nil
129
134
  end
130
135
  end
131
136
  end
@@ -0,0 +1,3 @@
1
+ all: aspack_unlzx
2
+ aspack_unlzx:
3
+ gcc aspack_unlzx.c -o aspack_unlzx
@@ -0,0 +1,92 @@
1
+ #include <stdlib.h>
2
+ #include <stdio.h>
3
+ #include <strings.h> // for bzero()
4
+
5
+ #include "lzxdec.c"
6
+
7
+ // based on ASPack Unpacker v1.00 by Dr.Golova (thx! :)
8
+
9
+ /* error codes for unpacker thread */
10
+ #define ERR_OK (0)
11
+ #define ERR_NO_FILE (1)
12
+ #define ERR_FILE_OPEN (2)
13
+ #define ERR_NO_MEM (3)
14
+ #define ERR_CANT_MAP (4)
15
+ #define ERR_FILE_CREATE (5)
16
+ #define ERR_FILE_WRITE (6)
17
+ #define ERR_COPY_OVL (7)
18
+ #define ERR_CORRUPT (8)
19
+ #define ERR_UNKNOWN (9)
20
+ #define ERR_SKIPPED (10)
21
+ #define ERR_UNPACK (11)
22
+ #define ERR_FAILED (12)
23
+
24
+
25
+ void write_result(void*buf, int size){
26
+ fwrite(buf,1,size,stdout);
27
+ }
28
+
29
+ int unpack(BYTE*packed_data, size_t packed_size, size_t unpacked_size){
30
+ LZX_CONTEXT LZX;
31
+ BYTE* unpacked_data = NULL;
32
+ size_t decoded_size;
33
+
34
+ bzero(&LZX, sizeof(LZX));
35
+
36
+ if ( NULL == (unpacked_data = calloc(1, unpacked_size + 300)) ){
37
+ perror("no mem");
38
+ return(ERR_NO_MEM);
39
+ }
40
+
41
+ decoded_size = DecodeLZX(&LZX, packed_data, unpacked_data, packed_size, unpacked_size);
42
+ if ( decoded_size < 0 || decoded_size < unpacked_size ) {
43
+ free(unpacked_data);
44
+ fprintf(stderr,"ERR_UNPACK\n");
45
+ return(ERR_UNPACK);
46
+ }
47
+
48
+ write_result(unpacked_data, decoded_size);
49
+ free(unpacked_data);
50
+ return 0;
51
+ }
52
+
53
+ int main(int argc, char*argv[]){
54
+ size_t packed_size, unpacked_size;
55
+ BYTE* packed_data = NULL;
56
+ int r;
57
+
58
+ if(argc != 3){
59
+ fprintf(stderr, "ASPack unLZX\n");
60
+ fprintf(stderr, "usage: %s <packed_size> <unpacked_size>\n", argv[0]);
61
+ fprintf(stderr, "(data is read from stdin and written to stdout)\n", argv[0]);
62
+ return 1;
63
+ }
64
+
65
+ sscanf(argv[1],"%zu",&packed_size);
66
+ if( packed_size < 1 || packed_size > 0x10000000 ){ // 256 Mb max
67
+ fprintf(stderr, "invalid packed_size: %zu\n", packed_size);
68
+ return 1;
69
+ }
70
+
71
+ sscanf(argv[2],"%zu",&unpacked_size);
72
+ if( unpacked_size < 1 || unpacked_size > 0x10000000 ){ // 256 Mb max
73
+ fprintf(stderr, "invalid unpacked_size: %zu\n", unpacked_size);
74
+ return 1;
75
+ }
76
+
77
+ /* alloc buffer */
78
+ if ( NULL == (packed_data = calloc(1, packed_size + 300)) ){
79
+ perror("no mem");
80
+ return(ERR_NO_MEM);
81
+ }
82
+
83
+ if( packed_size != fread(packed_data, 1, packed_size, stdin)){
84
+ free(packed_data);
85
+ perror("read");
86
+ return(ERR_NO_FILE);
87
+ }
88
+
89
+ r = unpack(packed_data, packed_size, unpacked_size);
90
+ free(packed_data);
91
+ return r;
92
+ }
@@ -0,0 +1,479 @@
1
+ //#include <windows.h>
2
+
3
+ typedef unsigned char BYTE;
4
+ typedef int INT;
5
+ typedef unsigned int UINT;
6
+ typedef unsigned long DWORD;
7
+ typedef int BOOL;
8
+
9
+ #define FALSE 0
10
+ #define TRUE 1
11
+
12
+ #include "lzxdec.h"
13
+
14
+ /* #define LZX_DEBUG_LOG */
15
+
16
+ #if defined _DEBUG && defined LZX_DEBUG_LOG
17
+ # include <stdio.h>
18
+ static FILE* FDebLog = NULL;
19
+ #endif
20
+
21
+ /* ##### *** COMMON FUNCTIONS *** ########################################## */
22
+
23
+ /* memset local redefinition */
24
+ static void lzx_memset(void* dst, int val, unsigned int count)
25
+ {
26
+ while( count-- )
27
+ {
28
+ *(char*)(dst) = val;
29
+ dst = (char*)(dst) + 1;
30
+ }
31
+ }
32
+
33
+ /* memcpy local redefinition */
34
+ static void lzx_memcpy(void* dst, void* src, unsigned int count)
35
+ {
36
+ while( count-- )
37
+ {
38
+ *(char*)(dst) = *(char*)(src);
39
+ dst = (char*)(dst) + 1;
40
+ src = (char*)(src) + 1;
41
+ }
42
+ }
43
+
44
+ /* ##### *** BIT READER FUNCTIONS *** ###################################### */
45
+
46
+ /* init bit reader */
47
+ #define BITRDR_INIT(BitRdr, RawSrc, RawLen) { \
48
+ (BitRdr)->SrcData = (RawSrc); \
49
+ (BitRdr)->SrcSize = (RawLen); \
50
+ (BitRdr)->CurOffs = 0; \
51
+ (BitRdr)->BitBuff = 0; \
52
+ (BitRdr)->BitFree = 32; \
53
+ }
54
+
55
+ /* read input byte (can be rewritten for file io) */
56
+ #define BITRDR_GETBYTE(BitRdr, RetVal) { \
57
+ if ( (BitRdr)->CurOffs < (BitRdr)->SrcSize ) \
58
+ RetVal = (BitRdr)->SrcData[(BitRdr)->CurOffs++]; \
59
+ else \
60
+ return(-1); /* error */ \
61
+ }
62
+
63
+ /* remove number of bits from bit buffer */
64
+ #define BITRDR_DROPBITS(BitRdr, BitNum) { \
65
+ (BitRdr)->BitFree += (BitNum); \
66
+ }
67
+
68
+ /* extract integer from bit buffer */
69
+ #define BITRDR_GETINT(BitRdr, RetVal) { \
70
+ DWORD BitBuff = (BitRdr)->BitBuff; \
71
+ UINT BitFree = (BitRdr)->BitFree; \
72
+ UINT UVal; \
73
+ while( BitFree >= 8 ) { \
74
+ BITRDR_GETBYTE(BitRdr, UVal); \
75
+ BitBuff = (BitBuff << 8) | UVal; \
76
+ BitFree -= 8; \
77
+ } \
78
+ RetVal = (BitBuff >> (8 - BitFree)) & 0x00ffffff; \
79
+ (BitRdr)->BitFree = BitFree; \
80
+ (BitRdr)->BitBuff = BitBuff; \
81
+ }
82
+
83
+ /* read number of bits from bit buffer */
84
+ #define BITRDR_GETBITS(BitRdr, BitNum, RetVal) { \
85
+ DWORD BitBuff = (BitRdr)->BitBuff; \
86
+ UINT BitFree = (BitRdr)->BitFree; \
87
+ UINT UVal; \
88
+ while( BitFree >= 8 ) { \
89
+ BITRDR_GETBYTE(BitRdr, UVal); \
90
+ BitBuff = (BitBuff << 8) | UVal; \
91
+ BitFree -= 8; \
92
+ } \
93
+ RetVal = (BitBuff >> (8 - BitFree)); \
94
+ RetVal = (RetVal & 0x00ffffff) >> (24 - (BitNum)); \
95
+ (BitRdr)->BitFree = (BitFree + (BitNum)); \
96
+ (BitRdr)->BitBuff = BitBuff; \
97
+ }
98
+
99
+ /* ##### *** SLIDING WINDOW DICTIONARY FUNCTIONS *** ####################### */
100
+
101
+ /* init swd context */
102
+ #define SWD_INIT(Wnd, Mem, Len) { \
103
+ (Wnd)->Window = (Mem); \
104
+ (Wnd)->WndLen = (Len); \
105
+ (Wnd)->CurOfs = 0; \
106
+ }
107
+
108
+ /* put byte to dictionary */
109
+ #define SWD_PUTBYTE(Wnd, DVal) { \
110
+ if ( (Wnd)->CurOfs < (Wnd)->WndLen ) \
111
+ (Wnd)->Window[(Wnd)->CurOfs++] = (BYTE)(DVal); \
112
+ else \
113
+ return(-1); /* error */ \
114
+ }
115
+
116
+ /* copy lz phrase in window */
117
+ #define SWD_DELTACOPY(Wnd, DOfs, DLen) { \
118
+ BYTE* WndPtr; \
119
+ if ( (Wnd)->CurOfs < (DOfs) ) \
120
+ return(-1); /* error */ \
121
+ if ( (Wnd)->CurOfs + (DLen) > (Wnd)->WndLen ) \
122
+ return(-1); /* error */ \
123
+ WndPtr = (Wnd)->Window + (Wnd)->CurOfs; \
124
+ lzx_memcpy(WndPtr, WndPtr - (DOfs), (DLen)); \
125
+ (Wnd)->CurOfs += (DLen); \
126
+ }
127
+
128
+ /* ##### *** HUFFMAN DECODERS FUNCTIONS *** ################################ */
129
+
130
+ /* init huffman decoder, return next table address */
131
+ static BYTE* LzxHuf_Init(LZX_HUFF* Huf, LZX_BITRDR* BitRdr, UINT SymNum,
132
+ BYTE* HufTbl)
133
+ {
134
+ Huf->BitRdr = BitRdr;
135
+ Huf->SymNum = SymNum;
136
+ Huf->Symbol = (UINT*)(HufTbl);
137
+ HufTbl += (SymNum * sizeof(Huf->Symbol[0]));
138
+ Huf->Length = HufTbl;
139
+ HufTbl += (256 * sizeof(Huf->Length[0]));
140
+ return(HufTbl);
141
+ }
142
+
143
+ /* decode one huffman symbol */
144
+ static INT LzxHuf_DecodeSymbol(LZX_HUFF* Huf)
145
+ {
146
+ UINT HVal, BNum, IOfs;
147
+
148
+ BITRDR_GETINT(Huf->BitRdr, HVal);
149
+ HVal &= 0x00fffe00;
150
+
151
+ if ( HVal < Huf->SymLim[8] )
152
+ BNum = Huf->Length[HVal >> 16];
153
+ else if ( HVal < Huf->SymLim[10] )
154
+ BNum = (HVal < Huf->SymLim[9]) ? (9) : (10);
155
+ else if ( HVal < Huf->SymLim[11] )
156
+ BNum = 11;
157
+ else if ( HVal < Huf->SymLim[12] )
158
+ BNum = 12;
159
+ else if ( HVal < Huf->SymLim[13] )
160
+ BNum = 13;
161
+ else
162
+ BNum = (HVal < Huf->SymLim[14]) ? (14) : (15);
163
+
164
+ BITRDR_DROPBITS(Huf->BitRdr, BNum);
165
+ IOfs = (HVal - Huf->SymLim[BNum-1]) >> (24 - BNum);
166
+ return(Huf->Symbol[Huf->SymIdx[BNum] + IOfs]);
167
+ }
168
+
169
+ /* construct huffman tables */
170
+ static INT LzxHuf_HufTblBuild(LZX_HUFF* Huf, BYTE* CodeLen)
171
+ {
172
+ UINT LenCnt[16];
173
+ UINT CurIdx[16];
174
+ UINT SymIdx, I;
175
+ UINT Lim, Idx;
176
+ UINT Ofs;
177
+
178
+ for ( I = 0; I < 16; I++ )
179
+ LenCnt[I] = 0;
180
+ for ( SymIdx = 0; SymIdx < Huf->SymNum; SymIdx++ )
181
+ LenCnt[CodeLen[SymIdx]]++;
182
+
183
+ #ifdef LZX_DEBUG_LOG
184
+ if ( NULL == FDebLog )
185
+ FDebLog = fopen("lzxdeb.log", "wt");
186
+ #endif
187
+
188
+ LenCnt[0] = 0;
189
+ CurIdx[0] = 0;
190
+ Huf->SymIdx[0] = 0;
191
+ Huf->SymLim[0] = 0;
192
+ Lim = 0;
193
+ Idx = 0;
194
+
195
+ for ( I = 1; I < 16; I++ )
196
+ {
197
+ Lim += (LenCnt[I] << (24 - I));
198
+ if ( Lim > 0x1000000 )
199
+ return(-1); /* overrun */
200
+
201
+ Huf->SymLim[I] = Lim;
202
+ Huf->SymIdx[I] = Huf->SymIdx[I-1] + LenCnt[I-1];
203
+ CurIdx[I] = Huf->SymIdx[I];
204
+
205
+ if ( I <= 8 )
206
+ {
207
+ Ofs = (Huf->SymLim[I] >> 16);
208
+ lzx_memset(&Huf->Length[Idx], I, Ofs - Idx);
209
+ Idx = Ofs;
210
+ }
211
+ }
212
+
213
+ if ( Lim != 0x1000000 )
214
+ return(-1); /* not full set */
215
+
216
+ #ifdef LZX_DEBUG_LOG
217
+ fprintf(FDebLog, "Huf->SymNum == %u\n", Huf->SymNum);
218
+ fprintf(FDebLog, "Huf->SymIdx == ");
219
+ for ( I = 0; I < 16; I++ )
220
+ fprintf(FDebLog, "%u ", Huf->SymIdx[I]);
221
+ fprintf(FDebLog, "\n");
222
+ fprintf(FDebLog, "Huf->SymLim == ");
223
+ for ( I = 0; I < 16; I++ )
224
+ fprintf(FDebLog, "%u ", Huf->SymLim[I]);
225
+ fprintf(FDebLog, "\n");
226
+ fflush(FDebLog);
227
+ #endif
228
+
229
+ for ( SymIdx = 0; SymIdx < Huf->SymNum; SymIdx++ )
230
+ {
231
+ if ( CodeLen[SymIdx] )
232
+ {
233
+ #ifdef LZX_DEBUG_LOG
234
+ fprintf(FDebLog, "%u\n", SymIdx);
235
+ fflush(FDebLog);
236
+ #endif
237
+ Huf->Symbol[CurIdx[CodeLen[SymIdx]]++] = SymIdx;
238
+ }
239
+ }
240
+
241
+ return(0); /* all ok */
242
+ }
243
+
244
+ /* ##### *** LZX DECODER FUNCTIONS *** ##################################### */
245
+
246
+ /* basic lzx tables */
247
+ static const UINT LzxTblLenBits[28] = {
248
+ 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4,
249
+ 5, 5, 5, 5
250
+ };
251
+ static const UINT LzxTblLenBase[28] = {
252
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32,
253
+ 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224
254
+ };
255
+ static const UINT LzxTblOfsBits[58] = {
256
+ 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7,
257
+ 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16,
258
+ 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18,
259
+ 18, 18, 18, 18
260
+ };
261
+ static const UINT LzxTblOfsBase[58] = {
262
+ 0x00000000, 0x00000001, 0x00000002, 0x00000003, 0x00000004, 0x00000006,
263
+ 0x00000008, 0x0000000C, 0x00000010, 0x00000018, 0x00000020, 0x00000030,
264
+ 0x00000040, 0x00000060, 0x00000080, 0x000000C0, 0x00000100, 0x00000180,
265
+ 0x00000200, 0x00000300, 0x00000400, 0x00000600, 0x00000800, 0x00000C00,
266
+ 0x00001000, 0x00001800, 0x00002000, 0x00003000, 0x00004000, 0x00006000,
267
+ 0x00008000, 0x0000C000, 0x00010000, 0x00018000, 0x00020000, 0x00030000,
268
+ 0x00040000, 0x00060000, 0x00080000, 0x000A0000, 0x000C0000, 0x000E0000,
269
+ 0x00100000, 0x00120000, 0x00140000, 0x00160000, 0x00180000, 0x001A0000,
270
+ 0x001C0000, 0x001E0000, 0x00200000, 0x00240000, 0x00280000, 0x002C0000,
271
+ 0x00300000, 0x00340000, 0x00380000, 0x003C0000
272
+ };
273
+
274
+ /* ------------------------------------------------------------------------- */
275
+
276
+ /* build lzx tables */
277
+ static INT Lzx_LzxTblBuild(LZX_CONTEXT* Ctx)
278
+ {
279
+ BYTE* Heap;
280
+ BYTE LenTbl[19];
281
+ BYTE HufSym[757];
282
+ UINT Val, I, Sym;
283
+ INT ISym;
284
+
285
+ Heap = Ctx->LstMem;
286
+ BITRDR_GETBITS(&Ctx->BitRdr, 1, Val);
287
+ if ( !Val ) lzx_memset(Heap, 0, 757);
288
+
289
+ for ( I = 0; I < 19; I++ )
290
+ {
291
+ BITRDR_GETBITS(&Ctx->BitRdr, 4, Val);
292
+ LenTbl[I] = (BYTE)(Val);
293
+ }
294
+
295
+ if ( LzxHuf_HufTblBuild(&Ctx->HufSpec, LenTbl) )
296
+ return(-1); /* error */
297
+
298
+ I = 0;
299
+ while ( I < 757 )
300
+ {
301
+ if ( (ISym = LzxHuf_DecodeSymbol(&Ctx->HufSpec)) == -1 )
302
+ return(-1); /* error */
303
+
304
+ if ( (Sym = (UINT)(ISym)) < 16 )
305
+ {
306
+ HufSym[I] = (BYTE)((Heap[I] + Sym) & 15); I++;
307
+ continue;
308
+ }
309
+
310
+ if ( Sym == 16 )
311
+ {
312
+ BITRDR_GETBITS(&Ctx->BitRdr, 2, Val); Val += 3;
313
+ while ( Val > 0 && I < 757 )
314
+ {
315
+ HufSym[I] = HufSym[I-1];
316
+ Val--; I++;
317
+ }
318
+ continue;
319
+ }
320
+
321
+ if ( Sym == 17 )
322
+ {
323
+ BITRDR_GETBITS(&Ctx->BitRdr, 3, Val);
324
+ Val += 3;
325
+ }
326
+ else
327
+ {
328
+ BITRDR_GETBITS(&Ctx->BitRdr, 7, Val);
329
+ Val += 11;
330
+ }
331
+
332
+ while ( Val > 0 && I < 757 )
333
+ {
334
+ HufSym[I] = 0;
335
+ Val--; I++;
336
+ }
337
+ }
338
+
339
+ if ( LzxHuf_HufTblBuild(&Ctx->HufBase, &HufSym[0]) )
340
+ return(-1);
341
+ if ( LzxHuf_HufTblBuild(&Ctx->HufLens, &HufSym[721]) )
342
+ return(-1);
343
+ if ( LzxHuf_HufTblBuild(&Ctx->HufOffs, &HufSym[749]) )
344
+ return(-1);
345
+
346
+ Ctx->HasOffs = FALSE;
347
+ for ( I = 0; I < 8; I++ )
348
+ {
349
+ if ( HufSym[749+I] != 3 )
350
+ {
351
+ Ctx->HasOffs = TRUE;
352
+ break;
353
+ }
354
+ }
355
+
356
+ lzx_memcpy(Heap, &HufSym[0], 757);
357
+ return(0); /* all ok */
358
+ }
359
+
360
+ /* ------------------------------------------------------------------------- */
361
+
362
+ INT DecodeLZX(LZX_CONTEXT* Ctx, BYTE* Src, BYTE* Dst, UINT PSize, UINT USize)
363
+ {
364
+ UINT Written;
365
+ UINT Symbol;
366
+ BYTE* HufMem;
367
+ UINT Ofs;
368
+ UINT Len;
369
+ UINT Num;
370
+ UINT Val;
371
+ INT ISym;
372
+
373
+ /* check params */
374
+ if ( !Ctx || !Src || !Dst || !USize )
375
+ return(-1); /* invalid param */
376
+
377
+ /* init lzx context */
378
+ BITRDR_INIT(&Ctx->BitRdr, Src, PSize);
379
+ SWD_INIT(&Ctx->Window, Dst, USize);
380
+ Ctx->HasOffs = FALSE;
381
+ Ctx->LstOfs[0] = 0;
382
+ Ctx->LstOfs[1] = 0;
383
+ Ctx->LstOfs[2] = 0;
384
+
385
+ /* init huffman coders */
386
+ HufMem = &Ctx->HufTbl[0];
387
+ HufMem = LzxHuf_Init(&Ctx->HufBase, &Ctx->BitRdr, 721, HufMem);
388
+ HufMem = LzxHuf_Init(&Ctx->HufLens, &Ctx->BitRdr, 28, HufMem);
389
+ HufMem = LzxHuf_Init(&Ctx->HufOffs, &Ctx->BitRdr, 8, HufMem);
390
+ HufMem = LzxHuf_Init(&Ctx->HufSpec, &Ctx->BitRdr, 19, HufMem);
391
+ lzx_memset(Ctx->LstMem = HufMem, 0, 757);
392
+
393
+ /* build lzx tables */
394
+ if ( Lzx_LzxTblBuild(Ctx) )
395
+ return(-1);
396
+
397
+ /* decode */
398
+ Written = 0;
399
+ while ( Written < USize )
400
+ {
401
+ if ( (ISym = LzxHuf_DecodeSymbol(&Ctx->HufBase)) == -1 )
402
+ return(-1);
403
+
404
+ if ( (Symbol = (UINT)(ISym)) < 256 )
405
+ {
406
+ /* literal */
407
+ SWD_PUTBYTE(&Ctx->Window, Symbol);
408
+ Written++;
409
+ continue;
410
+ }
411
+
412
+ if ( Symbol < 720 )
413
+ {
414
+ /* phrase */
415
+ Symbol -= 256;
416
+ Ofs = (Symbol >> 3);
417
+ Len = (Symbol & 7) + 2;
418
+
419
+ if ( Len == 9 )
420
+ {
421
+ if ( (ISym = LzxHuf_DecodeSymbol(&Ctx->HufLens)) == -1 )
422
+ return(-1);
423
+
424
+ Symbol = (UINT)(ISym);
425
+ Num = LzxTblLenBits[Symbol];
426
+ BITRDR_GETBITS(&Ctx->BitRdr, Num, Val);
427
+ Len += (Val + LzxTblLenBase[Symbol]);
428
+ }
429
+
430
+ Num = LzxTblOfsBits[Ofs];
431
+ Ofs = LzxTblOfsBase[Ofs];
432
+
433
+ if ( Num < 3 || !Ctx->HasOffs )
434
+ {
435
+ BITRDR_GETBITS(&Ctx->BitRdr, Num, Val);
436
+ Ofs += Val;
437
+ }
438
+ else
439
+ {
440
+ Num -= 3;
441
+ BITRDR_GETBITS(&Ctx->BitRdr, Num, Val);
442
+ if ( (ISym = LzxHuf_DecodeSymbol(&Ctx->HufOffs)) == -1 )
443
+ return(-1);
444
+ Ofs += ((UINT)(ISym) + (Val << 3));
445
+ }
446
+
447
+ if ( Ofs < 3 )
448
+ {
449
+ /* use saved last offset */
450
+ Ofs = Ctx->LstOfs[Num = Ofs];
451
+ if ( Num )
452
+ {
453
+ Ctx->LstOfs[Num] = Ctx->LstOfs[0];
454
+ Ctx->LstOfs[0] = Ofs;
455
+ }
456
+ }
457
+ else
458
+ {
459
+ /* update last offset */
460
+ Ctx->LstOfs[2] = Ctx->LstOfs[1];
461
+ Ctx->LstOfs[1] = Ctx->LstOfs[0];
462
+ Ctx->LstOfs[0] = (Ofs -= 3);
463
+ }
464
+
465
+ /* copy phrase */
466
+ SWD_DELTACOPY(&Ctx->Window, Ofs+1, Len);
467
+ Written += Len;
468
+ continue;
469
+ }
470
+
471
+ /* update trees */
472
+ if ( Lzx_LzxTblBuild(Ctx) )
473
+ return(-1);
474
+ }
475
+
476
+ return(Written); /* all ok */
477
+ }
478
+
479
+ /* ------------------------------------------------------------------------- */