blargg_err_t Nes_Cart::load_patched_ines( Auto_File_Reader in, Auto_File_Reader patch ) { RETURN_ERR( in.open() ); RETURN_ERR( patch.open() ); // read file into memory long size = in->remain(); byte* ines = (byte*) malloc( size ); CHECK_ALLOC( ines ); const char* err = in->read( ines, size ); // apply patch if ( !err ) err = apply_ips_patch( *patch, &ines, &size ); // load patched file if ( !err ) { Mem_File_Reader patched( ines, size ); err = load_ines( patched ); } free( ines ); return err; }
void patcher_copy::diff () const { QDir(patched()).removeRecursively(); for(QString modified_file : modified_files()){ QFile original_file(original() + "/" + modified_file); QString patch_path = patched() + "/" + modified_file; QFile patch_file(patch_path); if(patch_file.exists()){ patch_file.remove(); } else{ QDir().mkpath(QFileInfo(patch_path).absolutePath()); } original_file.copy(patch_path); } }
void patcher_copy::patch () const { for(QString patched_file : patched_files()){ QString original_path = original() + "/" + patched_file; QFile original_file(original_path); QFile patch_file(patched() + "/" + patched_file); if(original_file.exists()){ original_file.remove(); } else{ QDir().mkpath(QFileInfo(original_path).absolutePath()); } patch_file.copy(original_path); if(utimes(original_path.toLocal8Bit(), NULL)){ qCritical() << "Could not update patch file time."; } } }
blargg_err_t Nes_Rom::load_patched_ines_rom( Data_Reader& in, Data_Reader& patch ) { // read file into memory long size = in.remain(); byte* ines = (byte*) malloc( size ); BLARGG_CHECK_ALLOC( ines ); const char* err = in.read( ines, size ); // apply patch if ( !err ) err = apply_ips_patch( patch, &ines, &size ); // load patched file if ( !err ) { Mem_File_Reader patched( ines, size ); err = load_ines_rom( patched ); } free( ines ); return err; }
static bool patchSearch(Oracle *oracle, const patchStrategy &input, patchQueueT &thingsToTry) { if (input.MustInterpret.empty()) return true; if (debug_declobber_instructions) input.prettyPrint(stdout); unsigned long needed = *input.MustInterpret.begin(); if (debug_declobber_instructions) printf("\tLook at %lx\n", needed); patchStrategy c(input); /* @needed is definitely going to be interpreted after * this. */ c.Cont.insert(needed); c.MustInterpret.erase(needed); /* Decide which maneuver to use here. We need to either patch @needed itself or bring all of its predecessors into the patch. */ /* Figure out which instructions might get clobbered by the * patch */ std::set<unsigned long> clobbered_by_patch; unsigned offset = 0; offset += getInstructionSize(oracle->ms->addressSpace, StaticRip(needed)); while (offset < 5) { clobbered_by_patch.insert(needed + offset); offset += getInstructionSize(oracle->ms->addressSpace, StaticRip(needed + offset)); } /* Can't use patch if that would clobber an external. */ bool can_use_patch = true; for (auto it = clobbered_by_patch.begin(); can_use_patch && it != clobbered_by_patch.end(); it++) { if (oracle->isFunctionHead(StaticRip(*it))) can_use_patch = false; } /* Can't use patch if that would clobber/be clobbered by an existing patch point. */ for (auto it = input.Patch.begin(); can_use_patch && it != input.Patch.end(); it++) { if (needed > *it - 5 && needed < *it + 5) can_use_patch = false; } if (can_use_patch) { /* Try using a patch. */ patchStrategy patched(c); patched.Patch.insert(needed); for (auto it = clobbered_by_patch.begin(); it != clobbered_by_patch.end(); it++) { patched.Cont.insert(*it); } for (auto it = clobbered_by_patch.begin(); it != clobbered_by_patch.end(); it++) { std::set<unsigned long> predecessors; oracle->findPredecessors(*it, predecessors); for (unsigned long y = needed; y < *it; y++) predecessors.erase(y); patched.Cont.insert(*it); patched.MustInterpret.erase(*it); patched.MustInterpret.insert(predecessors.begin(), predecessors.end()); } thingsToTry.push(patched); if (debug_declobber_instructions) { printf("Patch to: "); patched.prettyPrint(stdout); } } /* Try expanding to predecessors. */ std::set<unsigned long> predecessors; oracle->findPredecessors(needed, predecessors); c.MustInterpret.insert(predecessors.begin(), predecessors.end()); thingsToTry.push(c); if (debug_declobber_instructions) { printf("Unpatched: "); c.prettyPrint(stdout); } return false; }
void add( uint8_t* addr ) { DL_ASSERT( next_addr < DL_ARRAY_LENGTH( addresses ) ); DL_ASSERT( !patched( addr ) ); addresses[next_addr++] = addr; }