~ubuntu-branches/ubuntu/feisty/clamav/feisty

« back to all changes in this revision

Viewing changes to libclamav/yc.c

  • Committer: Bazaar Package Importer
  • Author(s): Kees Cook
  • Date: 2007-02-20 10:33:44 UTC
  • mto: This revision was merged to the branch mainline in revision 16.
  • Revision ID: james.westby@ubuntu.com-20070220103344-zgcu2psnx9d98fpa
Tags: upstream-0.90
ImportĀ upstreamĀ versionĀ 0.90

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 *  Copyright (C) 2007-2008 Sourcefire, Inc.
3
 
 *
4
 
 *  Authors: Ivan Zlatev
 
2
 *  Copyright (C) 2005 Ivan Zlatev <pumqara@gmail.com>
5
3
 *
6
4
 *  This program is free software; you can redistribute it and/or modify
7
 
 *  it under the terms of the GNU General Public License version 2 as
8
 
 *  published by the Free Software Foundation.
 
5
 *  it under the terms of the GNU General Public License as published by
 
6
 *  the Free Software Foundation; either version 2 of the License, or
 
7
 *  (at your option) any later version.
9
8
 *
10
9
 *  This program is distributed in the hope that it will be useful,
11
10
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
24
23
 * 13/01/2006 - merged standalone unpacker into libclamav
25
24
 * 14/01/2006 - major rewrite and bugfix
26
25
 */
 
26
 
27
27
 
28
28
#include <string.h>
29
29
 
30
30
#if HAVE_CONFIG_H
31
31
#include "clamav-config.h"
32
32
#endif
 
33
 
33
34
#include "cltypes.h"
34
35
#include "pe.h"
35
36
#include "others.h"
36
37
#include "yc.h"
37
38
 
 
39
#define EC32(x) le32_to_host(x) /* Convert little endian to host */
38
40
#define EC16(x) le16_to_host(x) /* Convert little endian to host */
39
41
 
40
42
/* ========================================================================== */
119
121
              if(decryptor_offset[j]=='\xC0') /* ROL AL,num */
120
122
                {
121
123
                  j++;
122
 
                  CLI_ROL(al,decryptor_offset[j]);
 
124
                  ROL(al,decryptor_offset[j]);
123
125
                }
124
126
              else                      /* ROR AL,num */
125
127
                {
126
128
                  j++;
127
 
                  CLI_ROR(al,decryptor_offset[j]);
 
129
                  ROR(al,decryptor_offset[j]);
128
130
                }
129
131
              break;
130
132
 
133
135
              if(decryptor_offset[j]=='\xC8') /* ROR AL,CL */
134
136
                {
135
137
                  j++;
136
 
                  CLI_ROR(al,cl);
 
138
                  ROR(al,cl);
137
139
                }
138
140
              else                      /* ROL AL,CL */
139
141
                {
140
142
                  j++;
141
 
                  CLI_ROL(al,cl);
 
143
                  ROL(al,cl);
142
144
                }
143
145
              break;
144
146
 
163
165
/* ========================================================================== */
164
166
/* Main routine which calls all others */
165
167
 
166
 
