More generic approach for ghost detection/fixup on rebuild.

Better handling of rebuilt headers size with lots of sects.
Nested (2+) petite packed files still result in Broken.Executable but
they're indeed broken - not too elegant, but...


git-svn-id: file:///var/lib/svn/clamav-devel/branches/temp_branch_pe_cleanup@2954 77e5149b-7576-45b1-b177-96237e5ba77b
This commit is contained in:
aCaB
2007-03-20 03:57:21 +00:00
parent 9c0614e82c
commit 4490fd97ee
4 changed files with 22 additions and 25 deletions

View File

@@ -2254,7 +2254,7 @@ skip_upack_and_go_to_next_unpacker:
if (!petite_inflate2x_1to9(dest, min, max - min, exe_sections,
nsections - (found == 1 ? 1 : 0), EC32(optional_hdr32.ImageBase),
vep, ndesc, found, EC32(optional_hdr32.DataDirectory[2].VirtualAddress),
EC32(optional_hdr32.DataDirectory[2].Size), min)) {
EC32(optional_hdr32.DataDirectory[2].Size))) {
cli_dbgmsg("Petite: Unpacked and rebuilt executable saved in %s\n", tempfile);
cli_dbgmsg("***** Scanning rebuilt PE file *****\n");
free(dest);
@@ -2818,7 +2818,6 @@ int cli_peheader(int desc, struct cli_exe_info *peinfo)
for(i = 0; falign!=0x200 && i<peinfo->nsections; i++) {
/* file alignment fallback mode - blah */
if (falign && section_hdr[i].SizeOfRawData && EC32(section_hdr[i].PointerToRawData)%falign && !(EC32(section_hdr[i].PointerToRawData)%0x200)) {
cli_dbgmsg("Found misaligned section, using 0x200\n");
falign = 0x200;
}
}
@@ -2834,7 +2833,6 @@ int cli_peheader(int desc, struct cli_exe_info *peinfo)
if (peinfo->section[i].rsz && !CLI_ISCONTAINED(0, (uint32_t) fsize, peinfo->section[i].raw, peinfo->section[i].rsz))
peinfo->section[i].rsz = (fsize - peinfo->section[i].raw)*(fsize>peinfo->section[i].raw);
}
if(pe_plus)

View File

@@ -75,7 +75,7 @@ static int doubledl(char **scur, uint8_t *mydlptr, char *buffer, uint32_t buffer
return (olddl>>7)&1;
}
int petite_inflate2x_1to9(char *buf, uint32_t minrva, uint32_t bufsz, struct cli_exe_section *sections, unsigned int sectcount, uint32_t Imagebase, uint32_t pep, int desc, int version, uint32_t ResRva, uint32_t ResSize, uint32_t firstrva)
int petite_inflate2x_1to9(char *buf, uint32_t minrva, uint32_t bufsz, struct cli_exe_section *sections, unsigned int sectcount, uint32_t Imagebase, uint32_t pep, int desc, int version, uint32_t ResRva, uint32_t ResSize)
{
char *adjbuf = buf - minrva;
char *packed = NULL;
@@ -149,19 +149,6 @@ int petite_inflate2x_1to9(char *buf, uint32_t minrva, uint32_t bufsz, struct cli
usects[t].vsz = usects[t+1].rva - usects[t].rva;
}
if (firstrva!=usects[0].rva) {
struct cli_exe_section *nusects;
cli_dbgmsg("Petite: making room for ghosts.\n");
if ((nusects=cli_calloc(j+1, sizeof(struct cli_exe_section)))) {
memcpy(&nusects[1], usects, sizeof(struct cli_exe_section)*j);
nusects[0].rva=firstrva;
nusects[0].vsz=nusects[1].rva-firstrva;
free(usects);
usects = nusects;
j++;
}
}
/*
* Our encryption is pathetic and out software is lame but
* we need to claim it's unbreakable.

View File

@@ -23,6 +23,6 @@
#include "cltypes.h"
#include "pe.h"
int petite_inflate2x_1to9(char *buf, uint32_t minrva, uint32_t bufsz, struct cli_exe_section *sections, unsigned int sectcount, uint32_t Imagebase, uint32_t pep, int desc, int version, uint32_t ResRva, uint32_t ResSize, uint32_t baserva);
int petite_inflate2x_1to9(char *buf, uint32_t minrva, uint32_t bufsz, struct cli_exe_section *sections, unsigned int sectcount, uint32_t Imagebase, uint32_t pep, int desc, int version, uint32_t ResRva, uint32_t ResSize);
#endif

View File

@@ -119,45 +119,57 @@ struct IMAGE_PE_HEADER {
int cli_rebuildpe(char *buffer, struct cli_exe_section *sections, int sects, uint32_t base, uint32_t ep, uint32_t ResRva, uint32_t ResSize, int file)
{
int i;
uint32_t datasize=0, rawbase;
uint32_t datasize=0, rawbase=PESALIGN(0x148+0x80+0x28*sects, 0x200);
char *pefile=NULL, *curpe;
struct IMAGE_PE_HEADER *fakepe;
int i, gotghost=(sections[0].rva > PESALIGN(rawbase, 0x1000));
if(sects > 96)
if (gotghost) rawbase=PESALIGN(0x148+0x80+0x28*(sects+1), 0x200);
if(sects+gotghost > 96)
return 0;
for (i=0; i < sects; i++)
datasize+=PESALIGN(sections[i].rsz, 0x200);
rawbase = PESALIGN(0x148+0x80+0x28*sects, 0x200);
if(datasize > CLI_MAX_ALLOCATION)
return 0;
if((pefile = (char *) cli_calloc(rawbase+datasize, 1))) {
memcpy(pefile, HEADERS, 0x148);
datasize = 0x1000;
datasize = PESALIGN(rawbase, 0x1000);
fakepe = (struct IMAGE_PE_HEADER *)(pefile+0xd0);
fakepe->NumberOfSections = EC16(sects);
fakepe->NumberOfSections = EC16(sects+gotghost);
fakepe->AddressOfEntryPoint = EC32(ep);
fakepe->ImageBase = EC32(base);
fakepe->SizeOfHeaders = EC32(rawbase);
memset(pefile+0x148, 0, 0x80);
cli_writeint32(pefile+0x148+0x10, ResRva);
cli_writeint32(pefile+0x148+0x14, ResSize);
curpe = pefile+0x148+0x80;
if (gotghost) {
snprintf(curpe, 8, "empty");
cli_writeint32(curpe+8, sections[0].rva-datasize); /* vsize */
cli_writeint32(curpe+12, datasize); /* rva */
cli_writeint32(curpe+0x24, 0xffffffff);
curpe+=40;
datasize+=PESALIGN(sections[0].rva-datasize, 0x1000);
}
for (i=0; i < sects; i++) {
snprintf(curpe, 8, ".clam%.2d", i+1);
cli_writeint32(curpe+8, sections[i].vsz);
cli_writeint32(curpe+12, sections[i].rva);
cli_writeint32(curpe+16, sections[i].rsz);
cli_writeint32(curpe+20, rawbase);
/* already zeroed
cli_writeint32(curpe+24, 0);
cli_writeint32(curpe+28, 0);
cli_writeint32(curpe+32, 0);
*/
cli_writeint32(curpe+0x24, 0xffffffff);
memcpy(pefile+rawbase, buffer+sections[i].raw, sections[i].rsz);
rawbase+=PESALIGN(sections[i].rsz, 0x200);