Browse code

formatting commit only.

Micah Snyder authored on 2017/08/31 02:50:00
Showing 1 changed files
... ...
@@ -1,5 +1,5 @@
1 1
 /*
2
- *  Copyright (C) 2015 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
2
+ *  Copyright (C) 2015, 2017 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
3 3
  *  Copyright (C) 2007-2008 Sourcefire, Inc.
4 4
  *
5 5
  *  Authors: Alberto Wu
... ...
@@ -35,7 +35,6 @@
35 35
 ** [ A big fat thank to christoph for not letting me give up ]
36 36
 */
37 37
 
38
-
39 38
 /*
40 39
 ** TODO ( a fat one ):
41 40
 **
... ...
@@ -48,7 +47,6 @@
48 48
 **
49 49
 */
50 50
 
51
-
52 51
 #if HAVE_CONFIG_H
53 52
 #include "clamav-config.h"
54 53
 #endif
... ...
@@ -65,451 +63,521 @@
65 65
 #include "packlibs.h"
66 66
 #include "spin.h"
67 67
 
68
-
69
-static char exec86(uint8_t aelle, uint8_t cielle, char *curremu, int *retval) {
70
-  int len = 0;
71
-  *retval=0;
72
-  while (len <0x24) {
73
-    uint8_t opcode = curremu[len], support;
74
-    len++;
75
-    switch (opcode) {
76
-      case 0xeb:
77
-        len++;
78
-      case 0x0a:
79
-        len++;
80
-      case 0x90:
81
-      case 0xf8:
82
-      case 0xf9:
83
-        break;
84
-
85
-      case 0x02: /* add al, cl */
86
-        aelle+=cielle;
87
-	len++;
88
-        break;
89
-      case 0x2a: /* sub al, cl */
90
-        aelle-=cielle;
91
-	len++;
92
-        break;
93
-      case 0x04: /* add al, ?? */
94
-        aelle+=curremu[len];
95
-	len++;
96
-        break;
97
-      case 0x2c: /* sub al, ?? */
98
-        aelle-=curremu[len];
99
-	len++;
100
-        break;
101
-      case 0x32: /* xor al, cl */
102
-        aelle^=cielle;
103
-	len++;
104
-        break;
105
-      case 0x34: /* xor al, ?? */
106
-        aelle^=curremu[len];
107
-	len++;
108
-        break;
109
-
110
-      case 0xfe: /* inc/dec al */
111
-        if ( curremu[len] == '\xc0' ) aelle++;
112
-	else aelle--;
113
-        len++;
114
-        break;
115
-
116
-      case 0xc0: /* ror/rol al, ?? */
117
-	support = curremu[len];
118
-        len++;
119
-        if ( support == 0xc0 ) CLI_ROL(aelle, curremu[len]);
120
-        else CLI_ROR(aelle, curremu[len]);
68
+static char exec86(uint8_t aelle, uint8_t cielle, char *curremu, int *retval)
69
+{
70
+    int len = 0;
71
+    *retval = 0;
72
+    while (len < 0x24)
73
+    {
74
+        uint8_t opcode = curremu[len], support;
121 75
         len++;
122
-        break;
123
-
124
-      default:
125
-        cli_dbgmsg("spin: bogus opcode %x\n", opcode);
126
-	*retval=1;
127
-	return aelle;
76
+        switch (opcode)
77
+        {
78
+        case 0xeb:
79
+            len++;
80
+        case 0x0a:
81
+            len++;
82
+        case 0x90:
83
+        case 0xf8:
84
+        case 0xf9:
85
+            break;
86
+
87
+        case 0x02: /* add al, cl */
88
+            aelle += cielle;
89
+            len++;
90
+            break;
91
+        case 0x2a: /* sub al, cl */
92
+            aelle -= cielle;
93
+            len++;
94
+            break;
95
+        case 0x04: /* add al, ?? */
96
+            aelle += curremu[len];
97
+            len++;
98
+            break;
99
+        case 0x2c: /* sub al, ?? */
100
+            aelle -= curremu[len];
101
+            len++;
102
+            break;
103
+        case 0x32: /* xor al, cl */
104
+            aelle ^= cielle;
105
+            len++;
106
+            break;
107
+        case 0x34: /* xor al, ?? */
108
+            aelle ^= curremu[len];
109
+            len++;
110
+            break;
111
+
112
+        case 0xfe: /* inc/dec al */
113
+            if (curremu[len] == '\xc0')
114
+                aelle++;
115
+            else
116
+                aelle--;
117
+            len++;
118
+            break;
119
+
120
+        case 0xc0: /* ror/rol al, ?? */
121
+            support = curremu[len];
122
+            len++;
123
+            if (support == 0xc0)
124
+                CLI_ROL(aelle, curremu[len]);
125
+            else
126
+                CLI_ROR(aelle, curremu[len]);
127
+            len++;
128
+            break;
129
+
130
+        default:
131
+            cli_dbgmsg("spin: bogus opcode %x\n", opcode);
132
+            *retval = 1;
133
+            return aelle;
134
+        }
135
+    }
136
+    if (len != 0x24 || curremu[len] != '\xaa')
137
+    {
138
+        cli_dbgmsg("spin: bad emucode\n");
139
+        *retval = 1;
128 140
     }
129
-  }
130
-  if ( len!=0x24 || curremu[len]!='\xaa' ) {
131
-    cli_dbgmsg("spin: bad emucode\n");
132
-    *retval=1;
133
-  }
134
-  return aelle;
141
+    return aelle;
135 142
 }
136 143
 
137
-
138
-static uint32_t summit (char *src, int size) 
144
+static uint32_t summit(char *src, int size)
139 145
 {
140
-  uint32_t eax=0xffffffff, ebx=0xffffffff;
141
-  int i;
142
-
143
-  while(size) {
144
-    eax ^= *src++<<8 & 0xff00;
145
-    eax = eax>>3 & 0x1fffffff;
146
-    for (i=0; i<4; i++) {
147
-      uint32_t swap;
148
-      eax ^= ebx>>8 & 0xff;
149
-      eax += 0x7801a108;
150
-      eax ^= ebx;
151
-      CLI_ROR(eax, ebx&0xff);
152
-      swap = eax;
153
-      eax = ebx;
154
-      ebx = swap;
146
+    uint32_t eax = 0xffffffff, ebx = 0xffffffff;
147
+    int i;
148
+
149
+    while (size)
150
+    {
151
+        eax ^= *src++ << 8 & 0xff00;
152
+        eax = eax >> 3 & 0x1fffffff;
153
+        for (i = 0; i < 4; i++)
154
+        {
155
+            uint32_t swap;
156
+            eax ^= ebx >> 8 & 0xff;
157
+            eax += 0x7801a108;
158
+            eax ^= ebx;
159
+            CLI_ROR(eax, ebx & 0xff);
160
+            swap = eax;
161
+            eax = ebx;
162
+            ebx = swap;
163
+        }
164
+        size--;
155 165
     }
156
-    size--; 
157
-  }
158
-  return ebx;
166
+    return ebx;
159 167
 }
160 168
 
169
+int unspin(char *src, int ssize, struct cli_exe_section *sections, int sectcnt, uint32_t nep, int desc, cli_ctx *ctx)
170
+{
171
+    char *curr, *emu, *ep, *spinned;
172
+    char **sects;
173
+    int blobsz = 0, j;
174
+    uint32_t key32, bitmap, bitman;
175
+    uint32_t len;
176
+    uint8_t key8;
177
+
178
+    cli_dbgmsg("in unspin\n");
179
+
180
+    if ((spinned = (char *)cli_malloc(sections[sectcnt].rsz)) == NULL)
181
+    {
182
+        cli_dbgmsg("spin: Unable to allocate memory for spinned\n");
183
+        return 1;
184
+    }
161 185
 
162
-int unspin(char *src, int ssize, struct cli_exe_section *sections, int sectcnt, uint32_t nep, int desc, cli_ctx *ctx) {
163
-  char *curr, *emu, *ep, *spinned;
164
-  char **sects;
165
-  int blobsz=0, j;
166
-  uint32_t key32, bitmap, bitman;
167
-  uint32_t len;
168
-  uint8_t key8;
169
-
170
-  cli_dbgmsg("in unspin\n");
171
-
172
-  if ((spinned = (char *) cli_malloc(sections[sectcnt].rsz)) == NULL ) {
173
-      cli_dbgmsg("spin: Unable to allocate memory for spinned\n");
174
-    return 1;
175
-  }
176
-
177
-  memcpy(spinned, src + sections[sectcnt].raw, sections[sectcnt].rsz); 
178
-  ep = spinned + nep - sections[sectcnt].rva;
179
-
180
-  curr = ep+0xdb;
181
-  if ( *curr != '\xbb' ) {
182
-    free(spinned);
183
-    cli_dbgmsg("spin: Not spinned or bad version\n");
184
-    return 1;
185
-  }
186
-  
187
-  key8 = (uint8_t)*++curr;
188
-  curr+=4;
189
-  if ( *curr != '\xb9' ) {
190
-    free(spinned);
191
-    cli_dbgmsg("spin: Not spinned or bad version\n");
192
-    return 1;
193
-  }
194
-
195
-  if ( (len = cli_readint32(curr+1)) != 0x11fe ) {
196
-    free(spinned);
197
-    cli_dbgmsg("spin: Not spinned or bad version\n");
198
-    return 1;
199
-  }
200
-
201
-  cli_dbgmsg("spin: Key8 is %x, Len is %x\n", key8, len);
202
-
203
-  if (!CLI_ISCONTAINED(spinned, sections[sectcnt].rsz, ep, len+0x1fe5-1)) {
204
-    free(spinned);
205
-    cli_dbgmsg("spin: len out of bounds, giving up\n");
206
-    return 1;
207
-  }
208
-
209
-  if ( ep[0x1e0]!='\xb8' )
210
-    cli_dbgmsg("spin: prolly not spinned, expect failure\n");
211
-  
212
-  if ( (cli_readint32(ep+0x1e1) & 0x00200000) )
213
-    cli_dbgmsg("spin: password protected, expect failure\n");
214
-
215
-  curr = ep+0x1fe5+len-1;
216
-  while ( len-- ) {
217
-    *curr=(*curr)^(key8--);
218
-    curr--;
219
-  }
220
-
221
-  if (!CLI_ISCONTAINED(spinned, sections[sectcnt].rsz, ep+0x3217, 4)) {
222
-    free(spinned);
223
-    cli_dbgmsg("spin: key out of bounds, giving up\n");
224
-    return 1;
225
-  }
226
-
227
-  curr = ep+0x26eb;
228
-  key32 = cli_readint32(curr);
229
-  if ( (len = cli_readint32(curr+5)) != 0x5a0) {
230
-    free(spinned);
231
-    cli_dbgmsg("spin: Not spinned or bad version\n");
232
-    return 1;
233
-  }
234
-
235
-  curr = ep+0x2d5;
236
-  cli_dbgmsg("spin: Key is %x, Len is %x\n", key32, len);
237
-
238
-  while ( len-- ) {
239
-    if ( key32 & 1 ) {
240
-      key32 = key32>>1;
241
-      key32 ^= 0x8c328834;
242
-    } else {
243
-      key32 = key32>>1;
186
+    memcpy(spinned, src + sections[sectcnt].raw, sections[sectcnt].rsz);
187
+    ep = spinned + nep - sections[sectcnt].rva;
188
+
189
+    curr = ep + 0xdb;
190
+    if (*curr != '\xbb')
191
+    {
192
+        free(spinned);
193
+        cli_dbgmsg("spin: Not spinned or bad version\n");
194
+        return 1;
244 195
     }
245
-    *curr = *curr ^ (key32 & 0xff);
246
-    curr++;
247
-  }
248
-
249
-  len = ssize - cli_readint32(ep+0x429); /* sub size, value */
250
-  if ( len >= (uint32_t)ssize ) {
251
-    free(spinned);
252
-    cli_dbgmsg("spin: crc out of bounds, giving up\n");
253
-    return 1;
254
-  }
255
-  key32 = cli_readint32(ep+0x3217) - summit(src,len);
256
-
257
-  memcpy(src + sections[sectcnt].raw, spinned, sections[sectcnt].rsz); 
258
-  free(spinned); /* done CRC'ing - can have a dirty buffer now */
259
-  ep = src + nep + sections[sectcnt].raw - sections[sectcnt].rva; /* Fix the helper */
260
-
261
-  if (!CLI_ISCONTAINED(src, ssize, ep+0x3207, 4)) { /* this one holds all ep based checks */
262
-    cli_dbgmsg("spin: key out of bounds, giving up\n");
263
-    return 1;
264
-  }
265
-  bitmap = cli_readint32(ep+0x3207);
266
-  cli_dbgmsg("spin: Key32 is %x - XORbitmap is %x\n", key32, bitmap);
267
-  
268
-  cli_dbgmsg("spin: Decrypting sects (xor)\n");
269
-  for (j=0; j<sectcnt; j++) {
270
-
271
-    if (bitmap&1) {
272
-      uint32_t size = sections[j].rsz;
273
-      char *ptr = src + sections[j].raw;
274
-      uint32_t keydup = key32;
275
-      
276
-      if (!CLI_ISCONTAINED(src, ssize, ptr, size)) {
277
-	cli_dbgmsg("spin: sect %d out of file, giving up\n", j);
278
-	return 1; /* FIXME: Already checked in pe.c? */
279
-      }
280
-
281
-      while (size--) {
282
-	if (! (keydup & 1)) {
283
-	  keydup = keydup>>1;
284
-	  keydup ^= 0xed43af31;
285
-	} else {
286
-	  keydup = keydup>>1;
287
-	}
288
-	*ptr = *ptr ^ (keydup & 0xff);
289
-	ptr++;
290
-      }
291
-    } 
292
-    bitmap = bitmap >>1;
293
-  }
294
-  
295
-  cli_dbgmsg("spin: done\n");
296
-
297
-  
298
-  curr = ep+0x644;
299
-  if ( (len = cli_readint32(curr)) != 0x180) {
300
-    cli_dbgmsg("spin: Not spinned or bad version\n");
301
-    return 1;
302
-  }
303
-
304
-  key32 = cli_readint32(curr+0x0c);
305
-  cli_dbgmsg("spin: Key is %x, Len is %x\n", key32, len);
306
-  curr = ep+0x28d3;
307
-
308
-  if (!CLI_ISCONTAINED(src, ssize, curr, len)) { /* always true but i may decide to remove the previous check */
309
-    cli_dbgmsg("spin: key out of bounds, giving up\n");
310
-    return 1;
311
-  }
312
-  while ( len-- ) {
313
-    if ( key32 & 1 ) {
314
-      key32 = key32>>1;
315
-      key32 ^= 0xed43af32;
316
-    } else {
317
-      key32 = key32>>1;
196
+
197
+    key8 = (uint8_t) * ++curr;
198
+    curr += 4;
199
+    if (*curr != '\xb9')
200
+    {
201
+        free(spinned);
202
+        cli_dbgmsg("spin: Not spinned or bad version\n");
203
+        return 1;
318 204
     }
319
-    *curr = *curr ^ (key32 & 0xff);
320
-    curr++;
321
-  }
322
-
323
-
324
-  curr = ep+0x28dd;
325
-  if ( (len = cli_readint32(curr)) != 0x1a1 ) {
326
-    cli_dbgmsg("spin: Not spinned or bad version\n");
327
-    return 1;
328
-  }
329
-
330
-  cli_dbgmsg("spin: POLY1 len is %x\n", len);
331
-  curr+=0xf; /* POLY1 */
332
-  emu = ep+0x6d4;
333
-  if (!CLI_ISCONTAINED(src, ssize, emu, len)) {
334
-    cli_dbgmsg("spin: poly1 out of bounds\n");
335
-    return 1;
336
-  }
337
-  while (len) {
338
-    int xcfailure=0;
339
-    *emu=exec86(*emu, len-- & 0xff, curr, &xcfailure); /* unlame POLY1 */
340
-    if (xcfailure) {
341
-      cli_dbgmsg("spin: cannot exec poly1\n");
342
-      return 1;
205
+
206
+    if ((len = cli_readint32(curr + 1)) != 0x11fe)
207
+    {
208
+        free(spinned);
209
+        cli_dbgmsg("spin: Not spinned or bad version\n");
210
+        return 1;
343 211
     }
344
-    emu++;
345
-  }
346 212
 
213
+    cli_dbgmsg("spin: Key8 is %x, Len is %x\n", key8, len);
347 214
 
348
-  bitmap = cli_readint32(ep+0x6f1);
349
-  cli_dbgmsg("spin: POLYbitmap is %x - decrypting sects (poly)\n", bitmap);
350
-  curr = ep+0x755;
215
+    if (!CLI_ISCONTAINED(spinned, sections[sectcnt].rsz, ep, len + 0x1fe5 - 1))
216
+    {
217
+        free(spinned);
218
+        cli_dbgmsg("spin: len out of bounds, giving up\n");
219
+        return 1;
220
+    }
351 221
 
352
-  for (j=0; j<sectcnt; j++) {
353
-    if (bitmap&1) {
354
-      uint32_t notthesamelen = sections[j].rsz;
222
+    if (ep[0x1e0] != '\xb8')
223
+        cli_dbgmsg("spin: prolly not spinned, expect failure\n");
355 224
 
356
-      emu = src + sections[j].raw;
225
+    if ((cli_readint32(ep + 0x1e1) & 0x00200000))
226
+        cli_dbgmsg("spin: password protected, expect failure\n");
357 227
 
358
-      if (!CLI_ISCONTAINED(src,ssize,curr,0x24)) { /* section bounds already checked twice now */
359
-	cli_dbgmsg("spin: poly1 emucode is out of file?\n");
360
-	return 1;
361
-      }
228
+    curr = ep + 0x1fe5 + len - 1;
229
+    while (len--)
230
+    {
231
+        *curr = (*curr) ^ (key8--);
232
+        curr--;
233
+    }
234
+
235
+    if (!CLI_ISCONTAINED(spinned, sections[sectcnt].rsz, ep + 0x3217, 4))
236
+    {
237
+        free(spinned);
238
+        cli_dbgmsg("spin: key out of bounds, giving up\n");
239
+        return 1;
240
+    }
241
+
242
+    curr = ep + 0x26eb;
243
+    key32 = cli_readint32(curr);
244
+    if ((len = cli_readint32(curr + 5)) != 0x5a0)
245
+    {
246
+        free(spinned);
247
+        cli_dbgmsg("spin: Not spinned or bad version\n");
248
+        return 1;
249
+    }
250
+
251
+    curr = ep + 0x2d5;
252
+    cli_dbgmsg("spin: Key is %x, Len is %x\n", key32, len);
253
+
254
+    while (len--)
255
+    {
256
+        if (key32 & 1)
257
+        {
258
+            key32 = key32 >> 1;
259
+            key32 ^= 0x8c328834;
260
+        }
261
+        else
262
+        {
263
+            key32 = key32 >> 1;
264
+        }
265
+        *curr = *curr ^ (key32 & 0xff);
266
+        curr++;
267
+    }
268
+
269
+    len = ssize - cli_readint32(ep + 0x429); /* sub size, value */
270
+    if (len >= (uint32_t)ssize)
271
+    {
272
+        free(spinned);
273
+        cli_dbgmsg("spin: crc out of bounds, giving up\n");
274
+        return 1;
275
+    }
276
+    key32 = cli_readint32(ep + 0x3217) - summit(src, len);
362 277
 
363
-      while (notthesamelen) {
364
-	int xcfailure=0;
365
-        *emu=exec86(*emu, notthesamelen-- & 0xff, curr, &xcfailure);
366
-	if (xcfailure) {
367
-	  cli_dbgmsg("spin: cannot exec section\n");
368
-	  return 1;
369
-	}
278
+    memcpy(src + sections[sectcnt].raw, spinned, sections[sectcnt].rsz);
279
+    free(spinned);                                                  /* done CRC'ing - can have a dirty buffer now */
280
+    ep = src + nep + sections[sectcnt].raw - sections[sectcnt].rva; /* Fix the helper */
281
+
282
+    if (!CLI_ISCONTAINED(src, ssize, ep + 0x3207, 4))
283
+    { /* this one holds all ep based checks */
284
+        cli_dbgmsg("spin: key out of bounds, giving up\n");
285
+        return 1;
286
+    }
287
+    bitmap = cli_readint32(ep + 0x3207);
288
+    cli_dbgmsg("spin: Key32 is %x - XORbitmap is %x\n", key32, bitmap);
289
+
290
+    cli_dbgmsg("spin: Decrypting sects (xor)\n");
291
+    for (j = 0; j < sectcnt; j++)
292
+    {
293
+
294
+        if (bitmap & 1)
295
+        {
296
+            uint32_t size = sections[j].rsz;
297
+            char *ptr = src + sections[j].raw;
298
+            uint32_t keydup = key32;
299
+
300
+            if (!CLI_ISCONTAINED(src, ssize, ptr, size))
301
+            {
302
+                cli_dbgmsg("spin: sect %d out of file, giving up\n", j);
303
+                return 1; /* FIXME: Already checked in pe.c? */
304
+            }
305
+
306
+            while (size--)
307
+            {
308
+                if (!(keydup & 1))
309
+                {
310
+                    keydup = keydup >> 1;
311
+                    keydup ^= 0xed43af31;
312
+                }
313
+                else
314
+                {
315
+                    keydup = keydup >> 1;
316
+                }
317
+                *ptr = *ptr ^ (keydup & 0xff);
318
+                ptr++;
319
+            }
320
+        }
321
+        bitmap = bitmap >> 1;
322
+    }
323
+
324
+    cli_dbgmsg("spin: done\n");
325
+
326
+    curr = ep + 0x644;
327
+    if ((len = cli_readint32(curr)) != 0x180)
328
+    {
329
+        cli_dbgmsg("spin: Not spinned or bad version\n");
330
+        return 1;
331
+    }
332
+
333
+    key32 = cli_readint32(curr + 0x0c);
334
+    cli_dbgmsg("spin: Key is %x, Len is %x\n", key32, len);
335
+    curr = ep + 0x28d3;
336
+
337
+    if (!CLI_ISCONTAINED(src, ssize, curr, len))
338
+    { /* always true but i may decide to remove the previous check */
339
+        cli_dbgmsg("spin: key out of bounds, giving up\n");
340
+        return 1;
341
+    }
342
+    while (len--)
343
+    {
344
+        if (key32 & 1)
345
+        {
346
+            key32 = key32 >> 1;
347
+            key32 ^= 0xed43af32;
348
+        }
349
+        else
350
+        {
351
+            key32 = key32 >> 1;
352
+        }
353
+        *curr = *curr ^ (key32 & 0xff);
354
+        curr++;
355
+    }
356
+
357
+    curr = ep + 0x28dd;
358
+    if ((len = cli_readint32(curr)) != 0x1a1)
359
+    {
360
+        cli_dbgmsg("spin: Not spinned or bad version\n");
361
+        return 1;
362
+    }
363
+
364
+    cli_dbgmsg("spin: POLY1 len is %x\n", len);
365
+    curr += 0xf; /* POLY1 */
366
+    emu = ep + 0x6d4;
367
+    if (!CLI_ISCONTAINED(src, ssize, emu, len))
368
+    {
369
+        cli_dbgmsg("spin: poly1 out of bounds\n");
370
+        return 1;
371
+    }
372
+    while (len)
373
+    {
374
+        int xcfailure = 0;
375
+        *emu = exec86(*emu, len-- & 0xff, curr, &xcfailure); /* unlame POLY1 */
376
+        if (xcfailure)
377
+        {
378
+            cli_dbgmsg("spin: cannot exec poly1\n");
379
+            return 1;
380
+        }
370 381
         emu++;
371
-      }
372 382
     }
373
-      bitmap = bitmap >>1;
374
-  }
375
-  
376
-  cli_dbgmsg("spin: done\n");
377
-
378
-  bitmap = cli_readint32(ep+0x3061);
379
-  bitman = bitmap;
380
-
381
-  /* FIXMELIMITS: possibly rewrite to use the limits api */
382
-  if(ctx->engine->maxfilesize) {
383
-    unsigned long int filesize = 0;
384
-    
385
-    for (j=0; j<sectcnt; j++) {
386
-      if (bitmap&1) {
387
-	if ( filesize > ctx->engine->maxfilesize || sections[j].vsz > ctx->engine->maxfilesize - filesize ) return 2;
388
-	filesize += sections[j].vsz;
389
-      }
390
-      bitmap>>=1;
383
+
384
+    bitmap = cli_readint32(ep + 0x6f1);
385
+    cli_dbgmsg("spin: POLYbitmap is %x - decrypting sects (poly)\n", bitmap);
386
+    curr = ep + 0x755;
387
+
388
+    for (j = 0; j < sectcnt; j++)
389
+    {
390
+        if (bitmap & 1)
391
+        {
392
+            uint32_t notthesamelen = sections[j].rsz;
393
+
394
+            emu = src + sections[j].raw;
395
+
396
+            if (!CLI_ISCONTAINED(src, ssize, curr, 0x24))
397
+            { /* section bounds already checked twice now */
398
+                cli_dbgmsg("spin: poly1 emucode is out of file?\n");
399
+                return 1;
400
+            }
401
+
402
+            while (notthesamelen)
403
+            {
404
+                int xcfailure = 0;
405
+                *emu = exec86(*emu, notthesamelen-- & 0xff, curr, &xcfailure);
406
+                if (xcfailure)
407
+                {
408
+                    cli_dbgmsg("spin: cannot exec section\n");
409
+                    return 1;
410
+                }
411
+                emu++;
412
+            }
413
+        }
414
+        bitmap = bitmap >> 1;
391 415
     }
392
-    
393
-    bitmap = bitman;
394
-  }
395
-
396
-  cli_dbgmsg("spin: Compression bitmap is %x\n", bitmap);
397
-  if ( (sects= (char **) cli_malloc(sectcnt*sizeof(char *))) == NULL ) {
398
-      cli_dbgmsg("spin: malloc(%lu) failed\n", sectcnt*sizeof(char *));
399
-    return 1;
400
-  }
401
-
402
-  len = 0;
403
-  for (j=0; j<sectcnt; j++) {
404
-    if (bitmap&1) {
405
-       if ( (sects[j] = (char *) cli_malloc(sections[j].vsz) ) == NULL ) {
406
-	 cli_dbgmsg("spin: malloc(%d) failed\n", sections[j].vsz);
407
-	 len = 1;
408
-	 break;
409
-       }
410
-       blobsz+=sections[j].vsz;
411
-       memset(sects[j], 0, sections[j].vsz);
412
-       cli_dbgmsg("spin: Growing sect%d: was %x will be %x\n", j, sections[j].rsz, sections[j].vsz);
413
-       if ( cli_unfsg(src + sections[j].raw, sects[j], sections[j].rsz, sections[j].vsz, NULL, NULL) == -1 ) {
414
-	 len++;
415
-         cli_dbgmsg("spin: Unpack failure\n");
416
-       }
417
-    } else {
418
-      blobsz+=sections[j].rsz;
419
-      sects[j] = src + sections[j].raw;
420
-      cli_dbgmsg("spin: Not growing sect%d\n", j);
416
+
417
+    cli_dbgmsg("spin: done\n");
418
+
419
+    bitmap = cli_readint32(ep + 0x3061);
420
+    bitman = bitmap;
421
+
422
+    /* FIXMELIMITS: possibly rewrite to use the limits api */
423
+    if (ctx->engine->maxfilesize)
424
+    {
425
+        unsigned long int filesize = 0;
426
+
427
+        for (j = 0; j < sectcnt; j++)
428
+        {
429
+            if (bitmap & 1)
430
+            {
431
+                if (filesize > ctx->engine->maxfilesize || sections[j].vsz > ctx->engine->maxfilesize - filesize)
432
+                    return 2;
433
+                filesize += sections[j].vsz;
434
+            }
435
+            bitmap >>= 1;
436
+        }
437
+
438
+        bitmap = bitman;
421 439
     }
422
-    bitmap>>=1;
423
-  }
424
-  
425
-  cli_dbgmsg("spin: decompression complete\n");
426
- 
427
-  if ( len ) {
428
-    int t;
429
-    for (t=0 ; t<j ; t++) {
430
-      if (bitman&1)
431
-	free(sects[t]);
432
-      bitman = bitman >>1 & 0x7fffffff;
440
+
441
+    cli_dbgmsg("spin: Compression bitmap is %x\n", bitmap);
442
+    if ((sects = (char **)cli_malloc(sectcnt * sizeof(char *))) == NULL)
443
+    {
444
+        cli_dbgmsg("spin: malloc(%lu) failed\n", sectcnt * sizeof(char *));
445
+        return 1;
433 446
     }
434
-    free(sects);
435
-    return 1;
436
-  }
437 447
 
448
+    len = 0;
449
+    for (j = 0; j < sectcnt; j++)
450
+    {
451
+        if (bitmap & 1)
452
+        {
453
+            if ((sects[j] = (char *)cli_malloc(sections[j].vsz)) == NULL)
454
+            {
455
+                cli_dbgmsg("spin: malloc(%d) failed\n", sections[j].vsz);
456
+                len = 1;
457
+                break;
458
+            }
459
+            blobsz += sections[j].vsz;
460
+            memset(sects[j], 0, sections[j].vsz);
461
+            cli_dbgmsg("spin: Growing sect%d: was %x will be %x\n", j, sections[j].rsz, sections[j].vsz);
462
+            if (cli_unfsg(src + sections[j].raw, sects[j], sections[j].rsz, sections[j].vsz, NULL, NULL) == -1)
463
+            {
464
+                len++;
465
+                cli_dbgmsg("spin: Unpack failure\n");
466
+            }
467
+        }
468
+        else
469
+        {
470
+            blobsz += sections[j].rsz;
471
+            sects[j] = src + sections[j].raw;
472
+            cli_dbgmsg("spin: Not growing sect%d\n", j);
473
+        }
474
+        bitmap >>= 1;
475
+    }
438 476
 
439
-  key32 = cli_readint32(ep+0x2fee);
440
-  if (key32) {
441
-    /*    len = cli_readint32(ep+0x2fc8); -- Using vsizes instead */
477
+    cli_dbgmsg("spin: decompression complete\n");
478
+
479
+    if (len)
480
+    {
481
+        int t;
482
+        for (t = 0; t < j; t++)
483
+        {
484
+            if (bitman & 1)
485
+                free(sects[t]);
486
+            bitman = bitman >> 1 & 0x7fffffff;
487
+        }
488
+        free(sects);
489
+        return 1;
490
+    }
442 491
 
443
-    for (j=0; j<sectcnt; j++) {
444
-      if (sections[j].rva <= key32 && key32-sections[j].rva < sections[j].vsz && CLI_ISCONTAINED(src + sections[j].raw, sections[j].rsz, src + sections[j].raw, key32 - sections[j].rva))
445
-	break;
492
+    key32 = cli_readint32(ep + 0x2fee);
493
+    if (key32)
494
+    {
495
+        /*    len = cli_readint32(ep+0x2fc8); -- Using vsizes instead */
496
+
497
+        for (j = 0; j < sectcnt; j++)
498
+        {
499
+            if (sections[j].rva <= key32 && key32 - sections[j].rva < sections[j].vsz && CLI_ISCONTAINED(src + sections[j].raw, sections[j].rsz, src + sections[j].raw, key32 - sections[j].rva))
500
+                break;
501
+        }
502
+
503
+        if (j != sectcnt && ((bitman & (1 << j)) == 0))
504
+        { /* FIXME: not really sure either the res sect is lamed or just compressed, but this'll save some major headakes */
505
+            cli_dbgmsg("spin: Resources (sect%d) appear to be compressed\n\tuncompressed offset %x, len %x\n\tcompressed offset %x, len %x\n", j, sections[j].rva, key32 - sections[j].rva, key32, sections[j].vsz - (key32 - sections[j].rva));
506
+
507
+            if ((curr = (char *)cli_malloc(sections[j].vsz)) != NULL)
508
+            {
509
+                memcpy(curr, src + sections[j].raw, key32 - sections[j].rva);                           /* Uncompressed part */
510
+                memset(curr + key32 - sections[j].rva, 0, sections[j].vsz - (key32 - sections[j].rva)); /* bzero */
511
+                if (cli_unfsg(src + sections[j].raw + key32 - sections[j].rva, curr + key32 - sections[j].rva, sections[j].rsz - (key32 - sections[j].rva), sections[j].vsz - (key32 - sections[j].rva), NULL, NULL))
512
+                {
513
+
514
+                    free(curr);
515
+                    cli_dbgmsg("spin: Failed to grow resources, continuing anyway\n");
516
+                    blobsz += sections[j].rsz;
517
+                }
518
+                else
519
+                {
520
+                    sects[j] = curr;
521
+                    bitman |= 1 << j;
522
+                    cli_dbgmsg("spin: Resources grown\n");
523
+                    blobsz += sections[j].vsz;
524
+                }
525
+            }
526
+            else
527
+            {
528
+                /* malloc failed but i'm too deep into this crap to quit without leaking more :( */
529
+                cli_dbgmsg("spin: memory allocation failed, continuing anyway\n");
530
+                blobsz += sections[j].rsz;
531
+            }
532
+        }
533
+        else
534
+        {
535
+            cli_dbgmsg("spin: No res?!\n");
536
+        }
446 537
     }
447 538
 
448
-    if (j!=sectcnt && ((bitman & (1<<j)) == 0)) { /* FIXME: not really sure either the res sect is lamed or just compressed, but this'll save some major headakes */
449
-      cli_dbgmsg("spin: Resources (sect%d) appear to be compressed\n\tuncompressed offset %x, len %x\n\tcompressed offset %x, len %x\n", j, sections[j].rva, key32 - sections[j].rva, key32, sections[j].vsz - (key32 - sections[j].rva));
450
-
451
-      if ( (curr=(char *)cli_malloc(sections[j].vsz)) != NULL ) {
452
-	memcpy(curr, src + sections[j].raw, key32 - sections[j].rva); /* Uncompressed part */
453
-	memset(curr + key32 - sections[j].rva, 0, sections[j].vsz - (key32 - sections[j].rva)); /* bzero */
454
-	if ( cli_unfsg(src + sections[j].raw + key32 - sections[j].rva, curr + key32 - sections[j].rva, sections[j].rsz - (key32 - sections[j].rva), sections[j].vsz - (key32 - sections[j].rva), NULL, NULL) ) {
455
-      
456
-	  free(curr);
457
-	  cli_dbgmsg("spin: Failed to grow resources, continuing anyway\n");
458
-	  blobsz+=sections[j].rsz;
459
-	} else {
460
-	  sects[j]=curr;
461
-	  bitman|=1<<j;
462
-	  cli_dbgmsg("spin: Resources grown\n");
463
-	  blobsz+=sections[j].vsz;
464
-	}
465
-      } else {
466
-	/* malloc failed but i'm too deep into this crap to quit without leaking more :( */
467
-          cli_dbgmsg("spin: memory allocation failed, continuing anyway\n");
468
-	blobsz+=sections[j].rsz;
469
-      }
470
-    } else {
471
-      cli_dbgmsg("spin: No res?!\n");
539
+    bitmap = bitman; /* save as a free() bitmap */
540
+
541
+    if ((ep = (char *)cli_malloc(blobsz)) != NULL)
542
+    {
543
+        struct cli_exe_section *rebhlp;
544
+        if ((rebhlp = (struct cli_exe_section *)cli_malloc(sizeof(struct cli_exe_section) * (sectcnt))) != NULL)
545
+        {
546
+            char *to = ep;
547
+            int retval = 0;
548
+
549
+            for (j = 0; j < sectcnt; j++)
550
+            {
551
+                rebhlp[j].raw = (j > 0) ? (rebhlp[j - 1].raw + rebhlp[j - 1].rsz) : 0;
552
+                rebhlp[j].rsz = (bitmap & 1) ? sections[j].vsz : sections[j].rsz;
553
+                rebhlp[j].rva = sections[j].rva;
554
+                rebhlp[j].vsz = sections[j].vsz;
555
+
556
+                memcpy(to, sects[j], rebhlp[j].rsz);
557
+                to += rebhlp[j].rsz;
558
+                if (bitmap & 1)
559
+                    free(sects[j]);
560
+                bitmap = bitmap >> 1;
561
+            }
562
+
563
+            if (!cli_rebuildpe(ep, rebhlp, sectcnt, 0x400000, 0x1000, 0, 0, desc))
564
+            { /* can't be bothered fixing those values: the rebuilt exe is completely broken anyway. */
565
+                cli_dbgmsg("spin: Cannot write unpacked file\n");
566
+                retval = 1;
567
+            }
568
+            free(rebhlp);
569
+            free(ep);
570
+            free(sects);
571
+            return retval;
572
+        }
573
+        free(ep);
472 574
     }
473
-  }
474
-  
475
-
476
-  bitmap=bitman; /* save as a free() bitmap */
477
-
478
-  if ( (ep = (char *) cli_malloc(blobsz)) != NULL ) {
479
-    struct cli_exe_section *rebhlp;
480
-    if ( (rebhlp = (struct cli_exe_section *) cli_malloc(sizeof(struct cli_exe_section)*(sectcnt))) != NULL ) {
481
-      char *to = ep;
482
-      int retval = 0;
483
-
484
-      for (j = 0; j < sectcnt; j++) {
485
-	rebhlp[j].raw = (j>0)?(rebhlp[j-1].raw + rebhlp[j-1].rsz):0;
486
-	rebhlp[j].rsz = (bitmap &1) ? sections[j].vsz : sections[j].rsz;
487
-	rebhlp[j].rva = sections[j].rva;
488
-	rebhlp[j].vsz = sections[j].vsz;
489
-
490
-	memcpy(to, sects[j], rebhlp[j].rsz);
491
-	to+=rebhlp[j].rsz;
492
-	if ( bitmap & 1 ) free(sects[j]);
493
-	bitmap = bitmap >>1;
494
-      }
495
-
496
-      if (! cli_rebuildpe(ep, rebhlp, sectcnt, 0x400000, 0x1000, 0, 0, desc)) { /* can't be bothered fixing those values: the rebuilt exe is completely broken anyway. */
497
-	cli_dbgmsg("spin: Cannot write unpacked file\n");
498
-	retval = 1;
499
-      }
500
-      free(rebhlp);
501
-      free(ep);
502
-      free(sects);
503
-      return retval;
575
+
576
+    cli_dbgmsg("spin: free bitmap is %x\n", bitman);
577
+    for (j = 0; j < sectcnt; j++)
578
+    {
579
+        if (bitmap & 1)
580
+            free(sects[j]);
581
+        bitman = bitman >> 1 & 0x7fffffff;
504 582
     }
505
-    free(ep);
506
-  }
507
-
508
-  cli_dbgmsg ("spin: free bitmap is %x\n", bitman);
509
-  for (j=0; j<sectcnt; j++) {
510
-    if (bitmap&1) free(sects[j]);
511
-    bitman = bitman >>1 & 0x7fffffff;
512
-  }
513
-  free(sects);
514
-  return 1; /* :( */
583
+    free(sects);
584
+    return 1; /* :( */
515 585
 }