Unverified Commit 1e367e58 by Melvin Klimke Committed by GitHub

Parse subregister information from Ghidra (#110)

parent 387405d4
......@@ -315,6 +315,14 @@ impl From<ExpressionType> for IrCastOpType {
}
}
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Hash, Clone)]
pub struct RegisterProperties {
pub register: String,
pub base_register: String,
pub lsb: ByteSize,
pub size: ByteSize,
}
#[cfg(test)]
mod tests {
use super::*;
......@@ -354,4 +362,19 @@ mod tests {
)
.unwrap();
}
#[test]
fn register_properties_deserialization() {
let _: RegisterProperties = serde_json::from_str(
r#"
{
"register": "AH",
"base_register": "EAX",
"lsb": 2,
"size": 1
}
"#,
)
.unwrap();
}
}
use super::{Expression, ExpressionType, Variable};
use super::{Expression, ExpressionType, RegisterProperties, Variable};
use crate::intermediate_representation::Arg as IrArg;
use crate::intermediate_representation::Blk as IrBlk;
use crate::intermediate_representation::ByteSize;
......@@ -403,6 +403,7 @@ pub struct Project {
pub program: Term<Program>,
pub cpu_architecture: String,
pub stack_pointer_register: Variable,
pub register_properties: Vec<RegisterProperties>,
pub register_calling_convention: Vec<CallingConvention>,
}
......@@ -733,6 +734,14 @@ mod tests {
"is_virtual": false
},
"cpu_architecture": "x86_64",
"register_properties": [
{
"register": "AH",
"base_register": "EAX",
"lsb": 2,
"size": 1
}
],
"register_calling_convention": [
{
"calling_convention": "default",
......
......@@ -24,7 +24,6 @@ import ghidra.program.model.lang.PrototypeModel;
import ghidra.program.model.lang.Register;
import ghidra.program.model.listing.Function;
import ghidra.program.model.listing.FunctionIterator;
import ghidra.program.model.listing.FunctionManager;
import ghidra.program.model.listing.Instruction;
import ghidra.program.model.listing.InstructionIterator;
import ghidra.program.model.listing.Listing;
......@@ -250,6 +249,7 @@ public class PcodeExtractor extends GhidraScript {
} catch (FileNotFoundException e) {
System.out.println(e);
}
project.setRegisterProperties(HelperFunctions.getRegisterList());
return project;
}
......
package bil;
import com.google.gson.annotations.SerializedName;
public class RegisterProperties {
@SerializedName("register")
private String register;
@SerializedName("base_register")
private String baseRegister;
@SerializedName("lsb")
private int lsb;
@SerializedName("size")
private int size;
public RegisterProperties(String register, String baseRegister, int lsb, int size) {
this.setRegister(register);
this.setBaseRegister(baseRegister);
this.setLsb(lsb);
this.setSize(size);
}
public String getRegister() {
return register;
}
public void setRegister(String register) {
this.register = register;
}
public String getBaseRegister() {
return baseRegister;
}
public void setBaseRegister(String baseRegister) {
this.baseRegister = baseRegister;
}
public int getLsb() {
return lsb;
}
public void setLsb(int lsb) {
this.lsb = lsb;
}
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
}
......@@ -5,9 +5,11 @@ import java.util.HashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import bil.RegisterProperties;
import bil.Variable;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressIterator;
import ghidra.program.model.lang.Language;
import ghidra.program.model.lang.Register;
import ghidra.program.model.listing.Function;
import ghidra.program.model.listing.FunctionManager;
......@@ -221,4 +223,28 @@ public final class HelperFunctions {
String[] arch = langId.split(":");
return arch[0] + "_" + arch[2];
}
/**
* Returns a list of register properties including the register name itself,
* the name of the base register, the lsb of the register in the base register
* and the size of the register.
*
* @return list of register properties
*/
public static ArrayList<RegisterProperties> getRegisterList() {
ArrayList<RegisterProperties> regProps = new ArrayList<RegisterProperties>();
Language language = ghidraProgram.getLanguage();
int archSizeInBytes = (int)(language.getLanguageDescription().getSize() / 8);
for(Register reg : language.getRegisters()) {
regProps.add(
new RegisterProperties(reg.getName(),
reg.getBaseRegister().getName(),
(int)(reg.getLeastSignificatBitInBaseRegister() / archSizeInBytes),
context.getRegisterVarnode(reg).getSize())
);
}
return regProps;
}
}
package term;
import bil.RegisterProperties;
import bil.Variable;
import internal.RegisterConvention;
......@@ -12,6 +13,8 @@ public class Project {
private Term<Program> program;
@SerializedName("stack_pointer_register")
private Variable stackPointerRegister;
@SerializedName("register_properties")
private ArrayList<RegisterProperties> registerProperties;
@SerializedName("cpu_architecture")
private String cpuArch;
@SerializedName("register_calling_convention")
......@@ -58,4 +61,12 @@ public class Project {
public void setRegisterConvention(ArrayList<RegisterConvention> conventions) {
this.conventions = conventions;
}
public ArrayList<RegisterProperties> getRegisterProperties() {
return registerProperties;
}
public void setRegisterProperties(ArrayList<RegisterProperties> registerProperties) {
this.registerProperties = registerProperties;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment