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

« back to all changes in this revision

Viewing changes to libclamav/suecrypt.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
/*
 
2
 *  Copyright (C) 2006 aCaB <acab@clamav.net>
 
3
 *
 
4
 *  This program is free software; you can redistribute it and/or modify
 
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.
 
8
 *
 
9
 *  This program is distributed in the hope that it will be useful,
 
10
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
 *  GNU General Public License for more details.
 
13
 *
 
14
 *  You should have received a copy of the GNU General Public License
 
15
 *  along with this program; if not, write to the Free Software
 
16
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 
17
 *  MA 02110-1301, USA.
 
18
 */
 
19
 
 
20
/*
 
21
** suecrypt.c
 
22
**
 
23
** 05/08/2k6 - Quick RCE, started coding.
 
24
** 06/08/2k6 - There were large drops of black rain.
 
25
** 07/08/2k6 - Found more versions, back to reversing.
 
26
** 11/08/2k6 - Generic and special cases handler. Release. 
 
27
**
 
28
*/
 
29
 
 
30
/*
 
31
** Unpacks and rebuilds suecrypt(*)
 
32
**
 
33
** Not sure at all what this stuff is, couldn't find any reference to it
 
34
** Seems to be popular in dialers, can't say more except...
 
35
** Christoph asked for it and that's enough :)
 
36
**
 
37
** (*) some versions or maybe only some samples
 
38
*/
 
39
 
 
40
#if HAVE_CONFIG_H
 
41
#include "clamav-config.h"
 
42
#endif
 
43
 
 
44
#include <sys/types.h>
 
45
#ifdef HAVE_UNISTD_H
 
46
#include <unistd.h>
 
47
#endif
 
48
#include <stdlib.h>
 
49
#include <string.h>
 
50
 
 
51
#include "cltypes.h"
 
52
#include "others.h"
 
53
#include "pe.h"
 
54
#include "suecrypt.h"
 
55
 
 
56
#define EC32(x) le32_to_host(x) /* Convert little endian to host */
 
57
#define EC16(x) le16_to_host(x)
 
58
 
 
59
char *sudecrypt(int desc, size_t fsize, struct cli_exe_section *sections, uint16_t sects, char *buff, uint32_t bkey, uint32_t pkey, uint32_t e_lfanew) {
 
60
  char *file, *hunk;
 
61
  uint32_t va,sz,key;
 
62
  int i, j;
 
63
 
 
64
  cli_dbgmsg("in suecrypt\n");
 
65
 
 
66
  if (!(file=cli_calloc(fsize, 1))) return 0;
 
67
  lseek(desc, 0, SEEK_SET);
 
68
  if((size_t) cli_readn(desc, file, fsize) != fsize) {
 
69
    cli_dbgmsg("SUE: Can't read %d bytes\n", fsize);
 
70
    free(file);
 
71
    return 0;
 
72
  }
 
73
 
 
74
  va=(bkey>>16)|(bkey<<16);
 
75
  key=((sz=cli_readint32(buff+0x3e))^va);
 
76
  if (!key || key==0x208 || key==0x3bc) key=((sz=cli_readint32(buff+0x46))^va); /* FIXME: black magic */
 
77
 
 
78
  if (key!=pkey) {
 
79
    cli_dbgmsg("SUE: Key seems not (entirely) encrypted\n\tpossible key: 0%08x\n\tcrypted key:  0%08x\n\tplain key:    0%08x\n", pkey, key, sz);
 
80
    va=0;
 
81
    for (i=0; i<4; i++) {
 
82
      va=(va<<8)|0xff;
 
83
      if (((key&va)|(sz&(~va)))==pkey) {
 
84
        key=pkey;
 
85
        break;
 
86
      }
 
87
    }
 
88
    if (i==4) cli_dbgmsg("SUE: let's roll the dice...\n");
 
89
  }
 
90
  cli_dbgmsg("SUE: Decrypting with 0%08x\n", key);
 
91
 
 
92
  i=0;
 
93
  while(1) {
 
94
    if (!CLI_ISCONTAINED(buff-0x74, 0xbe, buff-0x58+i*8, 8)) {
 
95
      free(file);
 
96
      return 0;
 
97
    }
 
98
    va=(cli_readint32(buff-0x58+i*8)^bkey);
 
99
    sz=(cli_readint32(buff-0x58+4+i*8)^bkey);
 
100
    if (!va) break;
 
101
    cli_dbgmsg("SUE: Hunk #%d RVA:%x size:%d\n", i, va, sz);
 
102
    for (j=0; j<sects; j++) {
 
103
      if(!CLI_ISCONTAINED(sections[j].rva, sections[j].rsz, va, sz)) continue;
 
104
      hunk=file+sections[j].rva-va+sections[j].raw;
 
105
      while(sz>=4) {
 
106
        cli_writeint32(hunk, cli_readint32(hunk)^key);
 
107
        hunk+=4;
 
108
        sz-=4;
 
109
      }
 
110
      break;
 
111
    }
 
112
    if (j==sects) {
 
113
      cli_dbgmsg("SUE: Hunk out of file or cross sections\n");
 
114
      free(file);
 
115
      return 0;
 
116
    }
 
117
    i++;
 
118
  }
 
119
  va=(cli_readint32(buff-0x74)^bkey);
 
120
  cli_dbgmsg("SUE: found OEP: @%x\n", va);
 
121
 
 
122
  hunk=file+e_lfanew;
 
123
  hunk[6]=sects&0xff;
 
124
  hunk[7]=sects>>8;
 
125
  cli_writeint32(hunk+0x28, va);
 
126
  hunk+=0x18+(cli_readint32(hunk+0x14)&0xffff); /* size of PE + size of OPT */
 
127
  memset(hunk+0x28*sects, 0, 0x28);
 
128
 
 
129
  return file;
 
130
}