48
48
#define IMAGE_OPTIONAL_SIGNATURE 0x010b
50
50
#define DETECT_BROKEN (options & CL_SCAN_BLOCKBROKEN)
51
#define BLOCKMAX (options & CL_SCAN_BLOCKMAX)
52
53
#define UPX_NRV2B "\x11\xdb\x11\xc9\x01\xdb\x75\x07\x8b\x1e\x83\xee\xfc\x11\xdb\x11\xc9\x11\xc9\x75\x20\x41\x01\xdb"
53
54
#define UPX_NRV2D "\x83\xf0\xff\x74\x78\xd1\xf8\x89\xc5\xeb\x0b\x01\xdb\x75\x07\x8b\x1e\x83\xee\xfc\x11\xdb\x11\xc9"
149
int cli_scanpe(int desc, const char **virname, long int *scanned, const struct cl_node *root, const struct cl_limits *limits, unsigned int options, unsigned int arec, unsigned int mrec)
150
int cli_scanpe(int desc, const char **virname, unsigned long int *scanned, const struct cl_node *root, const struct cl_limits *limits, unsigned int options, unsigned int arec, unsigned int mrec)
151
152
uint16_t e_magic; /* DOS signature ("MZ") */
152
153
uint16_t nsections;
160
161
char sname[9], buff[4096], *tempfile;
161
162
unsigned int i, found, upx_success = 0, min = 0, max = 0, err, broken = 0;
162
163
unsigned int ssize = 0, dsize = 0, dll = 0;
163
int (*upxfn)(char *, int , char *, int *, uint32_t, uint32_t, uint32_t) = NULL;
164
int (*upxfn)(char *, uint32_t , char *, uint32_t *, uint32_t, uint32_t, uint32_t) = NULL;
164
165
char *src = NULL, *dest = NULL;
332
333
cli_dbgmsg("SizeOfOptionalHeader: %d\n", EC16(file_hdr.SizeOfOptionalHeader));
334
335
if(EC16(file_hdr.SizeOfOptionalHeader) != sizeof(struct pe_image_optional_hdr)) {
335
cli_warnmsg("Broken PE header detected.\n");
338
*virname = "Broken.Executable";
336
/* Support for PE32+ binaries available in CVS */
597
593
if(limits && limits->maxfilesize && (ssize > limits->maxfilesize || dsize > limits->maxfilesize)) {
598
594
cli_dbgmsg("FSG: Sizes exceeded (ssize: %d, dsize: %d, max: %lu)\n", ssize, dsize , limits->maxfilesize);
599
595
free(section_hdr);
597
*virname = "PE.FSG.ExceededFileSize";
603
604
if(ssize <= 0x19 || dsize <= ssize) {
668
/* FIXME: unused atm, needed for pe rebuilding */
669
cli_dbgmsg("FSG: found old EP @%x\n", cli_readint32(newebx + 12 - EC32(section_hdr[i + 1].VirtualAddress) + src) - EC32(optional_hdr.ImageBase));
669
newedx=cli_readint32(newebx + 12 - EC32(section_hdr[i + 1].VirtualAddress) + src) - EC32(optional_hdr.ImageBase);
670
cli_dbgmsg("FSG: found old EP @%x\n",newedx);
671
672
if((dest = (char *) cli_calloc(dsize, sizeof(char))) == NULL) {
672
673
free(section_hdr);
677
if(unfsg_200(newesi - EC32(section_hdr[i + 1].VirtualAddress) + src, dest, ssize + EC32(section_hdr[i + 1].VirtualAddress) - newesi, dsize) == -1) {
678
cli_dbgmsg("FSG: Unpacking failed\n");
678
tempfile = cli_gentemp(NULL);
679
if((ndesc = open(tempfile, O_RDWR|O_CREAT|O_TRUNC, S_IRWXU)) < 0) {
680
cli_dbgmsg("FSG: Can't create file %s\n", tempfile);
688
switch (unfsg_200(newesi - EC32(section_hdr[i + 1].VirtualAddress) + src, dest, ssize + EC32(section_hdr[i + 1].VirtualAddress) - newesi, dsize, newedi, EC32(optional_hdr.ImageBase), newedx, ndesc)) {
689
case 1: /* Everything OK */
690
cli_dbgmsg("FSG: Unpacked and rebuilt executable saved in %s\n", tempfile);
694
lseek(ndesc, 0, SEEK_SET);
696
cli_dbgmsg("***** Scanning rebuilt PE file *****\n");
697
if(cli_magic_scandesc(ndesc, virname, scanned, root, limits, options, arec, mrec) == CL_VIRUS) {
700
if(!cli_leavetemps_flag)
706
if(!cli_leavetemps_flag)
712
case 0: /* We've got an unpacked buffer, no exe though */
713
cli_dbgmsg("FSG: Successfully decompressed\n");
718
break; /* Go and scan the buffer! */
720
default: /* Everything gone wrong */
721
cli_dbgmsg("FSG: Unpacking failed\n");
686
cli_dbgmsg("FSG: Successfully decompressed\n");
729
break; /* were done with 2 */
704
747
if(limits && limits->maxfilesize && (ssize > limits->maxfilesize || dsize > limits->maxfilesize)) {
705
748
cli_dbgmsg("FSG: Sizes exceeded (ssize: %d, dsize: %d, max: %lu)\n", ssize, dsize, limits->maxfilesize);
706
749
free(section_hdr);
751
*virname = "PE.FSG.ExceededFileSize";
710
758
if(ssize <= 0x19 || dsize <= ssize) {
724
772
if(limits && limits->maxfilesize && (unsigned int) gp > limits->maxfilesize) {
725
773
cli_dbgmsg("FSG: Buffer size exceeded (size: %d, max: %lu)\n", gp, limits->maxfilesize);
726
774
free(section_hdr);
776
*virname = "PE.FSG.ExceededFileSize";
730
783
if((support = (char *) cli_malloc(gp)) == NULL) {
914
967
if(limits && limits->maxfilesize && (ssize > limits->maxfilesize || dsize > limits->maxfilesize)) {
915
968
cli_dbgmsg("FSG: Sizes exceeded (ssize: %d, dsize: %d, max: %lu)\n", ssize, dsize, limits->maxfilesize);
916
969
free(section_hdr);
971
*virname = "PE.FSG.ExceededFileSize";
920
978
if(ssize <= 0x19 || dsize <= ssize) {
934
992
if(limits && limits->maxfilesize && (unsigned int) gp > limits->maxfilesize) {
935
993
cli_dbgmsg("FSG: Buffer size exceeded (size: %d, max: %lu)\n", gp, limits->maxfilesize);
936
994
free(section_hdr);
996
*virname = "PE.FSG.ExceededFileSize";
940
1003
if((support = (char *) cli_malloc(gp)) == NULL) {
1094
1157
if(limits && limits->maxfilesize && (ssize > limits->maxfilesize || dsize > limits->maxfilesize)) {
1095
1158
cli_dbgmsg("UPX: Sizes exceeded (ssize: %d, dsize: %d, max: %lu)\n", ssize, dsize , limits->maxfilesize);
1096
1159
free(section_hdr);
1161
*virname = "PE.UPX.ExceededFileSize";
1100
1168
if(ssize <= 0x19 || dsize <= ssize) { /* FIXME: What are reasonable values? */
1283
1351
if(limits && limits->maxfilesize && dsize > limits->maxfilesize) {
1284
1352
cli_dbgmsg("Petite: Size exceeded (dsize: %d, max: %lu)\n", dsize, limits->maxfilesize);
1285
1353
free(section_hdr);
1355
*virname = "PE.Petite.ExceededFileSize";
1289
1362
if((dest = (char *) cli_calloc(dsize, sizeof(char))) == NULL) {