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; }
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 PackHeader::putPackHeader(upx_bytep p) { assert(get_le32(p) == UPX_MAGIC_LE32); if (get_le32(p+4) != UPX_MAGIC2_LE32) { //fprintf(stderr, "MAGIC2_LE32: %x %x\n", get_le32(p+4), UPX_MAGIC2_LE32); throwBadLoader(); } int size = 0; int old_chksum = 0; // the new variable length header if (format < 128) { if (format == UPX_F_DOS_COM || format == UPX_F_DOS_SYS) { size = 22; old_chksum = get_packheader_checksum(p, size - 1); set_le16(p+16,u_len); set_le16(p+18,c_len); p[20] = (unsigned char) filter; } else if (format == UPX_F_DOS_EXE) { size = 27; old_chksum = get_packheader_checksum(p, size - 1); set_le24(p+16,u_len); set_le24(p+19,c_len); set_le24(p+22,u_file_size); p[25] = (unsigned char) filter; } else if (format == UPX_F_DOS_EXEH) { throwInternalError("invalid format"); } else { size = 32; old_chksum = get_packheader_checksum(p, size - 1); set_le32(p+16,u_len); set_le32(p+20,c_len); set_le32(p+24,u_file_size); p[28] = (unsigned char) filter; p[29] = (unsigned char) filter_cto; assert(n_mru == 0 || (n_mru >= 2 && n_mru <= 256)); p[30] = (unsigned char) (n_mru ? n_mru - 1 : 0); } set_le32(p+8,u_adler); set_le32(p+12,c_adler); } else { size = 32; old_chksum = get_packheader_checksum(p, size - 1); set_be32(p+8,u_len); set_be32(p+12,c_len); set_be32(p+16,u_adler); set_be32(p+20,c_adler); set_be32(p+24,u_file_size); p[28] = (unsigned char) filter; p[29] = (unsigned char) filter_cto; assert(n_mru == 0 || (n_mru >= 2 && n_mru <= 256)); p[30] = (unsigned char) (n_mru ? n_mru - 1 : 0); } p[4] = (unsigned char) version; p[5] = (unsigned char) format; p[6] = (unsigned char) method; p[7] = (unsigned char) level; // header_checksum assert(size == getPackHeaderSize()); // check old header_checksum if (p[size - 1] != 0) { if (p[size - 1] != old_chksum) { //printf("old_checksum: %d %d\n", p[size - 1], old_chksum); throwBadLoader(); } } // store new header_checksum p[size - 1] = get_packheader_checksum(p, size - 1); }