mirror of
https://github.com/Cisco-Talos/clamav.git
synced 2026-05-05 22:25:38 -04:00
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:
@@ -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)
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user