diff options
| author | Rusty Wagner <rusty@vector35.com> | 2017-04-17 19:38:12 -0400 |
|---|---|---|
| committer | Rusty Wagner <rusty@vector35.com> | 2017-04-17 19:38:12 -0400 |
| commit | 0ed147b61a1418915c1e243e05aa05e736b6a73f (patch) | |
| tree | 8cc9c1eeefd7e83ae5468836e6f6bded94b4b335 | |
| parent | bf57618db521f8677fd57cd9baa5d77acf025845 (diff) | |
Use new variable system in functions
| -rw-r--r-- | binaryninjaapi.h | 81 | ||||
| -rw-r--r-- | binaryninjacore.h | 45 | ||||
| -rw-r--r-- | function.cpp | 151 | ||||
| -rw-r--r-- | mediumlevelil.cpp | 56 | ||||
| -rw-r--r-- | python/function.py | 39 | ||||
| -rw-r--r-- | python/mediumlevelil.py | 30 |
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 |
