Skip to content
Permalink
Browse files Browse the repository at this point in the history
Merge remote-tracking branch 'origin/GT-3198_dev747368_fix_XMLDecoder…
…_github_1090' into Ghidra_9.1
  • Loading branch information
ryanmkurtz committed Oct 2, 2019
2 parents 03f2365 + 5adfe71 commit a17728f
Show file tree
Hide file tree
Showing 9 changed files with 436 additions and 47 deletions.
Expand Up @@ -16,7 +16,6 @@
//This script dumps information about byte and instructions in neighborhoods around function starts
//and returns to an XML file
//@category FunctionStartPatterns
import java.beans.XMLEncoder;
import java.io.*;
import java.util.List;

Expand Down Expand Up @@ -118,10 +117,7 @@ protected void run() throws Exception {
File savedFile = new File(saveDir.getAbsolutePath() + File.separator +
currentProgram.getDomainFile().getPathname().replaceAll("/", "_") + "_" +
currentProgram.getExecutableMD5() + "_funcInfo.xml");
try (XMLEncoder xmlEncoder =
new XMLEncoder(new BufferedOutputStream(new FileOutputStream(savedFile)))) {
xmlEncoder.writeObject(funcPatternList);
}
funcPatternList.toXmlFile(savedFile);
Msg.info(this,
"Programs analyzed: " + programsAnalyzed + "; total functions: " + totalFuncs);
}
Expand Down
Expand Up @@ -43,7 +43,7 @@ public void addContextInfo(List<ContextRegisterInfo> contextRegisterInfo) {
return;
}
for (ContextRegisterInfo cRegInfo : contextRegisterInfo) {
addRegisterAndValue(cRegInfo.getContextRegister(), cRegInfo.getValueAsBigInteger());
addRegisterAndValue(cRegInfo.getContextRegister(), cRegInfo.getValue());
}
}

