summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRusty Wagner <rusty@vector35.com>2017-04-17 19:38:12 -0400
committerRusty Wagner <rusty@vector35.com>2017-04-17 19:38:12 -0400
commit0ed147b61a1418915c1e243e05aa05e736b6a73f (patch)
tree8cc9c1eeefd7e83ae5468836e6f6bded94b4b335
parentbf57618db521f8677fd57cd9baa5d77acf025845 (diff)
Use new variable system in functions
-rw-r--r--binaryninjaapi.h81
-rw-r--r--binaryninjacore.h45
-rw-r--r--function.cpp151
-rw-r--r--mediumlevelil.cpp56
-rw-r--r--python/function.py39
-rw-r--r--python/mediumlevelil.py30
6 files changed, 290 insertions, 112 deletions
diff --git a/binaryninjaapi.h b/binaryninjaapi.h
index af0cf5ce..c6ac8aa3 100644
--- a/binaryninjaapi.h
+++ b/binaryninjaapi.h
@@ -1809,11 +1809,24 @@ namespace BinaryNinja
static bool IsBackEdge(BasicBlock* source, BasicBlock* target);
};
- struct StackVariable
+ struct Variable: public BNVariable
{
+ Variable();
+ Variable(BNVariableSourceType type, uint32_t index, uint64_t identifier);
+ Variable(const BNVariable& var);
+
+ Variable& operator=(const Variable& var);
+
+ bool operator==(const Variable& var) const;
+ bool operator!=(const Variable& var) const;
+ bool operator<(const Variable& var) const;
+ };
+
+ struct VariableNameAndType
+ {
+ Variable var;
Ref<Type> type;
std::string name;
- int64_t offset;
bool autoDefined;
};
@@ -1928,12 +1941,20 @@ namespace BinaryNinja
Ref<FunctionGraph> CreateFunctionGraph();
- std::map<int64_t, StackVariable> GetStackLayout();
+ std::map<int64_t, std::vector<VariableNameAndType>> GetStackLayout();
void CreateAutoStackVariable(int64_t offset, Ref<Type> type, const std::string& name);
void CreateUserStackVariable(int64_t offset, Ref<Type> type, const std::string& name);
void DeleteAutoStackVariable(int64_t offset);
void DeleteUserStackVariable(int64_t offset);
- bool GetStackVariableAtFrameOffset(int64_t offset, StackVariable& var);
+ bool GetStackVariableAtFrameOffset(Architecture* arch, uint64_t addr, int64_t offset, VariableNameAndType& var);
+
+ std::map<Variable, VariableNameAndType> GetVariables();
+ void CreateAutoVariable(const Variable& var, Ref<Type> type, const std::string& name, bool singleOnly = false);
+ void CreateUserVariable(const Variable& var, Ref<Type> type, const std::string& name, bool singleOnly = false);
+ void DeleteAutoVariable(const Variable& var);
+ void DeleteUserVariable(const Variable& var);
+ Ref<Type> GetVariableType(const Variable& var);
+ std::string GetVariableName(const Variable& var);
void SetAutoIndirectBranches(Architecture* sourceArch, uint64_t source, const std::vector<ArchAndAddr>& branches);
void SetUserIndirectBranches(Architecture* sourceArch, uint64_t source, const std::vector<ArchAndAddr>& branches);
@@ -2228,24 +2249,24 @@ namespace BinaryNinja
ExprId a = 0, ExprId b = 0, ExprId c = 0, ExprId d = 0, ExprId e = 0, ExprId f = 0);
ExprId AddInstruction(ExprId expr);
- ExprId SetVar(size_t size, const BNILVariable& var, ExprId src);
- ExprId SetVarField(size_t size, const BNILVariable& var, int64_t offset, ExprId src);
- ExprId SetVarSplit(size_t size, const BNILVariable& high, const BNILVariable& low, ExprId src);
- ExprId SetVarSSA(size_t size, const BNILVariable& var, size_t index, ExprId src);
- ExprId SetVarFieldSSA(size_t size, const BNILVariable& var, size_t varIndex, int64_t offset, ExprId src);
- ExprId SetVarSplitSSA(size_t size, const BNILVariable& high, size_t highIndex,
- const BNILVariable& low, size_t lowIndex, ExprId src);
- ExprId SetVarAliased(size_t size, const BNILVariable& var, size_t destIndex, size_t srcIndex, ExprId src);
- ExprId SetVarFieldAliased(size_t size, const BNILVariable& var, size_t destIndex, size_t srcIndex,
+ ExprId SetVar(size_t size, const Variable& var, ExprId src);
+ ExprId SetVarField(size_t size, const Variable& var, int64_t offset, ExprId src);
+ ExprId SetVarSplit(size_t size, const Variable& high, const Variable& low, ExprId src);
+ ExprId SetVarSSA(size_t size, const Variable& var, size_t index, ExprId src);
+ ExprId SetVarFieldSSA(size_t size, const Variable& var, size_t varIndex, int64_t offset, ExprId src);
+ ExprId SetVarSplitSSA(size_t size, const Variable& high, size_t highIndex,
+ const Variable& low, size_t lowIndex, ExprId src);
+ ExprId SetVarAliased(size_t size, const Variable& var, size_t destIndex, size_t srcIndex, ExprId src);
+ ExprId SetVarFieldAliased(size_t size, const Variable& var, size_t destIndex, size_t srcIndex,
int64_t offset, ExprId src);
- ExprId Var(size_t size, const BNILVariable& var);
- ExprId VarField(size_t size, const BNILVariable& var, int64_t offset);
- ExprId VarSSA(size_t size, const BNILVariable& var, size_t index);
- ExprId VarFieldSSA(size_t size, const BNILVariable& var, int64_t offset, size_t varIndex);
- ExprId VarAliased(size_t size, const BNILVariable& var, size_t memIndex);
- ExprId VarFieldAliased(size_t size, const BNILVariable& var, int64_t offset, size_t memIndex);
- ExprId AddressOf(size_t size, const BNILVariable& var);
- ExprId AddressOfField(size_t size, const BNILVariable& var, int64_t offset);
+ ExprId Var(size_t size, const Variable& var);
+ ExprId VarField(size_t size, const Variable& var, int64_t offset);
+ ExprId VarSSA(size_t size, const Variable& var, size_t index);
+ ExprId VarFieldSSA(size_t size, const Variable& var, int64_t offset, size_t varIndex);
+ ExprId VarAliased(size_t size, const Variable& var, size_t memIndex);
+ ExprId VarFieldAliased(size_t size, const Variable& var, int64_t offset, size_t memIndex);
+ ExprId AddressOf(size_t size, const Variable& var);
+ ExprId AddressOfField(size_t size, const Variable& var, int64_t offset);
ExprId Goto(BNMediumLevelILLabel& label);
ExprId If(ExprId operand, BNMediumLevelILLabel& t, BNMediumLevelILLabel& f);
@@ -2255,7 +2276,7 @@ namespace BinaryNinja
ExprId AddLabelList(const std::vector<BNMediumLevelILLabel*>& labels);
ExprId AddOperandList(const std::vector<ExprId> operands);
- BNILVariable GetVariable(ExprId i, size_t varOperand);
+ Variable GetVariable(ExprId i, size_t varOperand);
BNMediumLevelILInstruction operator[](size_t i) const;
size_t GetIndexForInstruction(size_t i) const;
@@ -2278,21 +2299,21 @@ namespace BinaryNinja
size_t GetSSAExprIndex(size_t instr) const;
size_t GetNonSSAExprIndex(size_t instr) const;
- size_t GetSSAVarDefinition(const BNILVariable& var, size_t idx) const;
+ size_t GetSSAVarDefinition(const Variable& var, size_t idx) const;
size_t GetSSAMemoryDefinition(size_t idx) const;
- std::set<size_t> GetSSAVarUses(const BNILVariable& var, size_t idx) const;
+ std::set<size_t> GetSSAVarUses(const Variable& var, size_t idx) const;
std::set<size_t> GetSSAMemoryUses(size_t idx) const;
- RegisterValue GetSSAVarValue(const BNILVariable& var, size_t idx);
+ RegisterValue GetSSAVarValue(const Variable& var, size_t idx);
RegisterValue GetExprValue(size_t expr);
- PossibleValueSet GetPossibleSSAVarValues(const BNILVariable& var, size_t idx, size_t instr);
+ PossibleValueSet GetPossibleSSAVarValues(const Variable& var, size_t idx, size_t instr);
PossibleValueSet GetPossibleExprValues(size_t expr);
- size_t GetSSAVarIndexAtInstruction(const BNILVariable& var, size_t instr) const;
+ size_t GetSSAVarIndexAtInstruction(const Variable& var, size_t instr) const;
size_t GetSSAMemoryIndexAtInstruction(size_t instr) const;
- BNILVariable GetVariableForRegisterAtInstruction(uint32_t reg, size_t instr) const;
- BNILVariable GetVariableForFlagAtInstruction(uint32_t flag, size_t instr) const;
- BNILVariable GetVariableForStackLocationAtInstruction(int64_t offset, size_t instr) const;
+ Variable GetVariableForRegisterAtInstruction(uint32_t reg, size_t instr) const;
+ Variable GetVariableForFlagAtInstruction(uint32_t flag, size_t instr) const;
+ Variable GetVariableForStackLocationAtInstruction(int64_t offset, size_t instr) const;
RegisterValue GetRegisterValueAtInstruction(uint32_t reg, size_t instr);
RegisterValue GetRegisterValueAfterInstruction(uint32_t reg, size_t instr);
diff --git a/binaryninjacore.h b/binaryninjacore.h
index c43c9b21..68ea4069 100644
--- a/binaryninjacore.h
+++ b/binaryninjacore.h
@@ -766,16 +766,16 @@ extern "C"
size_t operand;
};
- enum BNILVariableSourceType
+ enum BNVariableSourceType
{
RegisterVariableSourceType,
FlagVariableSourceType,
StackVariableSourceType
};
- struct BNILVariable
+ struct BNVariable
{
- BNILVariableSourceType type;
+ BNVariableSourceType type;
uint32_t index;
int64_t identifier;
};
@@ -1129,11 +1129,11 @@ extern "C"
uint32_t (*getFloatReturnValueRegister)(void* ctxt);
};
- struct BNStackVariable
+ struct BNVariableNameAndType
{
+ BNVariable var;
BNType* type;
char* name;
- int64_t offset;
bool autoDefined;
};
@@ -1929,14 +1929,25 @@ extern "C"
uint64_t len, size_t* count);
BINARYNINJACOREAPI void BNFreeStringReferenceList(BNStringReference* strings);
- BINARYNINJACOREAPI BNStackVariable* BNGetStackLayout(BNFunction* func, size_t* count);
- BINARYNINJACOREAPI void BNFreeStackLayout(BNStackVariable* vars, size_t count);
+ BINARYNINJACOREAPI BNVariableNameAndType* BNGetStackLayout(BNFunction* func, size_t* count);
+ BINARYNINJACOREAPI void BNFreeVariableList(BNVariableNameAndType* vars, size_t count);
BINARYNINJACOREAPI void BNCreateAutoStackVariable(BNFunction* func, int64_t offset, BNType* type, const char* name);
BINARYNINJACOREAPI void BNCreateUserStackVariable(BNFunction* func, int64_t offset, BNType* type, const char* name);
BINARYNINJACOREAPI void BNDeleteAutoStackVariable(BNFunction* func, int64_t offset);
BINARYNINJACOREAPI void BNDeleteUserStackVariable(BNFunction* func, int64_t offset);
- BINARYNINJACOREAPI bool BNGetStackVariableAtFrameOffset(BNFunction* func, int64_t offset, BNStackVariable* var);
- BINARYNINJACOREAPI void BNFreeStackVariable(BNStackVariable* var);
+ BINARYNINJACOREAPI bool BNGetStackVariableAtFrameOffset(BNFunction* func, BNArchitecture* arch, uint64_t addr,
+ int64_t offset, BNVariableNameAndType* var);
+ BINARYNINJACOREAPI void BNFreeVariableNameAndType(BNVariableNameAndType* var);
+
+ BINARYNINJACOREAPI BNVariableNameAndType* BNGetFunctionVariables(BNFunction* func, size_t* count);
+ BINARYNINJACOREAPI void BNCreateAutoVariable(BNFunction* func, const BNVariable* var, BNType* type,
+ const char* name, bool singleOnly);
+ BINARYNINJACOREAPI void BNCreateUserVariable(BNFunction* func, const BNVariable* var, BNType* type,
+ const char* name, bool singleOnly);
+ BINARYNINJACOREAPI void BNDeleteAutoVariable(BNFunction* func, const BNVariable* var);
+ BINARYNINJACOREAPI void BNDeleteUserVariable(BNFunction* func, const BNVariable* var);
+ BINARYNINJACOREAPI BNType* BNGetVariableType(BNFunction* func, const BNVariable* var);
+ BINARYNINJACOREAPI char* BNGetVariableName(BNFunction* func, const BNVariable* var);
BINARYNINJACOREAPI void BNSetAutoIndirectBranches(BNFunction* func, BNArchitecture* sourceArch, uint64_t source,
BNArchitectureAndAddress* branches, size_t count);
@@ -2272,29 +2283,29 @@ extern "C"
BINARYNINJACOREAPI size_t BNGetMediumLevelILNonSSAExprIndex(BNMediumLevelILFunction* func, size_t expr);
BINARYNINJACOREAPI size_t BNGetMediumLevelILSSAVarDefinition(BNMediumLevelILFunction* func,
- const BNILVariable* var, size_t idx);
+ const BNVariable* var, size_t idx);
BINARYNINJACOREAPI size_t BNGetMediumLevelILSSAMemoryDefinition(BNMediumLevelILFunction* func, size_t idx);
- BINARYNINJACOREAPI size_t* BNGetMediumLevelILSSAVarUses(BNMediumLevelILFunction* func, const BNILVariable* var,
+ BINARYNINJACOREAPI size_t* BNGetMediumLevelILSSAVarUses(BNMediumLevelILFunction* func, const BNVariable* var,
size_t idx, size_t* count);
BINARYNINJACOREAPI size_t* BNGetMediumLevelILSSAMemoryUses(BNMediumLevelILFunction* func,
size_t idx, size_t* count);
BINARYNINJACOREAPI BNRegisterValue BNGetMediumLevelILSSAVarValue(BNMediumLevelILFunction* func,
- const BNILVariable* var, size_t idx);
+ const BNVariable* var, size_t idx);
BINARYNINJACOREAPI BNRegisterValue BNGetMediumLevelILExprValue(BNMediumLevelILFunction* func, size_t expr);
BINARYNINJACOREAPI BNPossibleValueSet BNGetMediumLevelILPossibleSSAVarValues(BNMediumLevelILFunction* func,
- const BNILVariable* var, size_t idx, size_t instr);
+ const BNVariable* var, size_t idx, size_t instr);
BINARYNINJACOREAPI BNPossibleValueSet BNGetMediumLevelILPossibleExprValues(BNMediumLevelILFunction* func, size_t expr);
BINARYNINJACOREAPI size_t BNGetMediumLevelILSSAVarIndexAtILInstruction(BNMediumLevelILFunction* func,
- const BNILVariable* var, size_t instr);
+ const BNVariable* var, size_t instr);
BINARYNINJACOREAPI size_t BNGetMediumLevelILSSAMemoryIndexAtILInstruction(BNMediumLevelILFunction* func,
size_t instr);
- BINARYNINJACOREAPI BNILVariable BNGetMediumLevelILVariableForRegisterAtInstruction(BNMediumLevelILFunction* func,
+ BINARYNINJACOREAPI BNVariable BNGetMediumLevelILVariableForRegisterAtInstruction(BNMediumLevelILFunction* func,
uint32_t reg, size_t instr);
- BINARYNINJACOREAPI BNILVariable BNGetMediumLevelILVariableForFlagAtInstruction(BNMediumLevelILFunction* func,
+ BINARYNINJACOREAPI BNVariable BNGetMediumLevelILVariableForFlagAtInstruction(BNMediumLevelILFunction* func,
uint32_t flag, size_t instr);
- BINARYNINJACOREAPI BNILVariable BNGetMediumLevelILVariableForStackLocationAtInstruction(BNMediumLevelILFunction* func,
+ BINARYNINJACOREAPI BNVariable BNGetMediumLevelILVariableForStackLocationAtInstruction(BNMediumLevelILFunction* func,
int64_t offset, size_t instr);
BINARYNINJACOREAPI BNRegisterValue BNGetMediumLevelILRegisterValueAtInstruction(BNMediumLevelILFunction* func,
diff --git a/function.cpp b/function.cpp
index 16ad1f1c..c3402eea 100644
--- a/function.cpp
+++ b/function.cpp
@@ -24,6 +24,69 @@ using namespace BinaryNinja;
using namespace std;
+Variable::Variable()
+{
+ type = RegisterVariableSourceType;
+ index = 0;
+ identifier = 0;
+}
+
+
+Variable::Variable(BNVariableSourceType t, uint32_t i, uint64_t id)
+{
+ type = t;
+ index = i;
+ identifier = id;
+}
+
+
+Variable::Variable(const BNVariable& var)
+{
+ type = var.type;
+ index = var.index;
+ identifier = var.identifier;
+}
+
+
+Variable& Variable::operator=(const Variable& var)
+{
+ type = var.type;
+ index = var.index;
+ identifier = var.identifier;
+ return *this;
+}
+
+
+bool Variable::operator==(const Variable& var) const
+{
+ if (type != var.type)
+ return false;
+ if (index != var.index)
+ return false;
+ return identifier == var.identifier;
+}
+
+
+bool Variable::operator!=(const Variable& var) const
+{
+ return !((*this) == var);
+}
+
+
+bool Variable::operator<(const Variable& var) const
+{
+ if (type < var.type)
+ return true;
+ if (type > var.type)
+ return false;
+ if (index < var.index)
+ return true;
+ if (index > var.index)
+ return false;
+ return identifier < var.identifier;
+}
+
+
Function::Function(BNFunction* func)
{
m_object = func;
@@ -414,23 +477,23 @@ Ref<FunctionGraph> Function::CreateFunctionGraph()
}
-map<int64_t, StackVariable> Function::GetStackLayout()
+map<int64_t, vector<VariableNameAndType>> Function::GetStackLayout()
{
size_t count;
- BNStackVariable* vars = BNGetStackLayout(m_object, &count);
+ BNVariableNameAndType* vars = BNGetStackLayout(m_object, &count);
- map<int64_t, StackVariable> result;
+ map<int64_t, vector<VariableNameAndType>> result;
for (size_t i = 0; i < count; i++)
{
- StackVariable var;
+ VariableNameAndType var;
var.name = vars[i].name;
var.type = new Type(BNNewTypeReference(vars[i].type));
- var.offset = vars[i].offset;
+ var.var = vars[i].var;
var.autoDefined = vars[i].autoDefined;
- result[vars[i].offset] = var;
+ result[vars[i].var.identifier].push_back(var);
}
- BNFreeStackLayout(vars, count);
+ BNFreeVariableList(vars, count);
return result;
}
@@ -459,22 +522,86 @@ void Function::DeleteUserStackVariable(int64_t offset)
}
-bool Function::GetStackVariableAtFrameOffset(int64_t offset, StackVariable& result)
+bool Function::GetStackVariableAtFrameOffset(Architecture* arch, uint64_t addr,
+ int64_t offset, VariableNameAndType& result)
{
- BNStackVariable var;
- if (!BNGetStackVariableAtFrameOffset(m_object, offset, &var))
+ BNVariableNameAndType var;
+ if (!BNGetStackVariableAtFrameOffset(m_object, arch->GetObject(), addr, offset, &var))
return false;
result.type = new Type(BNNewTypeReference(var.type));
result.name = var.name;
- result.offset = var.offset;
+ result.var = var.var;
result.autoDefined = var.autoDefined;
- BNFreeStackVariable(&var);
+ BNFreeVariableNameAndType(&var);
return true;
}
+map<Variable, VariableNameAndType> Function::GetVariables()
+{
+ size_t count;
+ BNVariableNameAndType* vars = BNGetFunctionVariables(m_object, &count);
+
+ map<Variable, VariableNameAndType> result;
+ for (size_t i = 0; i < count; i++)
+ {
+ VariableNameAndType var;
+ var.name = vars[i].name;
+ var.type = new Type(BNNewTypeReference(vars[i].type));
+ var.var = vars[i].var;
+ var.autoDefined = vars[i].autoDefined;
+ result[vars[i].var] = var;
+ }
+
+ BNFreeVariableList(vars, count);
+ return result;
+}
+
+
+void Function::CreateAutoVariable(const Variable& var, Ref<Type> type, const string& name, bool singleOnly)
+{
+ BNCreateAutoVariable(m_object, &var, type->GetObject(), name.c_str(), singleOnly);
+}
+
+
+void Function::CreateUserVariable(const Variable& var, Ref<Type> type, const string& name, bool singleOnly)
+{
+ BNCreateUserVariable(m_object, &var, type->GetObject(), name.c_str(), singleOnly);
+}
+
+
+void Function::DeleteAutoVariable(const Variable& var)
+{
+ BNDeleteAutoVariable(m_object, &var);
+}
+
+
+void Function::DeleteUserVariable(const Variable& var)
+{
+ BNDeleteAutoVariable(m_object, &var);
+}
+
+
+Ref<Type> Function::GetVariableType(const Variable& var)
+{
+ BNType* type = BNGetVariableType(m_object, &var);
+ if (!type)
+ return nullptr;
+ return new Type(type);
+}
+
+
+string Function::GetVariableName(const Variable& var)
+{
+ char* name = BNGetVariableName(m_object, &var);
+ string result = name;
+ BNFreeString(name);
+ return result;
+}
+
+
void Function::SetAutoIndirectBranches(Architecture* sourceArch, uint64_t source, const std::vector<ArchAndAddr>& branches)
{
BNArchitectureAndAddress* branchList = new BNArchitectureAndAddress[branches.size()];
diff --git a/mediumlevelil.cpp b/mediumlevelil.cpp
index b0eb83a1..4ec5d69e 100644
--- a/mediumlevelil.cpp
+++ b/mediumlevelil.cpp
@@ -73,34 +73,34 @@ ExprId MediumLevelILFunction::AddInstruction(size_t expr)
}
-ExprId MediumLevelILFunction::SetVar(size_t size, const BNILVariable& var, ExprId src)
+ExprId MediumLevelILFunction::SetVar(size_t size, const Variable& var, ExprId src)
{
return AddExpr(MLIL_SET_VAR, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.identifier, src);
}
-ExprId MediumLevelILFunction::SetVarField(size_t size, const BNILVariable& var, int64_t offset, ExprId src)
+ExprId MediumLevelILFunction::SetVarField(size_t size, const Variable& var, int64_t offset, ExprId src)
{
return AddExpr(MLIL_SET_VAR_FIELD, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.identifier,
offset, src);
}
-ExprId MediumLevelILFunction::SetVarSplit(size_t size, const BNILVariable& high, const BNILVariable& low, ExprId src)
+ExprId MediumLevelILFunction::SetVarSplit(size_t size, const Variable& high, const Variable& low, ExprId src)
{
return AddExpr(MLIL_SET_VAR_SPLIT, size, ((uint64_t)high.type << 32) | (uint64_t)high.index, high.identifier,
((uint64_t)low.type << 32) | (uint64_t)low.index, low.identifier, src);
}
-ExprId MediumLevelILFunction::SetVarSSA(size_t size, const BNILVariable& var, size_t varIndex, ExprId src)
+ExprId MediumLevelILFunction::SetVarSSA(size_t size, const Variable& var, size_t varIndex, ExprId src)
{
return AddExpr(MLIL_SET_VAR_SSA, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.identifier,
varIndex, src);
}
-ExprId MediumLevelILFunction::SetVarFieldSSA(size_t size, const BNILVariable& var, size_t varIndex,
+ExprId MediumLevelILFunction::SetVarFieldSSA(size_t size, const Variable& var, size_t varIndex,
int64_t offset, ExprId src)
{
return AddExpr(MLIL_SET_VAR_SSA_FIELD, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.identifier,
@@ -108,8 +108,8 @@ ExprId MediumLevelILFunction::SetVarFieldSSA(size_t size, const BNILVariable& va
}
-ExprId MediumLevelILFunction::SetVarSplitSSA(size_t size, const BNILVariable& high, size_t highIndex,
- const BNILVariable& low, size_t lowIndex, ExprId src)
+ExprId MediumLevelILFunction::SetVarSplitSSA(size_t size, const Variable& high, size_t highIndex,
+ const Variable& low, size_t lowIndex, ExprId src)
{
return AddExpr(MLIL_SET_VAR_SPLIT_SSA, size,
AddExpr(MLIL_VAR_SPLIT_DEST_SSA, size, ((uint64_t)high.type << 32) | (uint64_t)high.index,
@@ -119,7 +119,7 @@ ExprId MediumLevelILFunction::SetVarSplitSSA(size_t size, const BNILVariable& hi
}
-ExprId MediumLevelILFunction::SetVarAliased(size_t size, const BNILVariable& var, size_t destIndex,
+ExprId MediumLevelILFunction::SetVarAliased(size_t size, const Variable& var, size_t destIndex,
size_t srcIndex, ExprId src)
{
return AddExpr(MLIL_SET_VAR_ALIASED, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.identifier,
@@ -127,7 +127,7 @@ ExprId MediumLevelILFunction::SetVarAliased(size_t size, const BNILVariable& var
}
-ExprId MediumLevelILFunction::SetVarFieldAliased(size_t size, const BNILVariable& var, size_t destIndex,
+ExprId MediumLevelILFunction::SetVarFieldAliased(size_t size, const Variable& var, size_t destIndex,
size_t srcIndex, int64_t offset, ExprId src)
{
return AddExpr(MLIL_SET_VAR_ALIASED_FIELD, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.identifier,
@@ -135,25 +135,25 @@ ExprId MediumLevelILFunction::SetVarFieldAliased(size_t size, const BNILVariable
}
-ExprId MediumLevelILFunction::Var(size_t size, const BNILVariable& var)
+ExprId MediumLevelILFunction::Var(size_t size, const Variable& var)
{
return AddExpr(MLIL_VAR, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.identifier);
}
-ExprId MediumLevelILFunction::VarField(size_t size, const BNILVariable& var, int64_t offset)
+ExprId MediumLevelILFunction::VarField(size_t size, const Variable& var, int64_t offset)
{
return AddExpr(MLIL_VAR_FIELD, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.identifier, offset);
}
-ExprId MediumLevelILFunction::VarSSA(size_t size, const BNILVariable& var, size_t varIndex)
+ExprId MediumLevelILFunction::VarSSA(size_t size, const Variable& var, size_t varIndex)
{
return AddExpr(MLIL_VAR_SSA, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.identifier, varIndex);
}
-ExprId MediumLevelILFunction::VarFieldSSA(size_t size, const BNILVariable& var, int64_t offset,
+ExprId MediumLevelILFunction::VarFieldSSA(size_t size, const Variable& var, int64_t offset,
size_t varIndex)
{
return AddExpr(MLIL_VAR_SSA_FIELD, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.identifier,
@@ -161,26 +161,26 @@ ExprId MediumLevelILFunction::VarFieldSSA(size_t size, const BNILVariable& var,
}
-ExprId MediumLevelILFunction::VarAliased(size_t size, const BNILVariable& var, size_t memIndex)
+ExprId MediumLevelILFunction::VarAliased(size_t size, const Variable& var, size_t memIndex)
{
return AddExpr(MLIL_VAR_ALIASED, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.identifier, memIndex);
}
-ExprId MediumLevelILFunction::VarFieldAliased(size_t size, const BNILVariable& var, int64_t offset, size_t memIndex)
+ExprId MediumLevelILFunction::VarFieldAliased(size_t size, const Variable& var, int64_t offset, size_t memIndex)
{
return AddExpr(MLIL_VAR_ALIASED_FIELD, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.identifier,
offset, memIndex);
}
-ExprId MediumLevelILFunction::AddressOf(size_t size, const BNILVariable& var)
+ExprId MediumLevelILFunction::AddressOf(size_t size, const Variable& var)
{
return AddExpr(MLIL_ADDRESS_OF, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.identifier);
}
-ExprId MediumLevelILFunction::AddressOfField(size_t size, const BNILVariable& var, int64_t offset)
+ExprId MediumLevelILFunction::AddressOfField(size_t size, const Variable& var, int64_t offset)
{
return AddExpr(MLIL_ADDRESS_OF_FIELD, size, ((uint64_t)var.type << 32) | (uint64_t)var.index,
var.identifier, offset);
@@ -239,11 +239,11 @@ ExprId MediumLevelILFunction::AddOperandList(const vector<ExprId> operands)
}
-BNILVariable MediumLevelILFunction::GetVariable(ExprId i, size_t varOperand)
+Variable MediumLevelILFunction::GetVariable(ExprId i, size_t varOperand)
{
BNMediumLevelILInstruction instr = (*this)[i];
- BNILVariable result;
- result.type = (BNILVariableSourceType)(instr.operands[varOperand] >> 32);
+ Variable result;
+ result.type = (BNVariableSourceType)(instr.operands[varOperand] >> 32);
result.index = (uint32_t)instr.operands[varOperand];
result.identifier = instr.operands[varOperand + 1];
return result;
@@ -396,7 +396,7 @@ size_t MediumLevelILFunction::GetNonSSAExprIndex(size_t expr) const
}
-size_t MediumLevelILFunction::GetSSAVarDefinition(const BNILVariable& var, size_t idx) const
+size_t MediumLevelILFunction::GetSSAVarDefinition(const Variable& var, size_t idx) const
{
return BNGetMediumLevelILSSAVarDefinition(m_object, &var, idx);
}
@@ -408,7 +408,7 @@ size_t MediumLevelILFunction::GetSSAMemoryDefinition(size_t idx) const
}
-set<size_t> MediumLevelILFunction::GetSSAVarUses(const BNILVariable& var, size_t idx) const
+set<size_t> MediumLevelILFunction::GetSSAVarUses(const Variable& var, size_t idx) const
{
size_t count;
size_t* instrs = BNGetMediumLevelILSSAVarUses(m_object, &var, idx, &count);
@@ -436,7 +436,7 @@ set<size_t> MediumLevelILFunction::GetSSAMemoryUses(size_t idx) const
}
-RegisterValue MediumLevelILFunction::GetSSAVarValue(const BNILVariable& var, size_t idx)
+RegisterValue MediumLevelILFunction::GetSSAVarValue(const Variable& var, size_t idx)
{
BNRegisterValue value = BNGetMediumLevelILSSAVarValue(m_object, &var, idx);
return RegisterValue::FromAPIObject(value);
@@ -450,7 +450,7 @@ RegisterValue MediumLevelILFunction::GetExprValue(size_t expr)
}
-PossibleValueSet MediumLevelILFunction::GetPossibleSSAVarValues(const BNILVariable& var, size_t idx, size_t instr)
+PossibleValueSet MediumLevelILFunction::GetPossibleSSAVarValues(const Variable& var, size_t idx, size_t instr)
{
BNPossibleValueSet value = BNGetMediumLevelILPossibleSSAVarValues(m_object, &var, idx, instr);
return PossibleValueSet::FromAPIObject(value);
@@ -464,7 +464,7 @@ PossibleValueSet MediumLevelILFunction::GetPossibleExprValues(size_t expr)
}
-size_t MediumLevelILFunction::GetSSAVarIndexAtInstruction(const BNILVariable& var, size_t instr) const
+size_t MediumLevelILFunction::GetSSAVarIndexAtInstruction(const Variable& var, size_t instr) const
{
return BNGetMediumLevelILSSAVarIndexAtILInstruction(m_object, &var, instr);
}
@@ -476,19 +476,19 @@ size_t MediumLevelILFunction::GetSSAMemoryIndexAtInstruction(size_t instr) const
}
-BNILVariable MediumLevelILFunction::GetVariableForRegisterAtInstruction(uint32_t reg, size_t instr) const
+Variable MediumLevelILFunction::GetVariableForRegisterAtInstruction(uint32_t reg, size_t instr) const
{
return BNGetMediumLevelILVariableForRegisterAtInstruction(m_object, reg, instr);
}
-BNILVariable MediumLevelILFunction::GetVariableForFlagAtInstruction(uint32_t flag, size_t instr) const
+Variable MediumLevelILFunction::GetVariableForFlagAtInstruction(uint32_t flag, size_t instr) const
{
return BNGetMediumLevelILVariableForFlagAtInstruction(m_object, flag, instr);
}
-BNILVariable MediumLevelILFunction::GetVariableForStackLocationAtInstruction(int64_t offset, size_t instr) const
+Variable MediumLevelILFunction::GetVariableForStackLocationAtInstruction(int64_t offset, size_t instr) const
{
return BNGetMediumLevelILVariableForStackLocationAtInstruction(m_object, offset, instr);
}
diff --git a/python/function.py b/python/function.py
index 51d61792..74f4b0f8 100644
--- a/python/function.py
+++ b/python/function.py
@@ -26,7 +26,7 @@ import ctypes
import _binaryninjacore as core
from enums import (FunctionGraphType, BranchType, SymbolType, InstructionTextTokenType,
HighlightStandardColor, HighlightColorStyle, RegisterValueType, ImplicitRegisterExtend,
- DisassemblyOption, IntegerDisplayType, InstructionTextTokenContext)
+ DisassemblyOption, IntegerDisplayType, InstructionTextTokenContext, VariableSourceType)
import architecture
import highlight
import associateddatastore
@@ -146,14 +146,20 @@ class PossibleValueSet(object):
return "<undetermined>"
-class StackVariable(object):
- def __init__(self, ofs, name, t):
- self.offset = ofs
+class VariableNameAndType(object):
+ def __init__(self, var, name, t):
+ self.var = var
self.name = name
self.type = t
def __repr__(self):
- return "<var@%x: %s %s>" % (self.offset, self.type, self.name)
+ if self.var.type == VariableSourceType.StackVariableSourceType:
+ return "<stack var %x: %s %s>" % (self.var.identifier, self.type, self.name)
+ elif self.var.type == VariableSourceType.RegisterVariableSourceType:
+ return "<reg var %s: %s %s>" % (self.var.function.arch.get_reg_name(self.var.identifier), self.type, self.name)
+ elif self.var.type == VariableSourceType.FlagVariableSourceType:
+ return "<flag var %s: %s %s>" % (self.var.function.arch.get_flag_name(self.var.identifier), self.type, self.name)
+ return "<var %s: %s %s>" % (self.var, self.type, self.name)
def __str__(self):
return self.name
@@ -179,7 +185,7 @@ class StackVariableReference(object):
return "<operand %d ref to %s>" % (self.source_operand, self.name)
-class ILVariable(object):
+class Variable(object):
def __init__(self, func, var_type, index, identifier):
self.function = func
self.type = var_type
@@ -363,14 +369,27 @@ class Function(object):
@property
def stack_layout(self):
- """List of function stack (read-only)"""
+ """List of function stack variables (read-only)"""
count = ctypes.c_ulonglong()
v = core.BNGetStackLayout(self.handle, count)
result = []
for i in xrange(0, count.value):
- result.append(StackVariable(v[i].offset, v[i].name, types.Type(handle = core.BNNewTypeReference(v[i].type))))
- result.sort(key = lambda x: x.offset)
- core.BNFreeStackLayout(v, count.value)
+ var = Variable(self, v[i].var.type, v[i].var.index, v[i].var.identifier)
+ result.append(VariableNameAndType(var, v[i].name, types.Type(handle = core.BNNewTypeReference(v[i].type))))
+ result.sort(key = lambda x: x.var.identifier)
+ core.BNFreeVariableList(v, count.value)
+ return result
+
+ @property
+ def vars(self):
+ """List of function variables (read-only)"""
+ count = ctypes.c_ulonglong()
+ v = core.BNGetFunctionVariables(self.handle, count)
+ result = []
+ for i in xrange(0, count.value):
+ var = Variable(self, v[i].var.type, v[i].var.index, v[i].var.identifier)
+ result.append(VariableNameAndType(var, v[i].name, types.Type(handle = core.BNNewTypeReference(v[i].type))))
+ core.BNFreeVariableList(v, count.value)
return result
@property
diff --git a/python/mediumlevelil.py b/python/mediumlevelil.py
index dff79fbd..f827819f 100644
--- a/python/mediumlevelil.py
+++ b/python/mediumlevelil.py
@@ -22,7 +22,7 @@ import ctypes
# Binary Ninja components
import _binaryninjacore as core
-from .enums import MediumLevelILOperation, InstructionTextTokenType, ILVariableSourceType, ILBranchDependence
+from .enums import MediumLevelILOperation, InstructionTextTokenType, VariableSourceType, ILBranchDependence
import function
import basicblock
import lowlevelil
@@ -157,11 +157,11 @@ class MediumLevelILInstruction(object):
elif operand_type == "expr":
value = MediumLevelILInstruction(func, instr.operands[i])
elif operand_type == "var":
- var_type = ILVariableSourceType(instr.operands[i] >> 32)
+ var_type = VariableSourceType(instr.operands[i] >> 32)
index = instr.operands[i] & 0xffffffff
identifier = instr.operands[i + 1]
i += 1
- value = function.ILVariable(self.function, var_type, index, identifier)
+ value = function.Variable(self.function, var_type, index, identifier)
elif operand_type == "int_list":
count = ctypes.c_ulonglong()
operand_list = core.BNMediumLevelILGetOperandList(func.handle, self.expr_index, i, count)
@@ -175,10 +175,10 @@ class MediumLevelILInstruction(object):
i += 1
value = []
for j in xrange(count.value / 2):
- var_type = ILVariableSourceType(operand_list[j * 2] >> 32)
+ var_type = VariableSourceType(operand_list[j * 2] >> 32)
index = operand_list[j * 2] & 0xffffffff
identifier = operand_list[(j * 2) + 1]
- value.append(function.ILVariable(self.function, var_type, index, identifier))
+ value.append(function.Variable(self.function, var_type, index, identifier))
core.BNMediumLevelILFreeOperandList(operand_list)
elif operand_type == "var_ssa_list":
count = ctypes.c_ulonglong()
@@ -186,11 +186,11 @@ class MediumLevelILInstruction(object):
i += 1
value = []
for j in xrange(count.value / 3):
- var_type = ILVariableSourceType(operand_list[j * 3] >> 32)
+ var_type = VariableSourceType(operand_list[j * 3] >> 32)
index = operand_list[j * 3] & 0xffffffff
identifier = operand_list[(j * 3) + 1]
var_index = operand_list[(j * 3) + 2]
- value.append((function.ILVariable(self.function, var_type, index, identifier), var_index))
+ value.append((function.Variable(self.function, var_type, index, identifier), var_index))
core.BNMediumLevelILFreeOperandList(operand_list)
elif operand_type == "expr_list":
count = ctypes.c_ulonglong()
@@ -295,7 +295,7 @@ class MediumLevelILInstruction(object):
return core.BNGetMediumLevelILSSAMemoryIndexAtILInstruction(self.function.handle, self.instr_index)
def get_ssa_var_possible_values(self, var, index):
- var_data = core.BNILVariable()
+ var_data = core.BNVariable()
var_data.type = var.type
var_data.index = var.index
var_data.identifier = var.identifier
@@ -304,7 +304,7 @@ class MediumLevelILInstruction(object):
return result
def get_ssa_var_index(self, var):
- var_data = core.BNILVariable()
+ var_data = core.BNVariable()
var_data.type = var.type
var_data.index = var.index
var_data.identifier = var.identifier
@@ -314,17 +314,17 @@ class MediumLevelILInstruction(object):
if isinstance(reg, str):
reg = self.function.arch.regs[reg].index
result = core.BNGetMediumLevelILVariableForRegisterAtInstruction(self.function.handle, reg, self.instr_index)
- return function.ILVariable(self.function.source_function, result.type, result.index, result.identifier)
+ return function.Variable(self.function.source_function, result.type, result.index, result.identifier)
def get_var_for_flag(self, flag):
if isinstance(flag, str):
flag = self.function.arch.regs[flag].index
result = core.BNGetMediumLevelILVariableForFlagAtInstruction(self.function.handle, flag, self.instr_index)
- return function.ILVariable(self.function.source_function, result.type, result.index, result.identifier)
+ return function.Variable(self.function.source_function, result.type, result.index, result.identifier)
def get_var_for_stack_location(self, offset):
result = core.BNGetMediumLevelILVariableForStackLocationAtInstruction(self.function.handle, offset, self.instr_index)
- return function.ILVariable(self.function.source_function, result.type, result.index, result.identifier)
+ return function.Variable(self.function.source_function, result.type, result.index, result.identifier)
def get_reg_value(self, reg):
if isinstance(reg, str):
@@ -654,7 +654,7 @@ class MediumLevelILFunction(object):
return core.BNGetMediumLevelILNonSSAInstructionIndex(self.handle, instr)
def get_ssa_var_definition(self, var, index):
- var_data = core.BNILVariable()
+ var_data = core.BNVariable()
var_data.type = var.type
var_data.index = var.index
var_data.identifier = var.identifier
@@ -671,7 +671,7 @@ class MediumLevelILFunction(object):
def get_ssa_var_uses(self, var, index):
count = ctypes.c_ulonglong()
- var_data = core.BNILVariable()
+ var_data = core.BNVariable()
var_data.type = var.type
var_data.index = var.index
var_data.identifier = var.identifier
@@ -692,7 +692,7 @@ class MediumLevelILFunction(object):
return result
def get_ssa_var_value(self, var, index):
- var_data = core.BNILVariable()
+ var_data = core.BNVariable()
var_data.type = var.type
var_data.index = var.index
var_data.identifier = var.identifier