Exemplo n.º 1
0
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);
}
Exemplo n.º 2
0
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
}
Exemplo n.º 3
0
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;
}
Exemplo n.º 4
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;
}
Exemplo n.º 5
0
Arquivo: util.cpp Projeto: tfauck/upx
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;
}
Exemplo n.º 6
0
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;
}
Exemplo n.º 7
0
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;
}
Exemplo n.º 8
0
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");
}
Exemplo n.º 9
0
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
Exemplo n.º 10
0
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;
}
Exemplo n.º 11
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();
}
Exemplo n.º 12
0
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;
}