Expand Down
Expand Up @@ -56,7 +56,7 @@ public void addRegAndValueToFilter(String contextRegister, BigInteger value) {
public boolean allows(List<ContextRegisterInfo> contextRegisterInfos) {
for (ContextRegisterInfo cInfo : contextRegisterInfos) {
if (contextRegisters.contains(cInfo.getContextRegister())) {
if (!values.get(cInfo.getContextRegister()).equals(cInfo.getValueAsBigInteger())) {
if (!values.get(cInfo.getContextRegister()).equals(cInfo.getValue())) {
return false;
}
}
Expand Down
Expand Up @@ -17,13 +17,17 @@

import java.math.BigInteger;

import org.jdom.Element;

/**
* class for representing the values a specific context register assumes within a function body.
*/
public class ContextRegisterInfo {

static final String XML_ELEMENT_NAME = "ContextRegisterInfo";

String contextRegister;//the context register
String value;//the value it assumes (needed because a BigInteger will not serialize to xml)
BigInteger valueAsBigInteger;//the value it assumes
BigInteger value;//the value it assumes

/**
* Default constructor (used by XMLEncoder)
Expand Down Expand Up @@ -55,22 +59,12 @@ public void setContextRegister(String contextRegister) {
this.contextRegister = contextRegister;
}

/**
* Returns the value associated with this {@link ContextRegisterInfo} object as a
* {@link BigInteger}.
* @return
*/
public BigInteger getValueAsBigInteger() {
return valueAsBigInteger;
}

/**
* Sets the value associated with this {@link ContextRegisterInfo} object
* @param valueAsBigInteger
* @param value
*/
public void setValue(BigInteger valueAsBigInteger) {
this.valueAsBigInteger = valueAsBigInteger;
this.value = valueAsBigInteger.toString();
public void setValue(BigInteger value) {
this.value = value;

}

Expand All @@ -79,19 +73,10 @@ public void setValue(BigInteger valueAsBigInteger) {
* {@link String}.
* @return
*/
public String getValue() {
public BigInteger getValue() {
return value;
}

/**
* Sets the value associated with this {@link ContextRegisterInfo} object
* @param value
*/
public void setValue(String value) {
this.value = value;
this.valueAsBigInteger = new BigInteger(value);
}

@Override
public String toString() {
StringBuilder sb = new StringBuilder();
Expand Down Expand Up @@ -133,4 +118,38 @@ public int hashCode() {
hashCode = 31 * hashCode + value.hashCode();
return hashCode;
}

/**
* Creates a {@link ContextRegisterInfo} object using data in the supplied XML node.
*
* @param ele xml Element
* @return new {@link ContextRegisterInfo} object, never null
*/
public static ContextRegisterInfo fromXml(Element ele) {

String contextRegister = ele.getAttributeValue("contextRegister");
String value = ele.getAttributeValue("value");

ContextRegisterInfo result = new ContextRegisterInfo();
result.setContextRegister(contextRegister);
result.setValue(value != null ? new BigInteger(value) : null);

return result;
}

/**
* Converts this object into XML
*
* @return new jdom Element
*/
public Element toXml() {

Element e = new Element(XML_ELEMENT_NAME);
e.setAttribute("contextRegister", contextRegister);
if (value != null) {
e.setAttribute("value", value.toString());
}

return e;
}
}
Expand Up @@ -15,9 +15,16 @@
*/
package ghidra.bitpatterns.info;

import java.io.*;
import java.util.ArrayList;
import java.util.List;

import org.jdom.*;
import org.jdom.input.SAXBuilder;

import ghidra.util.Msg;
import ghidra.util.xml.XmlUtilities;

/**
* An object of this class stores all the function bit pattern information for an executable.
* It records the number of bytes and instructions for each category (first, pre, and return), as
Expand All @@ -27,6 +34,8 @@

public class FileBitPatternInfo {

static final String XML_ELEMENT_NAME = "FileBitPatternInfo";

private int numFirstBytes = 0;
private int numFirstInstructions = 0;
private int numPreBytes = 0;
Expand Down Expand Up @@ -195,4 +204,110 @@ public int getNumReturnInstructions() {
public void setNumReturnInstructions(int numReturnInstructions) {
this.numReturnInstructions = numReturnInstructions;
}

/**
* Converts this object into XML
*
* @return new jdom {@link Element}
*/
public Element toXml() {
Element result = new Element(XML_ELEMENT_NAME);
XmlUtilities.setStringAttr(result, "ghidraURL", ghidraURL);
XmlUtilities.setStringAttr(result, "languageID", languageID);
XmlUtilities.setIntAttr(result, "numFirstBytes", numFirstBytes);
XmlUtilities.setIntAttr(result, "numFirstInstructions", numFirstInstructions);
XmlUtilities.setIntAttr(result, "numPreBytes", numPreBytes);
XmlUtilities.setIntAttr(result, "numPreInstructions", numPreInstructions);
XmlUtilities.setIntAttr(result, "numReturnBytes", numReturnBytes);
XmlUtilities.setIntAttr(result, "numReturnInstructions", numReturnInstructions);

Element funcBitPatternInfoListEle = new Element("funcBitPatternInfoList");
for (FunctionBitPatternInfo fbpi : funcBitPatternInfo) {
funcBitPatternInfoListEle.addContent(fbpi.toXml());
}

result.addContent(funcBitPatternInfoListEle);

return result;
}

/**
* Creates a {@link FileBitPatternInfo} instance from XML.
*
* @param e XML element to convert
* @return new {@link FileBitPatternInfo}, never null
* @throws IOException if file IO error or xml data problem
*/
public static FileBitPatternInfo fromXml(Element e) throws IOException {

String ghidraURL = e.getAttributeValue("ghidraURL");
String languageID = e.getAttributeValue("languageID");
int numFirstBytes =
XmlUtilities.parseInt(XmlUtilities.requireStringAttr(e, "numFirstBytes"));
int numFirstInstructions =
XmlUtilities.parseInt(XmlUtilities.requireStringAttr(e, "numFirstInstructions"));
int numPreBytes = XmlUtilities.parseInt(XmlUtilities.requireStringAttr(e, "numPreBytes"));
int numPreInstructions =
XmlUtilities.parseInt(XmlUtilities.requireStringAttr(e, "numPreInstructions"));
int numReturnBytes =
XmlUtilities.parseInt(XmlUtilities.requireStringAttr(e, "numReturnBytes"));
int numReturnInstructions =
XmlUtilities.parseInt(XmlUtilities.requireStringAttr(e, "numReturnInstructions"));

List<FunctionBitPatternInfo> funcBitPatternInfoList = new ArrayList<>();
Element funcBitPatternInfoListEle = e.getChild("funcBitPatternInfoList");
if (funcBitPatternInfoListEle != null) {
for (Element childElement : XmlUtilities.getChildren(funcBitPatternInfoListEle,
FunctionBitPatternInfo.XML_ELEMENT_NAME)) {
funcBitPatternInfoList.add(FunctionBitPatternInfo.fromXml(childElement));
}
}

FileBitPatternInfo result = new FileBitPatternInfo();
result.setFuncBitPatternInfo(funcBitPatternInfoList);
result.setGhidraURL(ghidraURL);
result.setLanguageID(languageID);
result.setNumFirstBytes(numFirstBytes);
result.setNumFirstInstructions(numFirstInstructions);
result.setNumPreBytes(numPreBytes);
result.setNumPreInstructions(numPreInstructions);
result.setNumReturnBytes(numReturnBytes);
result.setNumReturnInstructions(numReturnInstructions);

return result;
}

/**
* Converts this object to XML and writes it to the specified file.
*
* @param destFile name of xml file to create
* @throws IOException if file io error
*/
public void toXmlFile(File destFile) throws IOException {
Element rootEle = toXml();
Document doc = new Document(rootEle);

XmlUtilities.writePrettyDocToFile(doc, destFile);
}

/**
* Creates a {@link FileBitPatternInfo} instance from a XML file.
*
* @param inputFile name of xml file to read
* @return new {@link FileBitPatternInfo} instance, never null
* @throws IOException if file io error or xml data format problem
*/
public static FileBitPatternInfo fromXmlFile(File inputFile) throws IOException {
SAXBuilder sax = XmlUtilities.createSecureSAXBuilder(false, false);
try (InputStream fis = new FileInputStream(inputFile)) {
Document doc = sax.build(fis);
Element rootElem = doc.getRootElement();
return fromXml(rootElem);
}
catch (JDOMException | IOException e) {
Msg.error(FileBitPatternInfo.class, "Bad file bit pattern file " + inputFile, e);
throw new IOException("Failed to read file bit pattern " + inputFile, e);
}

}
}
Expand Up @@ -16,7 +16,6 @@
package ghidra.bitpatterns.info;

import java.awt.Component;
import java.beans.XMLDecoder;
import java.io.*;
import java.util.*;

Expand Down Expand Up @@ -184,23 +183,19 @@ private void processXmlFile(File dataFile) {
numFiles++;

FileBitPatternInfo fileInfo = null;
try (XMLDecoder xmlDecoder = new XMLDecoder(new FileInputStream(dataFile))) {
fileInfo = (FileBitPatternInfo) xmlDecoder.readObject();
}
catch (ArrayIndexOutOfBoundsException e) {
// Probably wrong type of XML file...skip
try {
fileInfo = FileBitPatternInfo.fromXmlFile(dataFile);
}
catch (IOException e) {
Msg.error(this, "IOException", e);
}
if (fileInfo == null) {
Msg.info(this, "null FileBitPatternInfo for " + dataFile);
Msg.error(this, "Error reading FileBitPatternInfo file " + dataFile, e);
return;
}

if (fileInfo.getFuncBitPatternInfo() == null) {
Msg.info(this, "fList.getFuncBitPatternInfoList null for " + dataFile);
return;
}

if (params == null) {
//TODO: this will set the params to the params of the first valid file
//these should agree with the parameters for all of the files
Expand Down

0 comments on commit a17728f

Please sign in to comment.