arm/pe: fix "missing" icon & version info resource problem for wince 5

This commit is contained in:
László Molnár 2006-11-21 18:25:23 +01:00
parent 2569b09dbe
commit 4be3d79e12
3 changed files with 50 additions and 30 deletions

1
NEWS
View File

@ -4,6 +4,7 @@ User visible changes for UPX
Changes in 2.91 beta (XX XXX 2006): Changes in 2.91 beta (XX XXX 2006):
* assorted bug fixes * assorted bug fixes
* arm/pe: fix "missing" icon & version info resource problem for wince 5
Changes in 2.90 beta (08 Oct 2006): Changes in 2.90 beta (08 Oct 2006):
* LZMA algorithm support for most of the 32-bit and 64-bit file formats; * LZMA algorithm support for most of the 32-bit and 64-bit file formats;

View File

@ -727,13 +727,11 @@ void PackArmPe::pack(OutputFile *fo)
getLoaderSection("UPX1HEAD",(int*)&ic); getLoaderSection("UPX1HEAD",(int*)&ic);
identsize += ic; identsize += ic;
pe_section_t osection[3]; pe_section_t osection[4];
// section 0 : bss // section 0 : bss
// 1 : [ident + header] + packed_data + unpacker + tls // 1 : [ident + header] + packed_data + unpacker + tls
// 2 : not compressed data // 2 : not compressed data
// 3 : resource data -- wince 5 needs a new section for this
// section 2 should start with the resource data, because lots of lame
// windoze codes assume that resources starts on the beginning of a section
// identsplit - number of ident + (upx header) bytes to put into the PE header // identsplit - number of ident + (upx header) bytes to put into the PE header
int identsplit = pe_offset + sizeof(osection) + sizeof(oh); int identsplit = pe_offset + sizeof(osection) + sizeof(oh);
@ -771,7 +769,7 @@ void PackArmPe::pack(OutputFile *fo)
memset(osection,0,sizeof(osection)); memset(osection,0,sizeof(osection));
oh.entry = upxsection; oh.entry = upxsection;
oh.objects = 3; oh.objects = 4;
oh.chksum = 0; oh.chksum = 0;
// fill the data directory // fill the data directory
@ -800,12 +798,6 @@ void PackArmPe::pack(OutputFile *fo)
ODSIZE(PEDIR_RELOC) = soxrelocs; ODSIZE(PEDIR_RELOC) = soxrelocs;
ic += soxrelocs; ic += soxrelocs;
if (soresources)
processResources(&res,ic);
ODADDR(PEDIR_RESOURCE) = soresources ? ic : 0;
ODSIZE(PEDIR_RESOURCE) = soresources;
ic += soresources;
processImports(ic, linker->getSymbolOffset("IATT") + upxsection); processImports(ic, linker->getSymbolOffset("IATT") + upxsection);
ODADDR(PEDIR_IMPORT) = ic; ODADDR(PEDIR_IMPORT) = ic;
ODSIZE(PEDIR_IMPORT) = soimpdlls; ODSIZE(PEDIR_IMPORT) = soimpdlls;
@ -821,7 +813,15 @@ void PackArmPe::pack(OutputFile *fo)
} }
ic += soexport; ic += soexport;
const unsigned onam = ncsection + soxrelocs + soresources + ih.imagebase; ic = (ic + oam1) &~ oam1;
const unsigned res_start = ic;
if (soresources)
processResources(&res,ic);
ODADDR(PEDIR_RESOURCE) = soresources ? ic : 0;
ODSIZE(PEDIR_RESOURCE) = soresources;
ic += soresources;
const unsigned onam = ncsection + soxrelocs + ih.imagebase;
linker->defineSymbol("start_of_dll_names", onam); linker->defineSymbol("start_of_dll_names", onam);
linker->defineSymbol("start_of_imports", ih.imagebase + rvamin + cimports); linker->defineSymbol("start_of_imports", ih.imagebase + rvamin + cimports);
linker->defineSymbol("start_of_relocs", crelocs + rvamin + ih.imagebase); linker->defineSymbol("start_of_relocs", crelocs + rvamin + ih.imagebase);
@ -840,47 +840,45 @@ void PackArmPe::pack(OutputFile *fo)
patchPackHeader(loader, lsize); patchPackHeader(loader, lsize);
// this is computed here, because soxrelocs changes some lines above // this is computed here, because soxrelocs changes some lines above
const unsigned ncsize = soxrelocs + soresources + soimpdlls + soexport; const unsigned ncsize = soxrelocs + soimpdlls + soexport;
const unsigned fam1 = oh.filealign - 1; const unsigned fam1 = oh.filealign - 1;
// fill the sections // fill the sections
strcpy(osection[0].name,"UPX0"); strcpy(osection[0].name,"UPX0");
strcpy(osection[1].name,"UPX1"); strcpy(osection[1].name,"UPX1");
// after some windoze debugging I found that the name of the sections strcpy(osection[2].name, "UPX2");
// DOES matter :( .rsrc is used by oleaut32.dll (TYPELIBS) strcpy(osection[3].name, ".rsrc");
// and because of this lame dll, the resource stuff must be the
// first in the 3rd section - the author of this dll seems to be
// too idiot to use the data directories... M$ suxx 4 ever!
// ... even worse: exploder.exe in NiceTry also depends on this to
// locate version info
strcpy(osection[2].name,soresources ? ".rsrc" : "UPX2");
osection[0].vaddr = rvamin; osection[0].vaddr = rvamin;
osection[1].vaddr = s1addr; osection[1].vaddr = s1addr;
osection[2].vaddr = ncsection; osection[2].vaddr = ncsection;
osection[3].vaddr = res_start;
osection[0].size = 0; osection[0].size = 0;
osection[1].size = (s1size + fam1) &~ fam1; osection[1].size = (s1size + fam1) &~ fam1;
osection[2].size = (ncsize + fam1) &~ fam1; osection[2].size = (ncsize + fam1) &~ fam1;
osection[3].size = (soresources + fam1) &~ fam1;
osection[0].vsize = osection[1].vaddr - osection[0].vaddr; osection[0].vsize = osection[1].vaddr - osection[0].vaddr;
//osection[1].vsize = (osection[1].size + oam1) &~ oam1; //osection[1].vsize = (osection[1].size + oam1) &~ oam1;
//osection[2].vsize = (osection[2].size + oam1) &~ oam1; //osection[2].vsize = (osection[2].size + oam1) &~ oam1;
osection[1].vsize = osection[1].size; osection[1].vsize = osection[1].size;
osection[2].vsize = osection[2].size; osection[2].vsize = osection[2].size;
osection[3].vsize = osection[3].size;
osection[0].rawdataptr = 0; osection[0].rawdataptr = 0;
osection[1].rawdataptr = (pe_offset + sizeof(oh) + sizeof(osection) + fam1) &~ fam1; osection[1].rawdataptr = (pe_offset + sizeof(oh) + sizeof(osection) + fam1) &~ fam1;
osection[2].rawdataptr = osection[1].rawdataptr + osection[1].size; osection[2].rawdataptr = osection[1].rawdataptr + osection[1].size;
osection[3].rawdataptr = osection[2].rawdataptr + osection[2].size;
osection[0].flags = (unsigned) (PEFL_BSS|PEFL_EXEC|PEFL_WRITE|PEFL_READ); osection[0].flags = (unsigned) (PEFL_BSS|PEFL_EXEC|PEFL_WRITE|PEFL_READ);
osection[1].flags = (unsigned) (PEFL_DATA|PEFL_EXEC|PEFL_WRITE|PEFL_READ); osection[1].flags = (unsigned) (PEFL_DATA|PEFL_EXEC|PEFL_WRITE|PEFL_READ);
osection[2].flags = (unsigned) (PEFL_DATA|PEFL_READ); osection[2].flags = (unsigned) (PEFL_DATA|PEFL_READ);
osection[3].flags = (unsigned) (PEFL_DATA|PEFL_READ);
oh.imagesize = (osection[2].vaddr + osection[2].vsize + oam1) &~ oam1; oh.imagesize = (osection[3].vaddr + osection[3].vsize + oam1) &~ oam1;
oh.bsssize = osection[0].vsize; oh.bsssize = osection[0].vsize;
oh.datasize = osection[2].vsize; oh.datasize = osection[2].vsize + osection[3].vsize;
oh.database = osection[2].vaddr; oh.database = osection[2].vaddr;
oh.codesize = osection[1].vsize; oh.codesize = osection[1].vsize;
oh.codebase = osection[1].vaddr; oh.codebase = osection[1].vaddr;
@ -898,6 +896,11 @@ void PackArmPe::pack(OutputFile *fo)
infoHeader("[Writing compressed file]"); infoHeader("[Writing compressed file]");
if (soresources == 0)
{
oh.objects = 3;
memset(&osection[3], 0, sizeof(osection[3]));
}
// write loader + compressed file // write loader + compressed file
fo->write(&oh,sizeof(oh)); fo->write(&oh,sizeof(oh));
fo->write(osection,sizeof(osection)); fo->write(osection,sizeof(osection));
@ -918,14 +921,17 @@ void PackArmPe::pack(OutputFile *fo)
if ((ic = fo->getBytesWritten() & 3) != 0) if ((ic = fo->getBytesWritten() & 3) != 0)
fo->write(ibuf,4 - ic); fo->write(ibuf,4 - ic);
fo->write(otls,sotls); fo->write(otls,sotls);
if ((ic = fo->getBytesWritten() & (oh.filealign-1)) != 0) if ((ic = fo->getBytesWritten() & fam1) != 0)
fo->write(ibuf,oh.filealign - ic); fo->write(ibuf,oh.filealign - ic);
fo->write(oxrelocs,soxrelocs); fo->write(oxrelocs,soxrelocs);
fo->write(oresources,soresources);
fo->write(oimpdlls,soimpdlls); fo->write(oimpdlls,soimpdlls);
fo->write(oexport,soexport); fo->write(oexport,soexport);
if ((ic = fo->getBytesWritten() & (oh.filealign-1)) != 0) if ((ic = fo->getBytesWritten() & fam1) != 0)
fo->write(ibuf,oh.filealign - ic);
fo->write(oresources,soresources);
if ((ic = fo->getBytesWritten() & fam1) != 0)
fo->write(ibuf,oh.filealign - ic); fo->write(ibuf,oh.filealign - ic);
#if 0 #if 0
@ -968,7 +974,7 @@ int PackArmPe::canUnpack()
fi->readx(isection,sizeof(pe_section_t)*objs); fi->readx(isection,sizeof(pe_section_t)*objs);
if (ih.objects < 3) if (ih.objects < 3)
return -1; return -1;
bool is_packed = (ih.objects == 3 && bool is_packed = ((ih.objects == 3 || ih.objects == 4) &&
(IDSIZE(15) || ih.entry > isection[1].vaddr)); (IDSIZE(15) || ih.entry > isection[1].vaddr));
bool found_ph = false; bool found_ph = false;
if (memcmp(isection[0].name,"UPX",3) == 0) if (memcmp(isection[0].name,"UPX",3) == 0)

