void DkImageContainerT::loadingFinished() { DkTimer dt; if (getLoadState() == loading_canceled) { mLoadState = not_loaded; clear(); return; } if (!getLoader()->hasImage()) { mFileUpdateTimer.stop(); mEdited = false; QString msg = tr("Sorry, I could not load: %1").arg(fileName()); emit showInfoSignal(msg); emit fileLoadedSignal(false); mLoadState = exists_not; return; } else if (!getThumb()->hasImage()) { getThumb()->setImage(getLoader()->image()); } // clear file buffer if it exceeds a certain size?! e.g. psd files if (mFileBuffer && mFileBuffer->size()/(1024.0f*1024.0f) > DkSettings::resources.cacheMemory*0.5f) mFileBuffer->clear(); mLoadState = loaded; emit fileLoadedSignal(true); }
std::string CResourceLoader::getResourceName(const ResourceID & resourceIdent) const { auto locator = getResource(resourceIdent); if (locator.getLoader()) return locator.getLoader()->getFullName(locator.getResourceName()); return ""; }
void PackSys::patchLoader(OutputFile *fo, upx_byte *loader, int lsize, unsigned calls) { const int e_len = getLoaderSectionStart("SYSCUTPO"); const int d_len = lsize - e_len; assert(e_len > 0 && e_len < 128); assert(d_len > 0 && d_len < 256); if (ph.u_len + d_len + ph.overlap_overhead > 0xfffe) throwNotCompressible(); // use some fields of the original file linker->defineSymbol("attribute", get_le16(ibuf + 4)); linker->defineSymbol("interrupt", get_le16(ibuf + 8)); unsigned copy_to = ph.u_len + d_len + ph.overlap_overhead; linker->defineSymbol("calltrick_calls", calls); linker->defineSymbol("copy_source", ph.c_len + lsize - 1); linker->defineSymbol("copy_destination", copy_to); linker->defineSymbol("neg_e_len", 0 - e_len); linker->defineSymbol("NRV2B160", ph.u_len + ph.overlap_overhead + 1); linker->defineSymbol("original_strategy", get_le16(ibuf + 6)); relocateLoader(); loader = getLoader(); patchPackHeader(loader,e_len); // write loader + compressed file fo->write(loader,e_len); // entry fo->write(obuf,ph.c_len); fo->write(loader+e_len,d_len); // decompressor }
QImage DkImageContainer::image() { if (getLoader()->image().isNull() && getLoadState() == not_loaded) loadImage(); return mLoader->image(); }
void PackCom::pack(OutputFile *fo) { // read file ibuf.alloc(file_size); obuf.allocForCompression(file_size); fi->seek(0,SEEK_SET); fi->readx(ibuf,file_size); // prepare packheader ph.u_len = file_size; // prepare filter Filter ft(ph.level); ft.addvalue = getCallTrickOffset(); // compress const unsigned overlap_range = ph.u_len < 0xFE00 - ft.addvalue ? 32 : 0; compressWithFilters(&ft, overlap_range, NULL_cconf); const int lsize = getLoaderSize(); MemBuffer loader(lsize); memcpy(loader,getLoader(),lsize); const unsigned calls = ft.id % 3 ? ft.lastcall - 2 * ft.calls : ft.calls; patchLoader(fo, loader, lsize, calls); // verify verifyOverlappingDecompression(); // finally check the compression ratio if (!checkFinalCompressionRatio(fo)) throwNotCompressible(); }
void PackLinuxElf32x86interp::pack3(OutputFile *fo, Filter &/*ft*/) { unsigned base = getbase(phdri, ehdri.e_phnum); unsigned sz = PAGE_MASK & (~PAGE_MASK + elfout.phdr[0].p_filesz); if (base < (0x11000 + sz)) { base = 0x11000 + sz; } if (opt->o_unix.make_ptinterp) { base = 0x10000; } elfout.phdr[0].p_paddr = elfout.phdr[0].p_vaddr = base - sz; if (opt->o_unix.make_ptinterp) { initLoader(stub_i386_linux_elf_interp_entry, sizeof(stub_i386_linux_elf_interp_entry)); linker->addSection("FOLDEXEC", stub_i386_linux_elf_interp_fold, sizeof(stub_i386_linux_elf_interp_fold), 0); addLoader("LXPTI000", NULL); addLoader("LXPTI040", NULL); ph.method = M_NRV2B_LE32; addLoader(getDecompressorSections(), NULL); addLoader("LXPTI090", NULL); addLoader("LXPTI041", NULL); ph.method = M_NRV2D_LE32; addLoader(getDecompressorSections(), NULL); addLoader("LXPTI090", NULL); addLoader("LXPTI042", NULL); ph.method = M_NRV2E_LE32; addLoader(getDecompressorSections(), NULL); addLoader("LXPTI090", NULL); //addLoader("LXPTI043", NULL); //ph.method = M_CL1B_LE32; addLoader(getDecompressorSections(), NULL); //addLoader("LXPTI090", NULL); addLoader("LXPTI091", NULL); addLoader("LXPTI140", NULL); addLoader("LXUNF002,LXUNF008,LXUNF010", NULL); addFilter32(0x46); addLoader("LXUNF042,LXUNF035", NULL); addLoader("LXUNF002,LXUNF008,LXUNF010", NULL); addFilter32(0x49); addLoader("LXUNF042,LXUNF035", NULL); addLoader("LXPTI200", NULL); addLoader("FOLDEXEC", NULL); upx_byte const *p = getLoader(); lsize = getLoaderSize(); updateLoader(fo); fo->write(p, lsize); elfout.phdr[0].p_filesz = fo->getBytesWritten(); } else { updateLoader(fo); } }
void PackUnix::pack3(OutputFile *fo, Filter &/*ft*/) { upx_byte *p = getLoader(); lsize = getLoaderSize(); updateLoader(fo); patchLoaderChecksum(); fo->write(p, lsize); }
void SlotAssetsMgr::release(AssetsType type, int id) { string urlpath = getUrl(type, id); AssetsLoader* assetsLoader = getLoader(urlpath); if(assetsLoader != NULL) { LoaderItem* loaderItem = getLoaderItem(assetsLoader); if(loaderItem) loaderItem->setInvalid(); } }
bool DkImageContainer::saveImage(const QString& filePath, const QImage saveImg, int compression /* = -1 */) { QFileInfo saveFile = saveImageIntern(filePath, getLoader(), saveImg, compression); saveFile.refresh(); qDebug() << "save file: " << saveFile.absoluteFilePath(); return saveFile.exists() && saveFile.isFile(); }
bool DkImageContainer::loadImage() { if (!QFileInfo(mFileInfo).exists()) return false; if (getFileBuffer()->isEmpty()) mFileBuffer = loadFileToBuffer(mFilePath); mLoader = loadImageIntern(mFilePath, getLoader(), mFileBuffer); return mLoader->hasImage(); }
void PackUnix::patchLoaderChecksum() { unsigned char *const ptr = getLoader(); l_info *const lp = &linfo; // checksum for loader; also some PackHeader info lp->l_magic = UPX_MAGIC_LE32; // LE32 always set_te16(&lp->l_lsize, (upx_uint16_t) lsize); lp->l_version = (unsigned char) ph.version; lp->l_format = (unsigned char) ph.format; // INFO: lp->l_checksum is currently unused set_te32(&lp->l_checksum, upx_adler32(ptr, lsize)); }
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: ~28 KiB stack compressWithFilters(&ft, 512, &cconf, getStrategy(ft)); 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; bs->payload_length = ph.c_len; 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(); }
bool DkImageContainerT::loadImageThreaded(bool force) { #ifdef WITH_QUAZIP //zip archives: get zip file fileInfo for checks if(isFromZip()) setFilePath(getZipData()->getZipFilePath()); #endif // check file for updates QFileInfo fileInfo = filePath(); QDateTime modifiedBefore = fileInfo.lastModified(); fileInfo.refresh(); if (force || fileInfo.lastModified() != modifiedBefore || getLoader()->isDirty()) { qDebug() << "updating image..."; getThumb()->setImage(QImage()); clear(); } // null file? if (fileInfo.fileName().isEmpty() || !fileInfo.exists()) { QString msg = tr("Sorry, the file: %1 does not exist... ").arg(fileName()); emit showInfoSignal(msg); mLoadState = exists_not; return false; } else if (!fileInfo.permission(QFile::ReadUser)) { QString msg = tr("Sorry, you are not allowed to read: %1").arg(fileName()); emit showInfoSignal(msg); mLoadState = exists_not; return false; } #ifdef WITH_QUAZIP //zip archives: use the image file info from now on if(isFromZip()) setFilePath(getZipData()->getImageFileName()); #endif mLoadState = loading; fetchFile(); return true; }
void PackCom::patchLoader(OutputFile *fo, upx_byte *loader, int lsize, unsigned calls) { const int e_len = getLoaderSectionStart("COMCUTPO"); const int d_len = lsize - e_len; assert(e_len > 0 && e_len < 128); assert(d_len > 0 && d_len < 256); const unsigned upper_end = ph.u_len + ph.overlap_overhead + d_len + 0x100; unsigned stacksize = 0x60; if (upper_end + stacksize > 0xfffe) stacksize = 0x56; if (upper_end + stacksize > 0xfffe) throwCantPack("file is too big for dos/com"); linker->defineSymbol("calltrick_calls", calls); linker->defineSymbol("sp_limit", upper_end + stacksize); linker->defineSymbol("bytes_to_copy", ph.c_len + lsize); linker->defineSymbol("copy_source", ph.c_len + lsize + 0x100); linker->defineSymbol("copy_destination", upper_end); linker->defineSymbol("neg_e_len", 0 - e_len); linker->defineSymbol("NRV2B160", ph.u_len + ph.overlap_overhead); relocateLoader(); loader = getLoader(); // some day we could use the relocation stuff for patchPackHeader too patchPackHeader(loader,e_len); // write loader + compressed file fo->write(loader,e_len); // entry fo->write(obuf,ph.c_len); fo->write(loader+e_len,d_len); // decompressor #if 0 printf("%-13s: entry : %8ld bytes\n", getName(), (long) e_len); printf("%-13s: compressed : %8ld bytes\n", getName(), (long) ph.c_len); printf("%-13s: decompressor : %8ld bytes\n", getName(), (long) d_len); #endif }
void DkImageContainerT::fetchImage() { if (mFetchingBuffer) mBufferWatcher.waitForFinished(); if (mFetchingImage) { mLoadState = loading; return; } if (getLoader()->hasImage() || /*!fileBuffer || fileBuffer->isEmpty() ||*/ mLoadState == exists_not) { loadingFinished(); return; } qDebug() << "fetching: " << filePath(); mFetchingImage = true; connect(&mImageWatcher, SIGNAL(finished()), this, SLOT(imageLoaded()), Qt::UniqueConnection); mImageWatcher.setFuture(QtConcurrent::run(this, &nmc::DkImageContainerT::loadImageIntern, filePath(), mLoader, mFileBuffer)); }
//Load firm into FCRAM void loadFirm(void){ //Read FIRM from SD card and write to FCRAM fopen("/rei/firmware.bin", "rb"); firmSize = fsize()/2; if(PDN_MPCORE_CFG == 1) fseek(firmSize); fread(firmLocation, 1, firmSize); fclose(); decryptFirm(firmLocation, firmSize); //Initial setup firm = firmLocation; section = firm->section; keyInit(firmLocation + section[2].offset); //Set MPU for emu/thread code region getMPU(firmLocation, firmSize, &mpuOffset); memcpy((u8*)mpuOffset, mpu, sizeof(mpu)); //Inject custom loader fopen("/rei/loader.cxi", "rb"); u8 *arm11SysMods = (u8 *)firm + section[0].offset; Size ldrInFirmSize; Size ldrFileSize = fsize(); getLoader(arm11SysMods, &ldrInFirmSize, &ldrOffset); memcpy(section[0].address, arm11SysMods, ldrOffset); fread(section[0].address + ldrOffset, 1, ldrFileSize); memcpy(section[0].address + ldrOffset + ldrFileSize, arm11SysMods + ldrOffset + ldrInFirmSize, section[0].size - (ldrOffset + ldrInFirmSize)); fclose(); //Dont boot emu if AGB game was just played, or if START was held. getEmunandSect(&emuOffset, &emuHeader); if((HID & 0xFFF) == (1 << 3) || CFG_BOOTENV == 0x7 || !(emuOffset | emuHeader)) loadSys(); else loadEmu(); }
DiskDir *DiskDir::createNew(const char *dir) const { return new DiskDir(dir, getLoader()); }
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
void PackTos::pack(OutputFile *fo) { unsigned t; unsigned nrelocs = 0; unsigned relocsize = 0; unsigned overlay = 0; const unsigned i_text = ih.fh_text; const unsigned i_data = ih.fh_data; const unsigned i_sym = ih.fh_sym; const unsigned i_bss = ih.fh_bss; symbols.reset(); symbols.need_reloc = false; // prepare symbols for buildLoader() - worst case symbols.loop1.init(65536 + 1); symbols.loop2.init((160 - 1) / 4); symbols.loop3.init(65536 + 1); symbols.up21_d4 = 65536 + 1; symbols.up21_a6 = 65536 + 1; symbols.up31_base_d4 = 65536 + 1; symbols.up31_base_a6 = 65536 + 1; // read file const unsigned isize = file_size - i_sym; ibuf.alloc(isize); fi->seek(FH_SIZE, SEEK_SET); // read text + data t = i_text + i_data; fi->readx(ibuf,t); // skip symbols if (i_sym && opt->exact) throwCantPackExact(); fi->seek(i_sym,SEEK_CUR); // read relocations + overlay overlay = file_size - (FH_SIZE + i_text + i_data + i_sym); fi->readx(ibuf+t,overlay); #if 0 || (TESTING) printf("text: %d, data: %d, sym: %d, bss: %d, flags=0x%x\n", i_text, i_data, i_sym, i_bss, (int)ih.fh_flag); printf("xx1 reloc: %d, overlay: %d, fixup: %d\n", relocsize, overlay, overlay >= 4 ? (int)get_be32(ibuf+t) : -1); #endif // Check relocs (see load_and_reloc() in freemint/sys/memory.c). // Must work around TOS bugs and lots of broken programs. if (overlay < 4) { // Bug workaround: Whatever this is, silently keep it in // the (unused) relocations for byte-identical unpacking. relocsize = overlay; overlay = 0; } else if (get_be32(ibuf+t) == 0) { // Bug workaround - check the empty fixup before testing fh_reloc. relocsize = 4; overlay -= 4; } else if (ih.fh_reloc != 0) relocsize = 0; else { int r = check_relocs(ibuf+t, overlay, t, &nrelocs, &relocsize, &overlay); if (r != 0) throwCantPack("bad relocation table"); symbols.need_reloc = true; } #if 0 || (TESTING) printf("xx2: %d relocs: %d, overlay: %d, t: %d\n", nrelocs, relocsize, overlay, t); #endif checkOverlay(overlay); // Append original fileheader. t += relocsize; ih.fh_sym = 0; // we stripped all symbols memcpy(ibuf+t, &ih, FH_SIZE); t += FH_SIZE; #if 0 || (TESTING) printf("xx3 reloc: %d, overlay: %d, t: %d\n", relocsize, overlay, t); #endif assert(t <= isize); // Now the data in ibuf[0..t] looks like this: // text + data + relocs + original file header // After compression this will become the first part of the // data segement. The second part will be the decompressor. // alloc buffer (4096 is for decompressor and the various alignments) obuf.allocForCompression(t, 4096); // prepare packheader ph.u_len = t; // prepare filter Filter ft(ph.level); // compress (max_match = 65535) upx_compress_config_t cconf; cconf.reset(); cconf.conf_ucl.max_match = 65535; cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28 KiB stack compressWithFilters(&ft, 512, &cconf); // // multipass buildLoader() // // save initial loader const unsigned initial_lsize = getLoaderSize(); unsigned last_lsize = initial_lsize; MemBuffer last_loader(last_lsize); memcpy(last_loader, getLoader(), last_lsize); unsigned o_text, o_data, o_bss; unsigned e_len, d_len, d_off; for (;;) { // The decompressed data will now get placed at this offset: unsigned offset = (ph.u_len + ph.overlap_overhead) - ph.c_len; // get loader const unsigned lsize = getLoaderSize(); e_len = getLoaderSectionStart("CUTPOINT"); d_len = lsize - e_len; assert((e_len & 3) == 0 && (d_len & 1) == 0); // compute section sizes o_text = e_len; o_data = ph.c_len; o_bss = i_bss; // word align len of compressed data while (o_data & 1) { obuf[o_data++] = 0; offset++; } // append decompressor (part 2 of loader) d_off = o_data; ////memcpy(obuf + d_off, getLoader() + e_len, d_len); // must be done after relocation o_data += d_len; // dword align the len of the final data segment while (o_data & 3) { obuf[o_data++] = 0; offset++; } // dword align offset while (offset & 3) offset++; // new bss if (i_text + i_data + i_bss > o_text + o_data + o_bss) o_bss = (i_text + i_data + i_bss) - (o_text + o_data); // dirty bss unsigned dirty_bss = (o_data + offset) - (i_text + i_data); //printf("real dirty_bss: %d\n", dirty_bss); // dword align (or 16 - for speedup when clearing the dirty bss) const unsigned dirty_bss_align = opt->small ? 4 : 16; while (dirty_bss & (dirty_bss_align - 1)) dirty_bss++; // adjust bss, assert room for some stack unsigned stack = 512 + getDecompressorWrkmemSize(); if (dirty_bss + stack > o_bss) o_bss = dirty_bss + stack; // dword align the len of the final bss segment while (o_bss & 3) o_bss++; // update symbols for buildLoader() if (opt->small) { symbols.loop1.init(o_data / 4); symbols.loop2.init(0); } else { symbols.loop1.init(o_data / 160); symbols.loop2.init((o_data % 160) / 4); } symbols.loop3.init(dirty_bss / dirty_bss_align); symbols.up21_d4 = o_data + offset; symbols.up31_base_d4 = d_off + offset; symbols.up21_a6 = symbols.up21_d4 - (i_text + i_data); symbols.up31_base_a6 = symbols.up31_base_d4 - (i_text + i_data); assert((int)symbols.up21_a6 > 0); assert((int)symbols.up31_base_a6 > 0); const unsigned c = linker->getSymbolOffset("code_on_stack"); unsigned d; d = linker->getSymbolOffset("flush_cache_rts") - c; symbols.flush_cache_rts_offset = d; d = linker->getSymbolOffset("clear_dirty_stack_loop") - c; symbols.clear_dirty_stack_len = (d + 3) / 4 + 32 - 1; d = linker->getSymbolOffset("code_on_stack_end") - c; symbols.copy_to_stack_len = d / 2 - 1; // now re-build loader buildLoader(&ft); unsigned new_lsize = getLoaderSize(); //printf("buildLoader %d %d\n", new_lsize, initial_lsize); assert(new_lsize <= initial_lsize); if (new_lsize == last_lsize && memcmp(getLoader(), last_loader, last_lsize) == 0) break; last_lsize = new_lsize; memcpy(last_loader, getLoader(), last_lsize); } // // define symbols and reloc // defineDecompressorSymbols(); linker->defineSymbol("loop1_count", symbols.loop1.value); linker->defineSymbol("loop2_count", symbols.loop2.value); linker->defineSymbol("loop3_count", symbols.loop3.value); linker->defineSymbol("orig_p_tlen", i_text); linker->defineSymbol("orig_p_dlen", i_data); linker->defineSymbol("orig_p_blen", i_bss); if (symbols.up21_a6 <= 32767) linker->defineSymbol("up21_a6", symbols.up21_a6); else linker->defineSymbol("up21_d4", symbols.up21_d4); if (symbols.up31_a6 <= 32767) linker->defineSymbol("up31_a6", symbols.up31_a6); else if (symbols.up31_d4 <= 32767) linker->defineSymbol("up31_d4", symbols.up31_d4); else if (symbols.up31_a6 <= 65534) linker->defineSymbol("up31_a6", symbols.up31_a6 - 32767); else linker->defineSymbol("up31_d4", symbols.up31_d4); #if 0 printf("relocsize = %d\n", relocsize); printf("upx21(d4) = %d\n", symbols.up21_d4); printf("upx21(a6) = %d\n", symbols.up21_a6); printf("upx31(d4) = %d\n", symbols.up31_d4); printf("upx31(a6) = %d\n", symbols.up31_a6); #endif linker->defineSymbol("flush_cache_rts_offset", symbols.flush_cache_rts_offset); linker->defineSymbol("copy_to_stack_len", symbols.copy_to_stack_len); linker->defineSymbol("clear_dirty_stack_len", symbols.clear_dirty_stack_len); relocateLoader(); // // write // // set new file_hdr memcpy(&oh, &ih, FH_SIZE); if (opt->atari_tos.split_segments) { oh.fh_text = o_text; oh.fh_data = o_data; } else { // put everything into the text segment oh.fh_text = o_text + o_data; oh.fh_data = 0; } oh.fh_bss = o_bss; oh.fh_sym = 0; oh.fh_reserved = 0; // only keep the following flags: oh.fh_flag = ih.fh_flag & (F_FASTLOAD | F_ALTALLOC | F_SMALLTPA | F_ALLOCZERO | F_KEEP); // add an empty relocation fixup to workaround a bug in some TOS versions oh.fh_reloc = 0; #if 0 || (TESTING) printf("old text: %6d, data: %6d, bss: %6d, reloc: %d, overlay: %d\n", i_text, i_data, i_bss, relocsize, overlay); printf("new text: %6d, data: %6d, bss: %6d, flag=0x%x\n", o_text, o_data, o_bss, (int)oh.fh_flag); linker->dumpSymbols(); #endif // prepare loader MemBuffer loader(o_text); memcpy(loader, getLoader(), o_text); patchPackHeader(loader, o_text); // write new file header, loader and compressed file fo->write(&oh, FH_SIZE); fo->write(loader, o_text); // entry if (opt->debug.dump_stub_loader) OutputFile::dump(opt->debug.dump_stub_loader, loader, o_text); memcpy(obuf + d_off, getLoader() + e_len, d_len); // copy decompressor fo->write(obuf, o_data); // compressed + decompressor // write empty relocation fixup fo->write("\x00\x00\x00\x00", 4); // verify verifyOverlappingDecompression(); // copy the overlay copyOverlay(fo, overlay, &obuf); // finally check the compression ratio if (!checkFinalCompressionRatio(fo)) throwNotCompressible(); }
int main(int argc,char **argv) { QCoreApplication app(argc,argv); if(app.arguments().size()<2) { showSupportedBinTypes(); return -1; } BinType bin_type = getLoader(app.arguments()[1]); if(bin_type==eInvalid) { qCritical() << "Unhandled bin file type"; showSupportedBinTypes(); return -1; } BinStore binfile; binfile.open(argv[1],0); QString target_basename=QFileInfo(argv[1]).baseName(); bool json_output=true; try // handle possible cereal::RapidJSONException { if(app.arguments().size()>2) json_output = app.arguments()[2].toInt()!=0; switch(bin_type) { case eLevelsDebts: doConvert(doLoadRef<LevelExpAndDebt>(&binfile),target_basename,json_output); break; case eCombineChances: doConvert(doLoadRef<Parse_Combining>(&binfile),target_basename,json_output); break; case eBoostEffectiveness: doConvert(doLoadRef<Parse_Effectiveness>(&binfile),target_basename,json_output); break; case eParticleSystems:doConvert(doLoad<Parse_AllPSystems>(&binfile),target_basename,json_output); break; case eShops: doConvert(doLoadRef<AllShops_Data>(&binfile),target_basename,json_output); break; case eShopItems: doConvert(doLoad<AllShopItems_Data>(&binfile),target_basename,json_output); break; case eShopDepts: doConvert(doLoad<AllShopDepts_Data>(&binfile),target_basename,json_output); break; // case eSequencers: doConvert(doLoad<SequencerList>(&binfile),target_basename,json_output); break; case eTailorCosts: doConvert(doLoad<AllTailorCosts_Data>(&binfile),target_basename,json_output); break; case eCostumeSets: doConvert(doLoad<CostumeSet_Data>(&binfile),target_basename,json_output); break; case eBodyParts: doConvert(doLoad<AllBodyParts_Data>(&binfile),target_basename,json_output); break; case eGroupEmblems: doConvert(doLoad<GeoSet_Data>(&binfile),target_basename,json_output); break; case ePaletteSets: doConvert(doLoad<Pallette_Data>(&binfile),target_basename,json_output); break; case eZones: doConvert(doLoadRef<AllMaps_Data>(&binfile),target_basename,json_output); break; case eAttribNames: doConvert(doLoadRef<AttribNames_Data>(&binfile),target_basename,json_output); break; case eSceneGraph: doConvert(doLoadRef<SceneGraph_Data>(&binfile),target_basename,json_output); break; case eTrickDefinitions: doConvert(doLoadRef<SceneModifiers>(&binfile),target_basename,json_output); break; case eEntityClasses: doConvert(doLoadRef<Parse_AllCharClasses>(&binfile),target_basename,json_output); break; case eEntityOrigins: doConvert(doLoadRef<Parse_AllOrigins>(&binfile),target_basename,json_output); break; case ePowerDefinitions: doConvert(doLoadRef<AllPowerCategories>(&binfile),target_basename,json_output); break; case eNpcDefinitions: { auto data = doLoadRef<AllNpcs_Data>(&binfile); if (qApp->arguments().size() > 2) { QString name_to_find = app.arguments()[2]; std::sort(data->begin(), data->end(), [](const Parse_NPC &a, const Parse_NPC &b) -> bool { return QString(a.m_Name).compare(QString(b.m_Name), Qt::CaseInsensitive) < 0; }); auto iter = std::find_if(data->begin(), data->end(), [name_to_find](const Parse_NPC &n) -> bool { if (n.m_Name == name_to_find) return true; return false; }); qDebug() << iter - data->begin(); } else doConvert(data, target_basename, json_output); } break; case eFxBehavior_Definitions: doConvert(doLoadRef<Fx_AllBehaviors>(&binfile),target_basename,json_output); break; case eFxInfo_Definitions: doConvert(doLoadRef<Fx_AllInfos>(&binfile),target_basename,json_output); break; default: break; } } catch(cereal::RapidJSONException &e) { qWarning() << e.what(); return -1; } catch(std::exception &e) { qCritical() << e.what(); return -1; } return 0; }
void PackTmt::pack(OutputFile *fo) { big_relocs = 0; Packer::handleStub(fi,fo,adam_offset); const unsigned usize = ih.imagesize; const unsigned rsize = ih.relocsize; ibuf.alloc(usize+rsize+128); obuf.allocForCompression(usize+rsize+128); MemBuffer wrkmem; wrkmem.alloc(rsize+EXTRA_INFO); // relocations fi->seek(adam_offset+sizeof(ih),SEEK_SET); fi->readx(ibuf,usize); fi->readx(wrkmem+4,rsize); const unsigned overlay = file_size - fi->tell(); if (find_le32(ibuf,128,get_le32("UPX ")) >= 0) throwAlreadyPacked(); if (rsize == 0) throwCantPack("file is already compressed with another packer"); checkOverlay(overlay); unsigned relocsize = 0; //if (rsize) { for (unsigned ic=4; ic<=rsize; ic+=4) set_le32(wrkmem+ic,get_le32(wrkmem+ic)-4); relocsize = ptr_diff(optimizeReloc32(wrkmem+4,rsize/4,wrkmem,ibuf,1,&big_relocs), wrkmem); } wrkmem[relocsize++] = 0; set_le32(wrkmem+relocsize,ih.entry); // save original entry point relocsize += 4; set_le32(wrkmem+relocsize,relocsize+4); relocsize += 4; memcpy(ibuf+usize,wrkmem,relocsize); // prepare packheader ph.u_len = usize + relocsize; // prepare filter Filter ft(ph.level); ft.buf_len = usize; // 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: ~28 KiB stack compressWithFilters(&ft, 512, &cconf); const unsigned lsize = getLoaderSize(); const unsigned s_point = getLoaderSection("TMTMAIN1"); int e_len = getLoaderSectionStart("TMTCUTPO"); const unsigned d_len = lsize - e_len; assert(e_len > 0 && s_point > 0); // patch loader linker->defineSymbol("original_entry", ih.entry); defineDecompressorSymbols(); defineFilterSymbols(&ft); linker->defineSymbol("bytes_to_copy", ph.c_len + d_len); linker->defineSymbol("copy_dest", 0u - (ph.u_len + ph.overlap_overhead + d_len - 1)); linker->defineSymbol("copy_source", ph.c_len + lsize - 1); //fprintf(stderr,"\nelen=%x dlen=%x copy_len=%x copy_to=%x oo=%x jmp_pos=%x ulen=%x c_len=%x \n\n", // e_len,d_len,copy_len,copy_to,ph.overlap_overhead,jmp_pos,ph.u_len,ph.c_len); linker->defineSymbol("TMTCUTPO", ph.u_len + ph.overlap_overhead); relocateLoader(); MemBuffer loader(lsize); memcpy(loader,getLoader(),lsize); patchPackHeader(loader,e_len); memcpy(&oh,&ih,sizeof(oh)); oh.imagesize = ph.c_len + lsize; // new size oh.entry = s_point; // new entry point oh.relocsize = 4; // write loader + compressed file fo->write(&oh,sizeof(oh)); fo->write(loader,e_len); fo->write(obuf,ph.c_len); fo->write(loader+lsize-d_len,d_len); // decompressor char rel_entry[4]; set_le32(rel_entry,5 + s_point); fo->write(rel_entry,sizeof (rel_entry)); // verify verifyOverlappingDecompression(); // copy the overlay copyOverlay(fo, overlay, &obuf); // finally check the compression ratio if (!checkFinalCompressionRatio(fo)) throwNotCompressible(); }
void release_loader() { getLoader()->Release(); }
void PackWcle::pack(OutputFile *fo) { handleStub(fo); if (ih.byte_order || ih.word_order || ih.exe_format_level || ih.cpu_type < 2 || ih.cpu_type > 5 || ih.target_os != 1 || ih.module_type != 0x200 || ih.object_iterate_data_map_offset || ih.resource_entries || ih.module_directives_entries || ih.imported_modules_count || ih.object_table_entries > 255) throwCantPack("watcom/le: unexpected value in header"); readObjectTable(); readPageMap(); readResidentNames(); readEntryTable(); readFixupPageTable(); readFixups(); readImage(); readNonResidentNames(); // if (find_le32(iimage,20,get_le32("UPX ")) >= 0) if (find_le32(iimage,UPX_MIN(soimage,256u),UPX_MAGIC_LE32) >= 0) throwAlreadyPacked(); if (ih.init_ss_object != objects) throwCantPack("the stack is not in the last object"); preprocessFixups(); const unsigned text_size = IOT(ih.init_cs_object-1,npages) * mps; const unsigned text_vaddr = IOT(ih.init_cs_object-1,my_base_address); // attach some useful data at the end of preprocessed fixups ifixups[sofixups++] = (unsigned char) (ih.automatic_data_object & 0xff); unsigned ic = objects*sizeof(*iobject_table); memcpy(ifixups+sofixups,iobject_desc,ic); iobject_desc.dealloc(); sofixups += ic; set_le32(ifixups+sofixups,ih.init_esp_offset+IOT(ih.init_ss_object-1,my_base_address)); // old stack pointer set_le32(ifixups+sofixups+4,ih.init_eip_offset+text_vaddr); // real entry point set_le32(ifixups+sofixups+8,mps*pages); // virtual address of unpacked relocations ifixups[sofixups+12] = (unsigned char) (unsigned) objects; sofixups += 13; // prepare filter Filter ft(ph.level); ft.buf_len = text_size; ft.addvalue = text_vaddr; // compress encodeImage(&ft); const unsigned lsize = getLoaderSize(); neweip = getLoaderSection("WCLEMAIN"); int e_len = getLoaderSectionStart("WCLECUTP"); const unsigned d_len = lsize - e_len; assert(e_len > 0 && e_len < RESERVED); memmove(oimage+e_len,oimage+RESERVED,soimage); soimage += lsize; opages = (soimage+mps-1)/mps; oh.bytes_on_last_page = soimage%mps; encodeObjectTable(); encodeFixups(); encodeFixupPageTable(); encodePageMap(); encodeEntryTable(); encodeResidentNames(); encodeNonResidentNames(); // patch loader ic = (OOT(0,virtual_size) - d_len) &~ 15; assert(ic > ((ph.u_len + ph.overlap_overhead + 31) &~ 15)); linker->defineSymbol("WCLECUTP", ic); linker->defineSymbol("original_entry", ih.init_eip_offset + text_vaddr); linker->defineSymbol("original_stack", ih.init_esp_offset + IOT(ih.init_ss_object - 1, my_base_address)); linker->defineSymbol("start_of_relocs", mps*pages); defineDecompressorSymbols(); defineFilterSymbols(&ft); linker->defineSymbol("filter_buffer_start", text_vaddr); unsigned jpos = (((ph.c_len + 3) &~ 3) + d_len + 3) / 4; linker->defineSymbol("words_to_copy", jpos); linker->defineSymbol("copy_dest", ((ic + d_len + 3) &~ 3) - 4); linker->defineSymbol("copy_source", e_len + jpos * 4 - 4); relocateLoader(); MemBuffer loader(lsize); memcpy(loader, getLoader(), lsize); patchPackHeader(loader, lsize); memcpy(oimage, loader, e_len); memcpy(oimage + soimage - d_len, loader + e_len, d_len); writeFile(fo, opt->watcom_le.le); // verify verifyOverlappingDecompression(oimage + e_len, oimage.getSize() - e_len); // copy the overlay const unsigned overlaystart = ih.data_pages_offset + exe_offset + getImageSize(); const unsigned overlay = file_size - overlaystart - ih.non_resident_name_table_length; checkOverlay(overlay); copyOverlay(fo, overlay, &oimage); // finally check the compression ratio if (!checkFinalCompressionRatio(fo)) throwNotCompressible(); }
Track::Track(GLint givenVertexBufferLoc, GLint givenNormalBufferLoc) { setLoader(new ObjLoader()); ObjLoader * myLoaderRef = getLoader(); myLoaderRef -> loadObj(TRACK_PATH, MTL_BASEPATH); // In this OpenGL program, x-z is the horizontal plane. // The following code snippet grabs the x and z coordinates of all the // vertices that are at the bottom of the inner walls of the track. //std::cout << "ListPlot[ { " << std::endl; std::vector<GLfloat> vertices = myLoaderRef->getVertices(); for (int i = 0; i < vertices.size(); i += 3) { if (vertices[i + 1] > 1) continue; //if (i) std::cout << ", "; //std::cout << "{" << vertices[i] << ", " << vertices[i + 2] << "}"; walls.push_back(glm::vec2(vertices[i], vertices[i+2])); } //std::cout << " } ]" << std::endl; glGenBuffers(1, &vertexBuffer); glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); glBufferData(GL_ARRAY_BUFFER, myLoaderRef -> getVertices().size() * sizeof(GLfloat), myLoaderRef -> getVertices().data(), GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); glGenBuffers(1, &normalBuffer); glBindBuffer(GL_ARRAY_BUFFER, normalBuffer); glBufferData(GL_ARRAY_BUFFER, myLoaderRef -> getNormals().size() * sizeof(GLfloat), myLoaderRef -> getNormals().data(), GL_STATIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); glGenBuffers(1, &indexBuffer); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer); glBufferData(GL_ELEMENT_ARRAY_BUFFER, myLoaderRef -> getIndices().size() * sizeof(GLuint), myLoaderRef -> getIndices().data(), GL_STATIC_DRAW); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); vertexCount = (unsigned int) myLoaderRef -> getIndices().size(); // setup initial model matrix scaleMatrix = glm::translate(glm::mat4(1.0f), glm::vec3(0.0f, -1.0f, 0.0f)) * glm::mat4(1.0f); setModelMatrix(scaleMatrix); // wrap states using vao glGenVertexArraysAPPLE(1, &vertexArrayObjectHandle); glBindVertexArrayAPPLE(vertexArrayObjectHandle); // bind vertex array glEnableVertexAttribArray(givenVertexBufferLoc); glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); glVertexAttribPointer(givenVertexBufferLoc, 3, // to simplify program, we always use triangles GL_FLOAT, // type of elements in vertex buffer is GLfloat GL_FALSE, // not normalized 0, // to simplify program, we keep each object in a homogeneous buffer 0); glEnableVertexAttribArray(givenNormalBufferLoc); glBindBuffer(GL_ARRAY_BUFFER, normalBuffer); glVertexAttribPointer(givenNormalBufferLoc, 3, GL_FLOAT, GL_FALSE, 0, 0); // bind index array glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer); // finished: unbind vao to clear state glBindVertexArrayAPPLE(0); }
QSharedPointer<DkMetaDataT> DkImageContainer::getMetaData() { return getLoader()->getMetaData(); }
void DkImageContainer::setImage(const QImage& img, const QString& filePath) { setFilePath(mFilePath); getLoader()->setImage(img, filePath); mEdited = true; }
bool DkImageContainer::saveImage(const QString& filePath, int compression /* = -1 */) { return saveImage(filePath, getLoader()->image(), compression); }
bool DkImageContainer::setPageIdx(int skipIdx) { return getLoader()->setPageIdx(skipIdx); }
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(); }
XmlVisitor::XmlVisitor(Loader *aLoader) : loader(aLoader), elementHandler(getLoader()) { }