📄 p_vmlinz.cpp
字号:
setup_buf.alloc(setup_size); memcpy(setup_buf, obuf, setup_size); //OutputFile::dump("setup.img", setup_buf, setup_size); obuf.dealloc(); obuf.allocForCompression(klen); ph.u_len = klen; ph.filter = 0;}Linker* PackVmlinuzI386::newLinker() const{ return new ElfLinkerX86;}/*************************************************************************// vmlinuz specific**************************************************************************/void PackVmlinuzI386::buildLoader(const Filter *ft){ // prepare loader initLoader(stub_i386_linux_kernel_vmlinuz, sizeof(stub_i386_linux_kernel_vmlinuz)); addLoader("LINUZ000", ph.first_offset_found == 1 ? "LINUZ001" : "", ft->id ? "LZCALLT1" : "", "LZIMAGE0", getDecompressorSections(), NULL ); if (ft->id) { assert(ft->calls > 0); addLoader("LZCALLT9", NULL); addFilter32(ft->id); } addLoader("LINUZ990,IDENTSTR,UPX1HEAD", NULL);}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: ~28KB stack compressWithFilters(&ft, 512, &cconf); 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; 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();}/*************************************************************************// bvmlinuz specific**************************************************************************/void PackBvmlinuzI386::buildLoader(const Filter *ft){ // prepare loader initLoader(stub_i386_linux_kernel_vmlinuz, sizeof(stub_i386_linux_kernel_vmlinuz)); addLoader("LINUZ000", ph.first_offset_found == 1 ? "LINUZ001" : "", (0x40==(0xf0 & ft->id)) ? "LZCKLLT1" : (ft->id ? "LZCALLT1" : ""), "LBZIMAGE,IDENTSTR", "+40", // align the stuff to 4 byte boundary "UPX1HEAD", // 32 byte "LZCUTPOI", NULL); // fake alignment for the start of the decompressor linker->defineSymbol("LZCUTPOI", 0x1000); addLoader(getDecompressorSections(), NULL ); if (ft->id) { assert(ft->calls > 0); if (0x40==(0xf0 & ft->id)) { addLoader("LZCKLLT9", NULL); } else { addLoader("LZCALLT9", NULL); } addFilter32(ft->id); } addLoader("LINUZ990", NULL);}void PackBvmlinuzI386::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 upx_compress_config_t cconf; cconf.reset(); // limit stack size needed for runtime decompression cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28KB stack compressWithFilters(&ft, 512, &cconf); // 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; acc_uint32e_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); 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(); 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) & 0xffff; fo->write(setup_buf, setup_buf.getSize()); fo->write(loader, e_len); fo->write(obuf, c_len); 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();}/*************************************************************************// unpack**************************************************************************/int PackVmlinuzI386::canUnpack(){ if (readFileHeader() != getFormat()) return false; fi->seek(setup_size, SEEK_SET); return readPackHeader(1024) ? 1 : -1;}void PackVmlinuzI386::unpack(OutputFile *fo){ // no uncompression support for this format, so that // it is possible to remove the original deflate code (>10KB) // FIXME: but we could write the uncompressed "vmlinux" image ibuf.alloc(ph.c_len); obuf.allocForUncompression(ph.u_len); fi->seek(setup_size + ph.buf_offset + ph.getPackHeaderSize(), SEEK_SET); fi->readx(ibuf, ph.c_len); // decompress decompress(ibuf, obuf); // unfilter Filter ft(ph.level); ft.init(ph.filter, physical_start); ft.cto = (unsigned char) ph.filter_cto; ft.unfilter(obuf, ph.u_len); // write decompressed file if (fo) { throwCantUnpack("build a new kernel instead :-)"); //fo->write(obuf, ph.u_len); }}/*vi:ts=4:et*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -