mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-04 10:19:23 +02:00
GP-3697 Added delayed ProjectFileManager disposal in support of URL use
and opening linked project files and renamed ProjectFileData to DefaultProjectData.
This commit is contained in:
parent
5ef4b269a1
commit
3eb642885c
51 changed files with 1636 additions and 813 deletions
|
@ -33,215 +33,219 @@ import ghidra.program.model.listing.*;
|
|||
import ghidra.program.model.mem.*;
|
||||
import ghidra.program.model.symbol.*;
|
||||
|
||||
|
||||
public class MergeTwoProgramsScript extends GhidraScript {
|
||||
|
||||
@Override
|
||||
protected void run() throws Exception {
|
||||
|
||||
if ( currentProgram == null ) {
|
||||
printerr( "Please open a program first!" );
|
||||
if (currentProgram == null) {
|
||||
printerr("Please open a program first!");
|
||||
return;
|
||||
}
|
||||
|
||||
Program otherProgram = askProgram( "Select program from which to merge: " );
|
||||
Program otherProgram = askProgram("Select program from which to merge: ");
|
||||
|
||||
if ( otherProgram == null ) {
|
||||
printerr( "Please select the other program first!" );
|
||||
if (otherProgram == null) {
|
||||
printerr("Please select the other program first!");
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !currentProgram.getLanguage().equals( otherProgram.getLanguage() ) ) {
|
||||
printerr( "Incompatible program languages!" );
|
||||
return;
|
||||
try {
|
||||
|
||||
if (!currentProgram.getLanguage().equals(otherProgram.getLanguage())) {
|
||||
printerr("Incompatible program languages!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (currentProgram.getMemory().intersects(otherProgram.getMemory())) {
|
||||
printerr("Memory map of current program must be disjoint from other program!");
|
||||
return;
|
||||
}
|
||||
|
||||
openProgram(currentProgram);
|
||||
|
||||
mergeMemory(currentProgram, otherProgram);
|
||||
mergeSymbols(currentProgram, otherProgram);
|
||||
mergeBookmarks(currentProgram, otherProgram);
|
||||
mergeComments(currentProgram, otherProgram);
|
||||
mergeData(currentProgram, otherProgram);
|
||||
mergeInstructions(currentProgram, otherProgram);
|
||||
mergeEquates(currentProgram, otherProgram);
|
||||
mergeReferences(currentProgram, otherProgram);
|
||||
}
|
||||
|
||||
if ( currentProgram.getMemory().intersects( otherProgram.getMemory() ) ) {
|
||||
printerr( "Memory map of current program must be disjoint from other program!" );
|
||||
return;
|
||||
finally {
|
||||
otherProgram.release(this);
|
||||
}
|
||||
|
||||
openProgram( currentProgram );
|
||||
|
||||
mergeMemory ( currentProgram, otherProgram );
|
||||
mergeSymbols ( currentProgram, otherProgram );
|
||||
mergeBookmarks ( currentProgram, otherProgram );
|
||||
mergeComments ( currentProgram, otherProgram );
|
||||
mergeData ( currentProgram, otherProgram );
|
||||
mergeInstructions( currentProgram, otherProgram );
|
||||
mergeEquates ( currentProgram, otherProgram );
|
||||
mergeReferences ( currentProgram, otherProgram );
|
||||
}
|
||||
|
||||
private void mergeReferences( Program currProgram, Program otherProgram ) {
|
||||
monitor.setMessage( "Merging references..." );
|
||||
private void mergeReferences(Program currProgram, Program otherProgram) {
|
||||
monitor.setMessage("Merging references...");
|
||||
ReferenceManager currentReferenceManager = currProgram.getReferenceManager();
|
||||
ReferenceManager otherReferenceManager = otherProgram.getReferenceManager();
|
||||
ReferenceIterator otherReferenceIterator = otherReferenceManager.getReferenceIterator( otherProgram.getMinAddress() );
|
||||
while ( otherReferenceIterator.hasNext() ) {
|
||||
if ( monitor.isCancelled() ) {
|
||||
ReferenceIterator otherReferenceIterator =
|
||||
otherReferenceManager.getReferenceIterator(otherProgram.getMinAddress());
|
||||
while (otherReferenceIterator.hasNext()) {
|
||||
if (monitor.isCancelled()) {
|
||||
break;
|
||||
}
|
||||
Reference otherReference = otherReferenceIterator.next();
|
||||
if ( otherReference.isStackReference() ) {
|
||||
if (otherReference.isStackReference()) {
|
||||
continue;
|
||||
}
|
||||
currentReferenceManager.addReference( otherReference );
|
||||
currentReferenceManager.addReference(otherReference);
|
||||
}
|
||||
}
|
||||
|
||||
private void mergeInstructions( Program currProgram, Program otherProgram ) {
|
||||
monitor.setMessage( "Merging instructions..." );
|
||||
private void mergeInstructions(Program currProgram, Program otherProgram) {
|
||||
monitor.setMessage("Merging instructions...");
|
||||
Listing currentListing = currProgram.getListing();
|
||||
Listing otherListing = otherProgram.getListing();
|
||||
InstructionIterator otherInstructions = otherListing.getInstructions( true );
|
||||
while ( otherInstructions.hasNext() ) {
|
||||
if ( monitor.isCancelled() ) {
|
||||
InstructionIterator otherInstructions = otherListing.getInstructions(true);
|
||||
while (otherInstructions.hasNext()) {
|
||||
if (monitor.isCancelled()) {
|
||||
break;
|
||||
}
|
||||
Instruction otherInstruction = otherInstructions.next();
|
||||
if ( currentListing.isUndefined( otherInstruction.getMinAddress(), otherInstruction.getMaxAddress() ) ) {
|
||||
disassemble( otherInstruction.getMinAddress() );
|
||||
if (currentListing.isUndefined(otherInstruction.getMinAddress(),
|
||||
otherInstruction.getMaxAddress())) {
|
||||
disassemble(otherInstruction.getMinAddress());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void mergeEquates( Program currProgram, Program otherProgram ) throws Exception {
|
||||
monitor.setMessage( "Merging equates..." );
|
||||
private void mergeEquates(Program currProgram, Program otherProgram) throws Exception {
|
||||
monitor.setMessage("Merging equates...");
|
||||
EquateTable currentEquateTable = currProgram.getEquateTable();
|
||||
EquateTable otherEquateTable = otherProgram.getEquateTable();
|
||||
Iterator<Equate> otherEquates = otherEquateTable.getEquates();
|
||||
while ( otherEquates.hasNext() ) {
|
||||
if ( monitor.isCancelled() ) {
|
||||
while (otherEquates.hasNext()) {
|
||||
if (monitor.isCancelled()) {
|
||||
break;
|
||||
}
|
||||
Equate otherEquate = otherEquates.next();
|
||||
Equate currentEquate = currentEquateTable.createEquate( otherEquate.getName(), otherEquate.getValue() );
|
||||
EquateReference [] otherEquateReferences = otherEquate.getReferences();
|
||||
for ( EquateReference otherEquateReference : otherEquateReferences ) {
|
||||
if ( monitor.isCancelled() ) {
|
||||
Equate currentEquate =
|
||||
currentEquateTable.createEquate(otherEquate.getName(), otherEquate.getValue());
|
||||
EquateReference[] otherEquateReferences = otherEquate.getReferences();
|
||||
for (EquateReference otherEquateReference : otherEquateReferences) {
|
||||
if (monitor.isCancelled()) {
|
||||
break;
|
||||
}
|
||||
currentEquate.addReference( otherEquateReference.getAddress(), otherEquateReference.getOpIndex() );
|
||||
currentEquate.addReference(otherEquateReference.getAddress(),
|
||||
otherEquateReference.getOpIndex());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void mergeData( Program currProgram, Program otherProgram ) throws Exception {
|
||||
monitor.setMessage( "Merging data..." );
|
||||
private void mergeData(Program currProgram, Program otherProgram) throws Exception {
|
||||
monitor.setMessage("Merging data...");
|
||||
Listing currentListing = currProgram.getListing();
|
||||
Listing otherListing = otherProgram.getListing();
|
||||
DataIterator otherDataIterator = otherListing.getDefinedData( true );
|
||||
while ( otherDataIterator.hasNext() ) {
|
||||
if ( monitor.isCancelled() ) {
|
||||
DataIterator otherDataIterator = otherListing.getDefinedData(true);
|
||||
while (otherDataIterator.hasNext()) {
|
||||
if (monitor.isCancelled()) {
|
||||
break;
|
||||
}
|
||||
Data otherData = otherDataIterator.next();
|
||||
if ( currentListing.isUndefined( otherData.getMinAddress(), otherData.getMaxAddress() ) ) {
|
||||
currentListing.createData( otherData.getMinAddress(), otherData.getDataType() );
|
||||
if (currentListing.isUndefined(otherData.getMinAddress(), otherData.getMaxAddress())) {
|
||||
currentListing.createData(otherData.getMinAddress(), otherData.getDataType());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void mergeComments( Program currProgram, Program otherProgram ) throws Exception {
|
||||
monitor.setMessage( "Merging comments..." );
|
||||
int [] commentTypes = {
|
||||
CodeUnit.EOL_COMMENT,
|
||||
CodeUnit.PRE_COMMENT,
|
||||
CodeUnit.POST_COMMENT,
|
||||
CodeUnit.PLATE_COMMENT,
|
||||
CodeUnit.REPEATABLE_COMMENT,
|
||||
};
|
||||
private void mergeComments(Program currProgram, Program otherProgram) throws Exception {
|
||||
monitor.setMessage("Merging comments...");
|
||||
int[] commentTypes = { CodeUnit.EOL_COMMENT, CodeUnit.PRE_COMMENT, CodeUnit.POST_COMMENT,
|
||||
CodeUnit.PLATE_COMMENT, CodeUnit.REPEATABLE_COMMENT, };
|
||||
Listing currentListing = currProgram.getListing();
|
||||
Listing otherListing = otherProgram.getListing();
|
||||
CodeUnitIterator otherCodeUnits = otherListing.getCodeUnits( true );
|
||||
while ( otherCodeUnits.hasNext() ) {
|
||||
if ( monitor.isCancelled() ) {
|
||||
CodeUnitIterator otherCodeUnits = otherListing.getCodeUnits(true);
|
||||
while (otherCodeUnits.hasNext()) {
|
||||
if (monitor.isCancelled()) {
|
||||
break;
|
||||
}
|
||||
CodeUnit otherCodeUnit = otherCodeUnits.next();
|
||||
for ( int commentType : commentTypes ) {
|
||||
if ( monitor.isCancelled() ) {
|
||||
for (int commentType : commentTypes) {
|
||||
if (monitor.isCancelled()) {
|
||||
break;
|
||||
}
|
||||
String otherComment = otherCodeUnit.getComment( commentType );
|
||||
if ( otherComment != null ) {
|
||||
currentListing.setComment( otherCodeUnit.getAddress(), commentType, otherComment );
|
||||
String otherComment = otherCodeUnit.getComment(commentType);
|
||||
if (otherComment != null) {
|
||||
currentListing.setComment(otherCodeUnit.getAddress(), commentType,
|
||||
otherComment);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void mergeBookmarks( Program currProgram, Program otherProgram ) {
|
||||
monitor.setMessage( "Merging bookmarks..." );
|
||||
private void mergeBookmarks(Program currProgram, Program otherProgram) {
|
||||
monitor.setMessage("Merging bookmarks...");
|
||||
BookmarkManager currentBookmarkManager = currProgram.getBookmarkManager();
|
||||
BookmarkManager otherBookmarkManager = otherProgram.getBookmarkManager();
|
||||
Iterator<Bookmark> otherBookmarks = otherBookmarkManager.getBookmarksIterator();
|
||||
while ( otherBookmarks.hasNext() ) {
|
||||
if ( monitor.isCancelled() ) {
|
||||
while (otherBookmarks.hasNext()) {
|
||||
if (monitor.isCancelled()) {
|
||||
break;
|
||||
}
|
||||
Bookmark otherBookmark = otherBookmarks.next();
|
||||
currentBookmarkManager.setBookmark( otherBookmark.getAddress(),
|
||||
otherBookmark.getTypeString(),
|
||||
otherBookmark.getCategory(),
|
||||
otherBookmark.getComment() );
|
||||
currentBookmarkManager.setBookmark(otherBookmark.getAddress(),
|
||||
otherBookmark.getTypeString(), otherBookmark.getCategory(),
|
||||
otherBookmark.getComment());
|
||||
}
|
||||
}
|
||||
|
||||
private void mergeSymbols( Program currProgram, Program otherProgram ) throws Exception {
|
||||
monitor.setMessage( "Merging symbols..." );
|
||||
private void mergeSymbols(Program currProgram, Program otherProgram) throws Exception {
|
||||
monitor.setMessage("Merging symbols...");
|
||||
SymbolTable currentSymbolTable = currProgram.getSymbolTable();
|
||||
SymbolTable otherSymbolTable = otherProgram.getSymbolTable();
|
||||
SymbolIterator otherSymbols = otherSymbolTable.getAllSymbols( false );
|
||||
while ( otherSymbols.hasNext() ) {
|
||||
if ( monitor.isCancelled() ) {
|
||||
SymbolIterator otherSymbols = otherSymbolTable.getAllSymbols(false);
|
||||
while (otherSymbols.hasNext()) {
|
||||
if (monitor.isCancelled()) {
|
||||
break;
|
||||
}
|
||||
Symbol otherSymbol = otherSymbols.next();
|
||||
if ( otherSymbol.isDynamic() ) {
|
||||
if (otherSymbol.isDynamic()) {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
Namespace otherNamespace = otherSymbol.getParentNamespace();
|
||||
Namespace currentNamespace = mirrorNamespace( currProgram, otherProgram, otherNamespace );
|
||||
if ( otherSymbol.getSymbolType() == SymbolType.FUNCTION ) {
|
||||
Function otherFunction = otherProgram.getListing().getFunctionAt( otherSymbol.getAddress() );
|
||||
currProgram.getListing().createFunction( otherSymbol.getName(),
|
||||
currentNamespace,
|
||||
otherFunction.getEntryPoint(),
|
||||
otherFunction.getBody(),
|
||||
SourceType.USER_DEFINED );
|
||||
Namespace currentNamespace =
|
||||
mirrorNamespace(currProgram, otherProgram, otherNamespace);
|
||||
if (otherSymbol.getSymbolType() == SymbolType.FUNCTION) {
|
||||
Function otherFunction =
|
||||
otherProgram.getListing().getFunctionAt(otherSymbol.getAddress());
|
||||
currProgram.getListing()
|
||||
.createFunction(otherSymbol.getName(), currentNamespace,
|
||||
otherFunction.getEntryPoint(), otherFunction.getBody(),
|
||||
SourceType.USER_DEFINED);
|
||||
}
|
||||
else {
|
||||
currentSymbolTable.createLabel( otherSymbol.getAddress(),
|
||||
otherSymbol.getName(),
|
||||
currentNamespace,
|
||||
SourceType.USER_DEFINED );
|
||||
currentSymbolTable.createLabel(otherSymbol.getAddress(), otherSymbol.getName(),
|
||||
currentNamespace, SourceType.USER_DEFINED);
|
||||
}
|
||||
}
|
||||
catch ( Exception e ) {
|
||||
printerr( "Unable to create symbol: " + otherSymbol.getName() );
|
||||
catch (Exception e) {
|
||||
printerr("Unable to create symbol: " + otherSymbol.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Namespace mirrorNamespace( Program currProgram, Program otherProgram, Namespace otherNamespace ) throws Exception {
|
||||
if ( otherNamespace == null ) {
|
||||
private Namespace mirrorNamespace(Program currProgram, Program otherProgram,
|
||||
Namespace otherNamespace) throws Exception {
|
||||
if (otherNamespace == null) {
|
||||
return currProgram.getGlobalNamespace();
|
||||
}
|
||||
SourceType source = SourceType.USER_DEFINED;//this will be default, since we are running a script!
|
||||
try {
|
||||
source = otherNamespace.getSymbol().getSource();
|
||||
}
|
||||
catch ( Exception e ) {
|
||||
catch (Exception e) {
|
||||
}
|
||||
return NamespaceUtils.createNamespaceHierarchy(otherNamespace.getName(true), null,
|
||||
currProgram, source);
|
||||
}
|
||||
|
||||
private void mergeMemory( Program currProgram, Program otherProgram ) throws Exception {
|
||||
monitor.setMessage( "Merging memory..." );
|
||||
private void mergeMemory(Program currProgram, Program otherProgram) throws Exception {
|
||||
monitor.setMessage("Merging memory...");
|
||||
Memory otherMemory = otherProgram.getMemory();
|
||||
MemoryBlock[] otherBlocks = otherMemory.getBlocks();
|
||||
MessageLog log = new MessageLog();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue