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; }
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; }
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"); }
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; }