void PackVmlinuzI386::pack(OutputFile *fo) { readKernel(); // prepare filter Filter ft(ph.level); ft.buf_len = ph.u_len; ft.addvalue = physical_start; // saves 4 bytes in unfilter code // compress upx_compress_config_t cconf; cconf.reset(); // limit stack size needed for runtime decompression cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28 KiB stack compressWithFilters(&ft, 512, &cconf, getStrategy(ft)); const unsigned lsize = getLoaderSize(); defineDecompressorSymbols(); defineFilterSymbols(&ft); linker->defineSymbol("src_for_decompressor", zimage_offset + lsize); linker->defineSymbol("original_entry", physical_start); linker->defineSymbol("stack_offset", stack_offset_during_uncompression); relocateLoader(); MemBuffer loader(lsize); memcpy(loader, getLoader(), lsize); patchPackHeader(loader, lsize); boot_sect_t * const bs = (boot_sect_t *) ((unsigned char *) setup_buf); bs->sys_size = ALIGN_UP(lsize + ph.c_len, 16u) / 16; bs->payload_length = ph.c_len; fo->write(setup_buf, setup_buf.getSize()); fo->write(loader, lsize); fo->write(obuf, ph.c_len); #if 0 printf("%-13s: setup : %8ld bytes\n", getName(), (long) setup_buf.getSize()); printf("%-13s: loader : %8ld bytes\n", getName(), (long) lsize); printf("%-13s: compressed : %8ld bytes\n", getName(), (long) ph.c_len); #endif // verify verifyOverlappingDecompression(); // finally check the compression ratio if (!checkFinalCompressionRatio(fo)) throwNotCompressible(); }
void PackTmt::pack(OutputFile *fo) { big_relocs = 0; Packer::handleStub(fi,fo,adam_offset); const unsigned usize = ih.imagesize; const unsigned rsize = ih.relocsize; ibuf.alloc(usize+rsize+128); obuf.allocForCompression(usize+rsize+128); MemBuffer wrkmem; wrkmem.alloc(rsize+EXTRA_INFO); // relocations fi->seek(adam_offset+sizeof(ih),SEEK_SET); fi->readx(ibuf,usize); fi->readx(wrkmem+4,rsize); const unsigned overlay = file_size - fi->tell(); if (find_le32(ibuf,128,get_le32("UPX ")) >= 0) throwAlreadyPacked(); if (rsize == 0) throwCantPack("file is already compressed with another packer"); checkOverlay(overlay); unsigned relocsize = 0; //if (rsize) { for (unsigned ic=4; ic<=rsize; ic+=4) set_le32(wrkmem+ic,get_le32(wrkmem+ic)-4); relocsize = ptr_diff(optimizeReloc32(wrkmem+4,rsize/4,wrkmem,ibuf,1,&big_relocs), wrkmem); } wrkmem[relocsize++] = 0; set_le32(wrkmem+relocsize,ih.entry); // save original entry point relocsize += 4; set_le32(wrkmem+relocsize,relocsize+4); relocsize += 4; memcpy(ibuf+usize,wrkmem,relocsize); // prepare packheader ph.u_len = usize + relocsize; // prepare filter Filter ft(ph.level); ft.buf_len = usize; // compress upx_compress_config_t cconf; cconf.reset(); // limit stack size needed for runtime decompression cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28 KiB stack compressWithFilters(&ft, 512, &cconf); const unsigned lsize = getLoaderSize(); const unsigned s_point = getLoaderSection("TMTMAIN1"); int e_len = getLoaderSectionStart("TMTCUTPO"); const unsigned d_len = lsize - e_len; assert(e_len > 0 && s_point > 0); // patch loader linker->defineSymbol("original_entry", ih.entry); defineDecompressorSymbols(); defineFilterSymbols(&ft); linker->defineSymbol("bytes_to_copy", ph.c_len + d_len); linker->defineSymbol("copy_dest", 0u - (ph.u_len + ph.overlap_overhead + d_len - 1)); linker->defineSymbol("copy_source", ph.c_len + lsize - 1); //fprintf(stderr,"\nelen=%x dlen=%x copy_len=%x copy_to=%x oo=%x jmp_pos=%x ulen=%x c_len=%x \n\n", // e_len,d_len,copy_len,copy_to,ph.overlap_overhead,jmp_pos,ph.u_len,ph.c_len); linker->defineSymbol("TMTCUTPO", ph.u_len + ph.overlap_overhead); relocateLoader(); MemBuffer loader(lsize); memcpy(loader,getLoader(),lsize); patchPackHeader(loader,e_len); memcpy(&oh,&ih,sizeof(oh)); oh.imagesize = ph.c_len + lsize; // new size oh.entry = s_point; // new entry point oh.relocsize = 4; // write loader + compressed file fo->write(&oh,sizeof(oh)); fo->write(loader,e_len); fo->write(obuf,ph.c_len); fo->write(loader+lsize-d_len,d_len); // decompressor char rel_entry[4]; set_le32(rel_entry,5 + s_point); fo->write(rel_entry,sizeof (rel_entry)); // verify verifyOverlappingDecompression(); // copy the overlay copyOverlay(fo, overlay, &obuf); // finally check the compression ratio if (!checkFinalCompressionRatio(fo)) throwNotCompressible(); }
void PackWcle::pack(OutputFile *fo) { handleStub(fo); if (ih.byte_order || ih.word_order || ih.exe_format_level || ih.cpu_type < 2 || ih.cpu_type > 5 || ih.target_os != 1 || ih.module_type != 0x200 || ih.object_iterate_data_map_offset || ih.resource_entries || ih.module_directives_entries || ih.imported_modules_count || ih.object_table_entries > 255) throwCantPack("watcom/le: unexpected value in header"); readObjectTable(); readPageMap(); readResidentNames(); readEntryTable(); readFixupPageTable(); readFixups(); readImage(); readNonResidentNames(); // if (find_le32(iimage,20,get_le32("UPX ")) >= 0) if (find_le32(iimage,UPX_MIN(soimage,256u),UPX_MAGIC_LE32) >= 0) throwAlreadyPacked(); if (ih.init_ss_object != objects) throwCantPack("the stack is not in the last object"); preprocessFixups(); const unsigned text_size = IOT(ih.init_cs_object-1,npages) * mps; const unsigned text_vaddr = IOT(ih.init_cs_object-1,my_base_address); // attach some useful data at the end of preprocessed fixups ifixups[sofixups++] = (unsigned char) (ih.automatic_data_object & 0xff); unsigned ic = objects*sizeof(*iobject_table); memcpy(ifixups+sofixups,iobject_desc,ic); iobject_desc.dealloc(); sofixups += ic; set_le32(ifixups+sofixups,ih.init_esp_offset+IOT(ih.init_ss_object-1,my_base_address)); // old stack pointer set_le32(ifixups+sofixups+4,ih.init_eip_offset+text_vaddr); // real entry point set_le32(ifixups+sofixups+8,mps*pages); // virtual address of unpacked relocations ifixups[sofixups+12] = (unsigned char) (unsigned) objects; sofixups += 13; // prepare filter Filter ft(ph.level); ft.buf_len = text_size; ft.addvalue = text_vaddr; // compress encodeImage(&ft); const unsigned lsize = getLoaderSize(); neweip = getLoaderSection("WCLEMAIN"); int e_len = getLoaderSectionStart("WCLECUTP"); const unsigned d_len = lsize - e_len; assert(e_len > 0 && e_len < RESERVED); memmove(oimage+e_len,oimage+RESERVED,soimage); soimage += lsize; opages = (soimage+mps-1)/mps; oh.bytes_on_last_page = soimage%mps; encodeObjectTable(); encodeFixups(); encodeFixupPageTable(); encodePageMap(); encodeEntryTable(); encodeResidentNames(); encodeNonResidentNames(); // patch loader ic = (OOT(0,virtual_size) - d_len) &~ 15; assert(ic > ((ph.u_len + ph.overlap_overhead + 31) &~ 15)); linker->defineSymbol("WCLECUTP", ic); linker->defineSymbol("original_entry", ih.init_eip_offset + text_vaddr); linker->defineSymbol("original_stack", ih.init_esp_offset + IOT(ih.init_ss_object - 1, my_base_address)); linker->defineSymbol("start_of_relocs", mps*pages); defineDecompressorSymbols(); defineFilterSymbols(&ft); linker->defineSymbol("filter_buffer_start", text_vaddr); unsigned jpos = (((ph.c_len + 3) &~ 3) + d_len + 3) / 4; linker->defineSymbol("words_to_copy", jpos); linker->defineSymbol("copy_dest", ((ic + d_len + 3) &~ 3) - 4); linker->defineSymbol("copy_source", e_len + jpos * 4 - 4); relocateLoader(); MemBuffer loader(lsize); memcpy(loader, getLoader(), lsize); patchPackHeader(loader, lsize); memcpy(oimage, loader, e_len); memcpy(oimage + soimage - d_len, loader + e_len, d_len); writeFile(fo, opt->watcom_le.le); // verify verifyOverlappingDecompression(oimage + e_len, oimage.getSize() - e_len); // copy the overlay const unsigned overlaystart = ih.data_pages_offset + exe_offset + getImageSize(); const unsigned overlay = file_size - overlaystart - ih.non_resident_name_table_length; checkOverlay(overlay); copyOverlay(fo, overlay, &oimage); // finally check the compression ratio if (!checkFinalCompressionRatio(fo)) throwNotCompressible(); }
void PackBvmlinuzI386::pack(OutputFile *fo) { readKernel(); // prepare filter Filter ft(ph.level); ft.buf_len = (filter_len ? filter_len : (ph.u_len * 3)/5); // May 2008: 3/5 is heuristic to cover most .text but avoid non-instructions. // Otherwise "call trick" filter cannot find a free marker byte, // especially when it searches over tables of data. ft.addvalue = 0; // The destination buffer might be relocated at runtime. upx_compress_config_t cconf; cconf.reset(); // LINUZ001 allows most of low memory as stack for Bvmlinuz cconf.conf_lzma.max_num_probs = (0x90000 - 0x10000)>>1; // ushort: 512 KiB stack compressWithFilters(&ft, 512, &cconf, getStrategy(ft)); // align everything to dword boundary - it is easier to handle unsigned c_len = ph.c_len; memset(obuf + c_len, 0, 4); c_len = ALIGN_UP(c_len, 4u); const unsigned lsize = getLoaderSize(); if (M_IS_LZMA(ph.method)) { const lzma_compress_result_t *res = &ph.compress_result.result_lzma; upx_uint32_t properties = // lc, lp, pb, dummy (res->lit_context_bits << 0) | (res->lit_pos_bits << 8) | (res->pos_bits << 16); if (linker->bele->isBE()) // big endian - bswap32 acc_swab32s(&properties); linker->defineSymbol("lzma_properties", properties); // -2 for properties linker->defineSymbol("lzma_c_len", ph.c_len - 2); linker->defineSymbol("lzma_u_len", ph.u_len); unsigned const stack = getDecompressorWrkmemSize(); linker->defineSymbol("lzma_stack_adjust", 0u - stack); } const int e_len = getLoaderSectionStart("LZCUTPOI"); assert(e_len > 0); if (0==page_offset) { // not relocatable kernel const unsigned d_len4 = ALIGN_UP(lsize - e_len, 4u); const unsigned decompr_pos = ALIGN_UP(ph.u_len + ph.overlap_overhead, 16u); const unsigned copy_size = c_len + d_len4; const unsigned edi = decompr_pos + d_len4 - 4; // copy to const unsigned esi = ALIGN_UP(c_len + lsize, 4u) - 4; // copy from linker->defineSymbol("decompressor", decompr_pos - bzimage_offset + physical_start); linker->defineSymbol("src_for_decompressor", physical_start + decompr_pos - c_len); linker->defineSymbol("words_to_copy", copy_size / 4); linker->defineSymbol("copy_dest", physical_start + edi); linker->defineSymbol("copy_source", bzimage_offset + esi); } defineFilterSymbols(&ft); defineDecompressorSymbols(); if (0==page_offset) { linker->defineSymbol("original_entry", physical_start); } linker->defineSymbol("stack_offset", stack_offset_during_uncompression); relocateLoader(); MemBuffer loader(lsize); memcpy(loader, getLoader(), lsize); patchPackHeader(loader, lsize); boot_sect_t * const bs = (boot_sect_t *) ((unsigned char *) setup_buf); bs->sys_size = (ALIGN_UP(lsize + c_len, 16u) / 16); fo->write(setup_buf, setup_buf.getSize()); unsigned const e_pfx = (0==page_offset) ? 0 : getLoaderSectionStart("LINUZ110"); if (0!=page_offset) { fo->write(loader, e_pfx); } else { fo->write(loader, e_len); } fo->write(obuf, c_len); if (0!=page_offset) { fo->write(loader + e_pfx, e_len - e_pfx); } fo->write(loader + e_len, lsize - e_len); #if 0 printf("%-13s: setup : %8ld bytes\n", getName(), (long) setup_buf.getSize()); printf("%-13s: entry : %8ld bytes\n", getName(), (long) e_len); printf("%-13s: compressed : %8ld bytes\n", getName(), (long) c_len); printf("%-13s: decompressor : %8ld bytes\n", getName(), (long) (lsize - e_len)); #endif // verify verifyOverlappingDecompression(); // finally check the compression ratio if (!checkFinalCompressionRatio(fo)) throwNotCompressible(); }