View File

@ -1630,7 +1630,7 @@ void PeFile::rebuildResources(upx_byte *& extrainfo)
extrainfo += 2; extrainfo += 2;
const unsigned vaddr = IDADDR(PEDIR_RESOURCE); const unsigned vaddr = IDADDR(PEDIR_RESOURCE);
const upx_byte *r = ibuf - isection[2].vaddr; const upx_byte *r = ibuf - isection[ih.objects - 1].vaddr;
Resource res(r + vaddr); Resource res(r + vaddr);
while (res.next()) while (res.next())
if (res.offs() > vaddr) if (res.offs() > vaddr)
@ -1657,7 +1657,10 @@ void PeFile::unpack(OutputFile *fo)
handleStub(fi,fo,pe_offset); handleStub(fi,fo,pe_offset);
const unsigned overlay = file_size - ALIGN_UP(isection[2].rawdataptr + isection[2].size,ih.filealign); const unsigned iobjs = ih.objects;
const unsigned overlay = file_size - ALIGN_UP(isection[iobjs - 1].rawdataptr
+ isection[iobjs - 1].size,
ih.filealign);
checkOverlay(overlay); checkOverlay(overlay);
ibuf.alloc(ph.c_len); ibuf.alloc(ph.c_len);
@ -1698,6 +1701,16 @@ void PeFile::unpack(OutputFile *fo)
rebuildRelocs(extrainfo); rebuildRelocs(extrainfo);
rebuildTls(); rebuildTls();
rebuildExports(); rebuildExports();
if (iobjs == 4)
{
// read the resource section if present
ibuf.dealloc();
ibuf.alloc(isection[3].size);
fi->seek(isection[3].rawdataptr,SEEK_SET);
fi->readx(ibuf,isection[3].size);
}
rebuildResources(extrainfo); rebuildResources(extrainfo);
//FIXME: this does bad things if the relocation section got removed //FIXME: this does bad things if the relocation section got removed