pedump 0.5.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -0,0 +1,10 @@
1
+ class PEdump
2
+ module Version
3
+ MAJOR = 0
4
+ MINOR = 5
5
+ PATCH = 2
6
+ BUILD = nil
7
+
8
+ STRING = [MAJOR, MINOR, PATCH, BUILD].compact.join('.')
9
+ end
10
+ end
@@ -0,0 +1,171 @@
1
+ class PEdump
2
+ class VS_VERSIONINFO < IOStruct.new( 'v3a32v',
3
+ :wLength,
4
+ :wValueLength,
5
+ :wType,
6
+ :szKey, # The Unicode string L"VS_VERSION_INFO".
7
+ :Padding1,
8
+ # manual:
9
+ :Value, # VS_FIXEDFILEINFO
10
+ :Padding2,
11
+ :Children
12
+ )
13
+ def self.read f, size = SIZE
14
+ super.tap do |vi|
15
+ vi.szKey.force_encoding('UTF-16LE').encode!('UTF-8').sub!(/\u0000$/,'') rescue nil
16
+ vi.Padding1 = f.tell%4 > 0 ? f.read(4 - f.tell%4) : nil
17
+ vi.Value = VS_FIXEDFILEINFO.read(f,vi.wValueLength)
18
+ # As many zero words as necessary to align the Children member on a 32-bit boundary.
19
+ # These bytes are not included in wValueLength. This member is optional.
20
+ vi.Padding2 = f.tell%4 > 0 ? f.read(4 - f.tell%4) : nil
21
+ vi.Children = [] # An array of zero or one StringFileInfo structures,
22
+ # and zero or one VarFileInfo structures
23
+
24
+ 2.times do
25
+ pos = f.tell
26
+ f.seek(pos+6) # seek 6 bytes forward
27
+ t = f.read(6)
28
+ f.seek(pos) # return back
29
+ case t
30
+ when "V\x00a\x00r\x00"
31
+ vi.Children << VarFileInfo.read(f)
32
+ when "S\x00t\x00r\x00"
33
+ vi.Children << StringFileInfo.read(f)
34
+ else
35
+ PEdump.logger.warn "[?] invalid VS_VERSIONINFO child type #{t.inspect}"
36
+ break
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+
43
+ class VS_FIXEDFILEINFO < IOStruct.new( 'V13',
44
+ :dwSignature,
45
+ :dwStrucVersion,
46
+ :dwFileVersionMS,
47
+ :dwFileVersionLS,
48
+ :dwProductVersionMS,
49
+ :dwProductVersionLS,
50
+ :dwFileFlagsMask,
51
+ :dwFileFlags,
52
+ :dwFileOS,
53
+ :dwFileType,
54
+ :dwFileSubtype,
55
+ :dwFileDateMS,
56
+ :dwFileDateLS,
57
+ # manual:
58
+ :valid
59
+ )
60
+ def self.read f, size = SIZE
61
+ super.tap do |ffi|
62
+ ffi.valid = (ffi.dwSignature == 0xFEEF04BD)
63
+ end
64
+ end
65
+ end
66
+
67
+ class StringFileInfo < IOStruct.new( 'v3a30',
68
+ :wLength,
69
+ :wValueLength, # always 0
70
+ :wType, # 1 => text data, 0 => binary data
71
+ :szKey, # The Unicode string L"StringFileInfo"
72
+ :Padding, # As many zero words as necessary to align the Children member on a 32-bit boundary
73
+ :Children # An array of one or more StringTable structures
74
+ )
75
+ def self.read f, size = SIZE
76
+ pos0 = f.tell
77
+ super.tap do |x|
78
+ x.szKey.force_encoding('UTF-16LE').encode!('UTF-8').sub!(/\u0000$/,'') rescue nil
79
+ x.Padding = f.tell%4 > 0 ? f.read(4 - f.tell%4) : nil
80
+ x.Children = []
81
+ while !f.eof? && f.tell < pos0+x.wLength
82
+ x.Children << StringTable.read(f)
83
+ end
84
+ end
85
+ end
86
+ end
87
+
88
+ class StringTable < IOStruct.new( 'v3a16v',
89
+ :wLength, # The length, in bytes, of this StringTable structure,
90
+ # including all structures indicated by the Children member.
91
+ :wValueLength, # always 0
92
+ :wType, # 1 => text data, 0 => binary data
93
+ :szKey, # An 8-digit hexadecimal number stored as a Unicode string
94
+ :Padding, # As many zero words as necessary to align the Children member on a 32-bit boundary
95
+ :Children # An array of one or more String structures.
96
+ )
97
+ def self.read f, size = SIZE
98
+ pos0 = f.tell
99
+ super.tap do |x|
100
+ x.szKey.force_encoding('UTF-16LE').encode!('UTF-8').sub!(/\u0000$/,'') rescue nil
101
+ x.Padding = f.tell%4 > 0 ? f.read(4 - f.tell%4) : nil
102
+ x.Children = []
103
+ while !f.eof? && f.tell < pos0+x.wLength
104
+ x.Children << VersionString.read(f)
105
+ end
106
+ end
107
+ end
108
+ end
109
+
110
+ class VersionString < IOStruct.new( 'v3',
111
+ :wLength, # The length, in bytes, of this String structure.
112
+ :wValueLength, # The size, in words, of the Value member
113
+ :wType, # 1 => text data, 0 => binary data
114
+ :szKey, # An arbitrary Unicode string
115
+ :Padding, # As many zero words as necessary to align the Value member on a 32-bit boundary
116
+ :Value # A zero-terminated string. See the szKey member description for more information
117
+ )
118
+ def self.read f, size = SIZE
119
+ pos = f.tell
120
+ super.tap do |x|
121
+ x.szKey = ''
122
+ x.szKey << f.read(2) until x.szKey[-2..-1] == "\x00\x00" || f.eof?
123
+ x.Padding = f.tell%4 > 0 ? f.read(4 - f.tell%4) : nil
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)
129
+ if f.tell%4 > 0
130
+ f.read(4-f.tell%4) # undoc padding?
131
+ end
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
134
+ end
135
+ end
136
+ end
137
+
138
+ class VarFileInfo < IOStruct.new( 'v3a24v',
139
+ :wLength,
140
+ :wValueLength, # always 0
141
+ :wType, # 1 => text data, 0 => binary data
142
+ :szKey, # The Unicode string L"VarFileInfo"
143
+ :Padding, # As many zero words as necessary to align the Children member on a 32-bit boundary
144
+ :Children # Typically contains a list of languages that the application or DLL supports
145
+ )
146
+ def self.read f, size = SIZE
147
+ super.tap do |x|
148
+ x.szKey.force_encoding('UTF-16LE').encode!('UTF-8').sub!(/\u0000$/,'') rescue nil
149
+ x.Padding = f.tell%4 > 0 ? f.read(4 - f.tell%4) : nil
150
+ x.Children = Var.read(f)
151
+ end
152
+ end
153
+ end
154
+
155
+ class Var < IOStruct.new( 'v3a24',
156
+ :wLength,
157
+ :wValueLength, # The length, in bytes, of the Value member
158
+ :wType, # 1 => text data, 0 => binary data
159
+ :szKey, # The Unicode string L"Translation"
160
+ :Padding, # As many zero words as necessary to align the Children member on a 32-bit boundary
161
+ :Value # An array of one or more values that are language and code page identifier pairs
162
+ )
163
+ def self.read f, size = SIZE
164
+ super.tap do |x|
165
+ x.szKey.force_encoding('UTF-16LE').encode!('UTF-8').sub!(/\u0000$/,'') rescue nil
166
+ x.Padding = f.tell%4 > 0 ? f.read(4 - f.tell%4) : nil
167
+ x.Value = f.read(x.wValueLength).unpack('v*')
168
+ end
169
+ end
170
+ end
171
+ 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
+ /* ------------------------------------------------------------------------- */