2
* Copyright (C) 2006 aCaB <acab@clamav.net>
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.
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.
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,
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.
31
** Unpacks and rebuilds suecrypt(*)
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 :)
37
** (*) some versions or maybe only some samples
41
#include "clamav-config.h"
44
#include <sys/types.h>
56
#define EC32(x) le32_to_host(x) /* Convert little endian to host */
57
#define EC16(x) le16_to_host(x)
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) {
64
cli_dbgmsg("in suecrypt\n");
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);
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 */
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);
83
if (((key&va)|(sz&(~va)))==pkey) {
88
if (i==4) cli_dbgmsg("SUE: let's roll the dice...\n");
90
cli_dbgmsg("SUE: Decrypting with 0%08x\n", key);
94
if (!CLI_ISCONTAINED(buff-0x74, 0xbe, buff-0x58+i*8, 8)) {
98
va=(cli_readint32(buff-0x58+i*8)^bkey);
99
sz=(cli_readint32(buff-0x58+4+i*8)^bkey);
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;
106
cli_writeint32(hunk, cli_readint32(hunk)^key);
113
cli_dbgmsg("SUE: Hunk out of file or cross sections\n");
119
va=(cli_readint32(buff-0x74)^bkey);
120
cli_dbgmsg("SUE: found OEP: @%x\n", va);
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);