void PackArmPe::buildLoader(const Filter *ft) { const unsigned char *loader = use_thumb_stub ? stub_arm_v4t_wince_pe : stub_arm_v4a_wince_pe; unsigned size = use_thumb_stub ? sizeof(stub_arm_v4t_wince_pe) : sizeof(stub_arm_v4a_wince_pe); // prepare loader initLoader(loader, size); if (isdll) addLoader("DllStart", NULL); addLoader("ExeStart", NULL); if (ph.method == M_NRV2E_8) addLoader("Call2E", NULL); else if (ph.method == M_NRV2B_8) addLoader("Call2B", NULL); else if (ph.method == M_NRV2D_8) addLoader("Call2D", NULL); else if (M_IS_LZMA(ph.method)) addLoader("+40C,CallLZMA", NULL); if (ft->id == 0x50) addLoader("+40C,Unfilter_0x50", NULL); if (sorelocs) addLoader("+40C,Relocs", NULL); addLoader("+40C,Imports", NULL); addLoader("ProcessEnd", NULL); if (ph.method == M_NRV2E_8) addLoader(".ucl_nrv2e_decompress_8", NULL); else if (ph.method == M_NRV2B_8) addLoader(".ucl_nrv2b_decompress_8", NULL); else if (ph.method == M_NRV2D_8) addLoader(".ucl_nrv2d_decompress_8", NULL); else if (M_IS_LZMA(ph.method)) addLoader("+40C,LZMA_DECODE,LZMA_DEC10", NULL); addLoader("IDENTSTR,UPX1HEAD", NULL); }
int PackExe::fillExeHeader(struct exe_header_t *eh) const { #define oh (*eh) // fill new exe header int flag = 0; if (!opt->dos_exe.no_reloc && !M_IS_LZMA(ph.method)) flag |= USEJUMP; if (ih.relocs == 0) flag |= NORELOC; memset(&oh,0,sizeof(oh)); oh.ident = 'M' + 'Z' * 256; oh.headsize16 = 2; unsigned minsp = 0x200; if (M_IS_LZMA(ph.method)) minsp = stack_for_lzma; minsp = ALIGN_UP(minsp, 16u); assert(minsp < 0xff00); if (oh.sp > minsp) minsp = oh.sp; if (minsp < 0xff00 - 2) minsp = ALIGN_UP(minsp, 2u); oh.sp = minsp; unsigned destpara = (ph.u_len + ph.overlap_overhead - ph.c_len + 31) / 16; oh.ss = ph.c_len/16 + destpara; if (ih.ss*16 + ih.sp < 0x100000 && ih.ss > oh.ss && ih.sp > 0x200) oh.ss = ih.ss; if (oh.ss*16 + 0x50 < ih.ss*16 + ih.sp && oh.ss*16 + 0x200 > ih.ss*16 + ih.sp) oh.ss += 0x20; if (oh.ss != ih.ss) flag |= SS; if (oh.sp != ih.sp || M_IS_LZMA(ph.method)) flag |= SP; return flag; #undef oh }
unsigned PackTos::getDecomprOffset(int method, int small) const { UNUSED(small); if (M_IS_NRV2B(method)) return 2; // FIXME: do not hardcode this value else if (M_IS_NRV2D(method)) return 2; // FIXME: do not hardcode this value else if (M_IS_NRV2E(method)) return 2; // FIXME: do not hardcode this value else if (M_IS_LZMA(method)) return linker->getSectionSize("__mulsi3"); else throwBadLoader(); return 0; }
const int *PackArmPe::getCompressionMethods(int method, int level) const { static const int m_all[] = { M_NRV2B_8, M_NRV2E_8, M_LZMA, M_END }; static const int m_lzma[] = { M_LZMA, M_END }; static const int m_nrv2b[] = { M_NRV2B_8, M_END }; static const int m_nrv2e[] = { M_NRV2E_8, M_END }; if (!use_thumb_stub) return getDefaultCompressionMethods_8(method, level); if (method == M_ALL) return m_all; if (M_IS_LZMA(method)) return m_lzma; if (M_IS_NRV2B(method)) return m_nrv2b; if (M_IS_NRV2E(method)) return m_nrv2e; return m_nrv2e; }
bool set_method_name(char *buf, size_t size, int method, int level) { bool r = true; const char *alg; if (M_IS_NRV2B(method)) alg = "NRV2B"; else if (M_IS_NRV2D(method)) alg = "NRV2D"; else if (M_IS_NRV2E(method)) alg = "NRV2E"; else if (M_IS_LZMA(method)) alg = "LZMA"; else { alg = "???"; r = false; } if (level > 0) upx_snprintf(buf, size, "%s/%d", alg, level); else upx_snprintf(buf, size, "%s", alg); return r; }
int upx_test_overlap ( const upx_bytep buf, const upx_bytep tbuf, unsigned src_off, unsigned src_len, unsigned* dst_len, int method, const upx_compress_result_t *cresult ) { int r = UPX_E_ERROR; if (cresult && cresult->method == 0) cresult = NULL; assert(*dst_len > 0); assert(src_len < *dst_len); // must be compressed unsigned overlap_overhead = src_off + src_len - *dst_len; assert((int)overlap_overhead > 0); if (0) { } #if (WITH_LZMA) else if (M_IS_LZMA(method)) r = upx_lzma_test_overlap(buf, tbuf, src_off, src_len, dst_len, method, cresult); #endif #if (WITH_NRV) else if (M_IS_NRV2B(method) || M_IS_NRV2D(method) || M_IS_NRV2E(method)) r = upx_nrv_test_overlap(buf, tbuf, src_off, src_len, dst_len, method, cresult); #endif #if (WITH_UCL) else if (M_IS_NRV2B(method) || M_IS_NRV2D(method) || M_IS_NRV2E(method)) r = upx_ucl_test_overlap(buf, tbuf, src_off, src_len, dst_len, method, cresult); #endif else { throwInternalError("unknown decompression method"); } return r; }
int upx_decompress ( const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned* dst_len, int method, const upx_compress_result_t *cresult ) { int r = UPX_E_ERROR; assert(*dst_len > 0); assert(src_len < *dst_len); // must be compressed if (cresult && cresult->method == 0) cresult = NULL; if (0) { } #if (WITH_LZMA) else if (M_IS_LZMA(method)) r = upx_lzma_decompress(src, src_len, dst, dst_len, method, cresult); #endif #if (WITH_NRV) else if (M_IS_NRV2B(method) || M_IS_NRV2D(method) || M_IS_NRV2E(method)) r = upx_nrv_decompress(src, src_len, dst, dst_len, method, cresult); #endif #if (WITH_UCL) else if (M_IS_NRV2B(method) || M_IS_NRV2D(method) || M_IS_NRV2E(method)) r = upx_ucl_decompress(src, src_len, dst, dst_len, method, cresult); #endif #if (WITH_ZLIB) else if (M_IS_DEFLATE(method)) r = upx_zlib_decompress(src, src_len, dst, dst_len, method, cresult); #endif else { throwInternalError("unknown decompression method"); } return r; }
void PackTos::buildLoader(const Filter *ft) { assert(ft->id == 0); initLoader(stub_m68k_atari_tos, sizeof(stub_m68k_atari_tos)); //linker->dumpSymbols(); // // part 1a // addLoader("entry"); if (symbols.up21_a6 <= 32767) addLoader("set_up21_a6.w"); else if (symbols.up21_d4 <= 32767) addLoader("set_up21_d4.w"); else addLoader("set_up21_d4.l"); assert(symbols.loop1.count || symbols.loop2.count); if (symbols.loop1.count) { if (symbols.loop1.value <= 127) addLoader("loop1_set_count.b"); else if (symbols.loop1.value <= 65535) addLoader("loop1_set_count.w"); else addLoader("loop1_set_count.l"); addLoader("loop1_label"); addLoader(opt->small ? "loop1.small" : "loop1.fast"); if (symbols.loop1.mode == symbols.LOOP_SUBQ_L) addLoader("loop1_subql"); else if (symbols.loop1.mode == symbols.LOOP_SUBQ_W) addLoader("loop1_subqw"); else if (symbols.loop1.mode == symbols.LOOP_DBRA) addLoader("loop1_dbra"); else throwBadLoader(); } if (symbols.loop2.count) { assert(symbols.loop2.mode == symbols.LOOP_DBRA); addLoader(opt->small ? "loop2.small" : "loop2.fast"); } addLoader("copy_to_stack"); if (M_IS_NRV2B(ph.method)) addLoader("nrv2b.init"); else if (M_IS_NRV2D(ph.method)) addLoader("nrv2d.init"); else if (M_IS_NRV2E(ph.method)) addLoader("nrv2e.init"); else if (M_IS_LZMA(ph.method)) addLoader("lzma.init"); else throwBadLoader(); symbols.up31_d4 = symbols.up31_base_d4 + getDecomprOffset(ph.method, opt->small); symbols.up31_a6 = symbols.up31_base_a6 + getDecomprOffset(ph.method, opt->small); if (symbols.up31_a6 <= 32767) addLoader("jmp_decompressor_a6.w"); else if (symbols.up31_d4 <= 32767) addLoader("jmp_decompressor_d4.w"); else if (symbols.up31_a6 <= 65534) addLoader("jmp_decompressor_a6.w2"); else addLoader("jmp_decompressor_d4.l"); // // part 1b // addLoader("code_on_stack"); addLoader("clear_dirty_bss"); addLoader("loop3_label"); addLoader(opt->small ? "loop3.small" : "loop3.fast"); if (symbols.loop3.mode == symbols.LOOP_SUBQ_L) addLoader("loop3_subql"); else if (symbols.loop3.mode == symbols.LOOP_SUBQ_W) addLoader("loop3_subqw"); else if (symbols.loop3.mode == symbols.LOOP_DBRA) addLoader("loop3_dbra"); else throwBadLoader(); addLoader("flush_cache"); addLoader("restore_stack"); #if 0 addLoader("clear_dirty_stack"); #endif addLoader("start_program"); addLoader("IDENTSTR,+40D,UPX1HEAD,CUTPOINT"); // // part 2 // if (M_IS_NRV2B(ph.method)) { addLoader(opt->small ? "nrv2b_8.small" : "nrv2b_8.fast"); } else if (M_IS_NRV2D(ph.method)) { addLoader(opt->small ? "nrv2d_8.small" : "nrv2d_8.fast"); } else if (M_IS_NRV2E(ph.method)) { addLoader(opt->small ? "nrv2e_8.small" : "nrv2e_8.fast"); } else if (M_IS_LZMA(ph.method)) { addLoader("__mulsi3"); addLoader(opt->small ? "lzma.small" : "lzma.fast"); addLoader("lzma.finish"); } else throwBadLoader(); if (symbols.need_reloc) addLoader("reloc"); assert(symbols.loop3.count); if (symbols.loop3.value <= 127) addLoader("loop3_set_count.b"); else if (symbols.loop3.value <= 65535) addLoader("loop3_set_count.w"); else addLoader("loop3_set_count.l"); addLoader("jmp_stack"); }
void PackExe::buildLoader(const Filter *) { // get flag exe_header_t dummy_oh; int flag = fillExeHeader(&dummy_oh); initLoader(stub_i086_dos16_exe, sizeof(stub_i086_dos16_exe)); if (M_IS_LZMA(ph.method)) { addLoader("LZMA_DEC00", opt->small ? "LZMA_DEC10" : "LZMA_DEC20", "LZMA_DEC30", use_clear_dirty_stack ? "LZMA_DEC31" : "", "LZMA_DEC32", ph.u_len > 0xffff ? "LZMA_DEC33" : "", NULL ); addLoaderEpilogue(flag); defineDecompressorSymbols(); const unsigned lsize0 = getLoaderSize(); // Lzma decompression code starts at ss:0x10, and its size is // lsize bytes. It also needs getDecompressorWrkmemSize() bytes // during uncompression. It also uses some stack, so 0x100 // more bytes are allocated stack_for_lzma = 0x10 + lsize0 + getDecompressorWrkmemSize() + 0x100; stack_for_lzma = ALIGN_UP(stack_for_lzma, 16u); unsigned clear_dirty_stack_low = 0x10 + lsize0; clear_dirty_stack_low = ALIGN_UP(clear_dirty_stack_low, 2u); if (use_clear_dirty_stack) linker->defineSymbol("clear_dirty_stack_low", clear_dirty_stack_low); relocateLoader(); const unsigned lsize = getLoaderSize(); assert(lsize0 == lsize); MemBuffer loader(lsize); memcpy(loader, getLoader(), lsize); MemBuffer compressed_lzma; compressed_lzma.allocForCompression(lsize); unsigned c_len_lzma = MemBuffer::getSizeForCompression(lsize); int r = upx_compress(loader, lsize, compressed_lzma, &c_len_lzma, NULL, M_NRV2B_LE16, 9, NULL, NULL); assert(r == UPX_E_OK); assert(c_len_lzma < lsize); info("lzma+relocator code compressed: %u -> %u", lsize, c_len_lzma); // reinit the loader initLoader(stub_i086_dos16_exe, sizeof(stub_i086_dos16_exe)); // prepare loader if (device_driver) addLoader("DEVICEENTRY,LZMADEVICE,DEVICEENTRY2", NULL); linker->addSection("COMPRESSED_LZMA", compressed_lzma, c_len_lzma, 0); addLoader("LZMAENTRY,NRV2B160,NRVDDONE,NRVDECO1,NRVGTD00,NRVDECO2", NULL); } else if (device_driver) addLoader("DEVICEENTRY,DEVICEENTRY2", NULL); addLoader("EXEENTRY", M_IS_LZMA(ph.method) && device_driver ? "LONGSUB" : "SHORTSUB", "JNCDOCOPY", relocsize ? "EXERELPU" : "", "EXEMAIN4", M_IS_LZMA(ph.method) ? "" : "EXEMAIN4B", "EXEMAIN4C", M_IS_LZMA(ph.method) ? "COMPRESSED_LZMA_START,COMPRESSED_LZMA" : "", "+G5DXXXX,UPX1HEAD,EXECUTPO", NULL ); if (ph.method == M_NRV2B_8) addLoader("NRV2B16S", // decompressor ph.u_len > DI_LIMIT ? "N2B64K01" : "", "NRV2BEX1", opt->cpu == opt->CPU_8086 ? "N2BX8601" : "N2B28601", "NRV2BEX2", opt->cpu == opt->CPU_8086 ? "N2BX8602" : "N2B28602", "NRV2BEX3", ph.c_len > 0xffff ? "N2B64K02" : "", "NRV2BEX9", NULL ); else if (ph.method == M_NRV2D_8) addLoader("NRV2D16S", ph.u_len > DI_LIMIT ? "N2D64K01" : "", "NRV2DEX1", opt->cpu == opt->CPU_8086 ? "N2DX8601" : "N2D28601", "NRV2DEX2", opt->cpu == opt->CPU_8086 ? "N2DX8602" : "N2D28602", "NRV2DEX3", ph.c_len > 0xffff ? "N2D64K02" : "", "NRV2DEX9", NULL ); else if (ph.method == M_NRV2E_8) addLoader("NRV2E16S", ph.u_len > DI_LIMIT ? "N2E64K01" : "", "NRV2EEX1", opt->cpu == opt->CPU_8086 ? "N2EX8601" : "N2E28601", "NRV2EEX2", opt->cpu == opt->CPU_8086 ? "N2EX8602" : "N2E28602", "NRV2EEX3", ph.c_len > 0xffff ? "N2E64K02" : "", "NRV2EEX9", NULL ); else if M_IS_LZMA(ph.method) return; else
static int do_option(int optc, const char *arg) { int i = 0; switch (optc) { #if 0 // FIXME: to_stdout doesn't work because of console code mess //case 'c': case 517: opt->to_stdout = true; break; #endif case 'd': set_cmd(CMD_DECOMPRESS); break; case 'D': opt->debug.debug_level++; break; case 'f': opt->force++; break; case 909: set_cmd(CMD_FILEINFO); break; case 'h': case 'H': case '?': set_cmd(CMD_HELP); break; case 'h'+256: #if 1 if (!acc_isatty(STDOUT_FILENO)) { /* according to GNU standards */ set_term(stdout); opt->console = CON_FILE; } #endif show_help(1); e_exit(EXIT_OK); break; case 'i': opt->info_mode++; break; case 'l': set_cmd(CMD_LIST); break; case 'L': set_cmd(CMD_LICENSE); break; case 'o': set_output_name(mfx_optarg,1); break; case 'q': opt->verbose = (opt->verbose > 1 ? 1 : opt->verbose - 1); break; case 't': set_cmd(CMD_TEST); break; case 'v': opt->verbose = (opt->verbose < 3 ? 3 : opt->verbose + 1); break; case 'V': set_cmd(CMD_VERSION); break; case 'V'+256: /* according to GNU standards */ set_term(stdout); opt->console = CON_FILE; show_version(0); e_exit(EXIT_OK); break; // method case 702: opt->method_nrv2b_seen = true; if (!set_method(M_NRV2B_LE32, -1)) e_method(M_NRV2B_LE32, opt->level); break; case 704: opt->method_nrv2d_seen = true; if (!set_method(M_NRV2D_LE32, -1)) e_method(M_NRV2D_LE32, opt->level); break; case 705: opt->method_nrv2e_seen = true; if (!set_method(M_NRV2E_LE32, -1)) e_method(M_NRV2E_LE32, opt->level); break; case 721: opt->method_lzma_seen = true; opt->all_methods_use_lzma = true; if (!set_method(M_LZMA, -1)) e_method(M_LZMA, opt->level); break; case 722: opt->method_lzma_seen = false; opt->all_methods_use_lzma = false; if (M_IS_LZMA(opt->method)) opt->method = -1; break; // compression level case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if (!set_method(-1, optc - '0')) e_method(opt->method, optc); break; case 902: // --ultra-brute opt->ultra_brute = true; /* fallthrough */ case 901: // --brute opt->all_methods = true; opt->all_methods_use_lzma = true; opt->method = -1; opt->all_filters = true; opt->filter = -1; opt->crp.crp_ucl.m_size = 999999; /* fallthrough */ case 900: // --best if (!set_method(-1, 10)) e_method(opt->method, 10); break; // debug case 542: if (!mfx_optarg || strlen(mfx_optarg) != 4) e_optarg(arg); memcpy(opt->debug.fake_stub_version, mfx_optarg, 4); break; case 543: if (!mfx_optarg || strlen(mfx_optarg) != 4) e_optarg(arg); memcpy(opt->debug.fake_stub_year, mfx_optarg, 4); break; case 544: if (!mfx_optarg || !mfx_optarg[0]) e_optarg(arg); opt->debug.dump_stub_loader = mfx_optarg; break; case 545: opt->debug.disable_random_id = true; break; // mp (meta) case 501: getoptvar(&opt->mp_compress_task, 1, 999999, arg); break; case 502: opt->mp_query_format = true; break; case 503: opt->mp_query_num_tasks = true; break; // misc case 512: opt->console = CON_FILE; break; case 513: opt->console = CON_ANSI_MONO; break; case 514: opt->console = CON_ANSI_COLOR; break; case 516: opt->no_progress = true; break; case 519: opt->no_env = true; break; case 526: opt->preserve_mode = false; break; case 527: opt->preserve_ownership = false; break; case 528: opt->preserve_timestamp = false; break; // compression settings case 520: // --small if (opt->small < 0) opt->small = 0; opt->small++; break; case 521: // --filter= getoptvar(&opt->filter, 0, 255, arg); opt->all_filters = false; break; case 522: // --no-filter opt->filter = 0; opt->all_filters = false; opt->no_filter = true; break; case 523: // --all-filters opt->all_filters = true; opt->filter = -1; break; case 524: // --all-methods opt->all_methods = true; opt->all_methods_use_lzma = true; opt->method = -1; break; case 525: // --exact opt->exact = true; break; // compression runtime parameters case 801: getoptvar(&opt->crp.crp_ucl.c_flags, 0, 3, arg); break; case 802: getoptvar(&opt->crp.crp_ucl.s_level, 0, 2, arg); break; case 803: getoptvar(&opt->crp.crp_ucl.h_level, 0, 1, arg); break; case 804: getoptvar(&opt->crp.crp_ucl.p_level, 0, 7, arg); break; case 805: getoptvar(&opt->crp.crp_ucl.max_offset, 256u, ~0u, arg); break; case 806: getoptvar(&opt->crp.crp_ucl.max_match, 16u, ~0u, arg); break; case 807: getoptvar(&opt->crp.crp_ucl.m_size, 10000u, 999999u, arg); break; case 811: getoptvar(&opt->crp.crp_lzma.pos_bits, arg); break; case 812: getoptvar(&opt->crp.crp_lzma.lit_pos_bits, arg); break; case 813: getoptvar(&opt->crp.crp_lzma.lit_context_bits, arg); break; case 814: getoptvar(&opt->crp.crp_lzma.dict_size, arg); break; case 816: getoptvar(&opt->crp.crp_lzma.num_fast_bytes, arg); break; case 821: getoptvar(&opt->crp.crp_zlib.mem_level, arg); break; case 822: getoptvar(&opt->crp.crp_zlib.window_bits, arg); break; case 823: getoptvar(&opt->crp.crp_zlib.strategy, arg); break; // backup case 'k': opt->backup = 1; break; case 541: if (opt->backup != 1) // do not overide '--backup' opt->backup = 0; break; // overlay case 551: if (mfx_optarg && strcmp(mfx_optarg,"skip") == 0) opt->overlay = opt->SKIP_OVERLAY; else if (mfx_optarg && strcmp(mfx_optarg,"copy") == 0) opt->overlay = opt->COPY_OVERLAY; else if (mfx_optarg && strcmp(mfx_optarg,"strip") == 0) opt->overlay = opt->STRIP_OVERLAY; else e_optarg(arg); break; case 552: opt->overlay = opt->SKIP_OVERLAY; break; case 553: opt->overlay = opt->COPY_OVERLAY; break; case 554: opt->overlay = opt->STRIP_OVERLAY; break; // CPU case 560: if (mfx_optarg && strcmp(mfx_optarg,"8086") == 0) opt->cpu = opt->CPU_8086; else if (mfx_optarg && strcmp(mfx_optarg,"386") == 0) opt->cpu = opt->CPU_386; else if (mfx_optarg && strcmp(mfx_optarg,"486") == 0) opt->cpu = opt->CPU_486; else e_optarg(arg); break; case 561: opt->cpu = opt->CPU_8086; break; case 563: opt->cpu = opt->CPU_386; break; case 564: opt->cpu = opt->CPU_486; break; // case 600: opt->dos_exe.force_stub = true; break; case 601: opt->dos_exe.no_reloc = true; break; case 610: opt->djgpp2_coff.coff = true; break; case 620: opt->watcom_le.le = true; break; case 630: opt->win32_pe.compress_exports = 1; if (mfx_optarg && mfx_optarg[0]) getoptvar(&opt->win32_pe.compress_exports, 0, 1, arg); //printf("compress_exports: %d\n", opt->win32_pe.compress_exports); break; case 631: opt->win32_pe.compress_icons = 1; if (mfx_optarg && mfx_optarg[0]) getoptvar(&opt->win32_pe.compress_icons, 0, 3, arg); //printf("compress_icons: %d\n", opt->win32_pe.compress_icons); break; case 632: opt->win32_pe.compress_resources = 1; if (mfx_optarg && mfx_optarg[0]) getoptvar(&opt->win32_pe.compress_resources, 0, 1, arg); //printf("compress_resources: %d\n", opt->win32_pe.compress_resources); break; case 633: // opt->win32_pe.strip_loadconf - OBSOLETE - IGNORED break; case 634: opt->win32_pe.strip_relocs = 1; if (mfx_optarg && mfx_optarg[0]) getoptvar(&opt->win32_pe.strip_relocs, 0, 1, arg); //printf("strip_relocs: %d\n", opt->win32_pe.strip_relocs); break; case 635: if (!mfx_optarg || !mfx_optarg[0]) e_optarg(arg); opt->win32_pe.keep_resource = mfx_optarg; break; case 650: opt->atari_tos.split_segments = true; break; case 660: getoptvar(&opt->o_unix.blocksize, 8192u, ~0u, arg); break; case 661: opt->o_unix.force_execve = true; break; case 662: opt->o_unix.script_name = "/usr/local/lib/upx/upxX"; if (mfx_optarg && mfx_optarg[0]) set_script_name(mfx_optarg, 1); break; case 663: opt->o_unix.is_ptinterp = true; break; case 664: opt->o_unix.use_ptinterp = true; break; case 665: opt->o_unix.make_ptinterp = true; break; case 666: // Linux opt->o_unix.osabi0 = Elf32_Ehdr::ELFOSABI_LINUX; break; case 667: // FreeBSD opt->o_unix.osabi0 = Elf32_Ehdr::ELFOSABI_FREEBSD; break; case 668: // NetBSD opt->o_unix.osabi0 = Elf32_Ehdr::ELFOSABI_NETBSD; break; case 669: // OpenBSD opt->o_unix.osabi0 = Elf32_Ehdr::ELFOSABI_OPENBSD; break; case 670: opt->ps1_exe.boot_only = true; break; case 671: opt->ps1_exe.no_align = true; opt->ps1_exe.boot_only = false; break; case 672: opt->ps1_exe.do_8bit = true; break; case 673: opt->ps1_exe.do_8mib = false; break; case 674: opt->o_unix.unmap_all_pages = true; // val ? break; case '\0': return -1; case ':': return -2; default: fprintf(stderr,"%s: internal error in getopt (%d)\n", argv0, optc); return -3; } UNUSED(i); return 0; }
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(); }
int upx_compress ( const upx_bytep src, unsigned src_len, upx_bytep dst, unsigned* dst_len, upx_callback_p cb, int method, int level, const upx_compress_config_t *cconf, upx_compress_result_t *cresult ) { int r = UPX_E_ERROR; upx_compress_result_t cresult_buffer; assert(method > 0); assert(level > 0); #if 1 // set available bytes in dst if (*dst_len == 0) *dst_len = MemBuffer::getSizeForCompression(src_len); #else // force users to provide *dst_len assert(*dst_len != 0); #endif // for UPX, we always require a reasonably sized outbut buffer assert(*dst_len >= MemBuffer::getSizeForCompression(src_len)); if (!cresult) cresult = &cresult_buffer; memset(cresult, 0, sizeof(*cresult)); #if 1 // debug cresult->method = method; cresult->level = level; cresult->u_len = src_len; cresult->c_len = 0; #endif if (0) { } #if (WITH_LZMA) else if (M_IS_LZMA(method)) r = upx_lzma_compress(src, src_len, dst, dst_len, cb, method, level, cconf, cresult); #endif #if (WITH_NRV) else if (M_IS_NRV2B(method) || M_IS_NRV2D(method) || M_IS_NRV2E(method)) r = upx_nrv_compress(src, src_len, dst, dst_len, cb, method, level, cconf, cresult); #endif #if (WITH_UCL) else if (M_IS_NRV2B(method) || M_IS_NRV2D(method) || M_IS_NRV2E(method)) r = upx_ucl_compress(src, src_len, dst, dst_len, cb, method, level, cconf, cresult); #endif else { throwInternalError("unknown compression method"); } #if 1 // debug cresult->c_len = *dst_len; #endif return r; }