int yc_decrypt(char *fbuf, unsigned int filesize, struct cli_exe_section *sections, unsigned int sectcount, uint32_t peoffset, int desc, uint32_t ecx,int16_t offset) {
167
 
  uint32_t ycsect = sections[sectcount].raw+offset;
 
168
int yc_decrypt(char *fbuf, unsigned int filesize, struct pe_image_section_hdr *sections, unsigned int sectcount, uint32_t peoffset, int desc)
 
169
{
 
170
  uint32_t ycsect = EC32(sections[sectcount].PointerToRawData);
168
171
  unsigned int i;
169
172
  struct pe_image_file_hdr *pe = (struct pe_image_file_hdr*) (fbuf + peoffset);
170
 
  char *sname = (char *)pe + EC16(pe->SizeOfOptionalHeader) + 0x18;
171
173
 
172
174
  /* 
173
175
 
175
177
 
176
178
  Start offset for analyze: Start of yC Section + 0x93
177
179
  End offset for analyze: Start of yC Section + 0xC3
178
 
  Length to decrypt - ECX = 0xB97
 
180
  Lenght to decrypt - ECX = 0xB97
179
181
 
180
182
  */
181
 
  cli_dbgmsg("yC: offset: %x, length: %x\n", offset, ecx);
182
 
  cli_dbgmsg("yC: decrypting decryptor on sect %d\n", sectcount);
183
 
  if (yc_poly_emulator(fbuf + ycsect + 0x93, fbuf + ycsect + 0xc6, ecx))
 
183
  cli_dbgmsg("yC: decrypting decryptor on sect %d\n", sectcount); 
 
184
  if (yc_poly_emulator(fbuf + ycsect + 0x93, fbuf + ycsect + 0xc6 ,0xB97))
184
185
    return 1;
185
 
  filesize-=sections[sectcount].ursz;
 
186
  filesize-=EC32(sections[sectcount].SizeOfRawData);
186
187
 
187
188
  /* 
188
189
 
198
199
  /* Loop through all sections and decrypt them... */
199
200
  for(i=0;i<sectcount;i++)
200
201
    {
201
 
      uint32_t name = (uint32_t) cli_readint32(sname+i*0x28);
202
 
      if (!sections[i].raw ||
203
 
          !sections[i].rsz ||
204
 
           name == 0x63727372 || /* rsrc */
 
202
      uint32_t name = (uint32_t) cli_readint32((char *)sections[i].Name);
 
203
      if ( name == 0x63727372 || /* rsrc */
205
204
           name == 0x7273722E || /* .rsr */
206
205
           name == 0x6F6C6572 || /* relo */
207
206
           name == 0x6C65722E || /* .rel */
209
208
           name == 0x6164722E || /* .rda */
210
209
           name == 0x6164692E || /* .ida */
211
210
           name == 0x736C742E || /* .tls */
212
 
           (name&0xffff) == 0x4379  /* yC */
213
 
        ) continue;
214
 
      cli_dbgmsg("yC: decrypting sect%d\n",i);
215
 
      if (yc_poly_emulator(fbuf + ycsect + (offset == -0x18 ? 0x3ea : 0x457), fbuf + sections[i].raw, sections[i].ursz))
216
 
          return 1;
 
211
           ((name&0xffff) == 0x4379) || /* yC */
 
212
           EC32(sections[i].PointerToRawData) == 0 ||
 
213
           EC32(sections[i].SizeOfRawData) == 0 ) continue;
 
214
      cli_dbgmsg("yC: decrypting sect%d\n",i); 
 
215
      if (yc_poly_emulator(fbuf + ycsect + 0x457, fbuf + EC32(sections[i].PointerToRawData), EC32(sections[i].SizeOfRawData)))
 
216
        return 1;
217
217
    }
218
218
 
219
219
  /* Remove yC section */
220
 
  pe->NumberOfSections=EC16(sectcount);
 
220
  pe->NumberOfSections=EC16(pe->NumberOfSections)-1;
221
221
 
222
222
  /* Remove IMPORT_DIRECTORY information */
223
223
  memset((char *)pe + sizeof(struct pe_image_file_hdr) + 0x68, 0, 8);
227
227
  cli_writeint32((char *)pe + sizeof(struct pe_image_file_hdr) + 16, cli_readint32(fbuf + ycsect + 0xa0f));
228
228
 
229
229
  /* Fix SizeOfImage */
230
 
  cli_writeint32((char *)pe + sizeof(struct pe_image_file_hdr) + 0x38, cli_readint32((char *)pe + sizeof(struct pe_image_file_hdr) + 0x38) - sections[sectcount].vsz);
 
230
  cli_writeint32((char *)pe + sizeof(struct pe_image_file_hdr) + 0x38, cli_readint32((char *)pe + sizeof(struct pe_image_file_hdr) + 0x38) - EC32(sections[sectcount].VirtualSize));
231
231
 
232
232
  if (cli_writen(desc, fbuf, filesize)==-1) {
233
233
    cli_dbgmsg("yC: Cannot write unpacked file\n");