diff options
| author | Rusty Wagner <rusty@vector35.com> | 2017-04-20 23:25:31 -0400 |
|---|---|---|
| committer | Rusty Wagner <rusty@vector35.com> | 2017-04-20 23:25:31 -0400 |
| commit | d50d190f297afcb9621b39eb1d351e9eae96271b (patch) | |
| tree | 1962dd1f0ecb6101f25b63f57cb638685937537c | |
| parent | 0ed147b61a1418915c1e243e05aa05e736b6a73f (diff) | |
Renaming and adding variable identifiers
| -rw-r--r-- | binaryninjaapi.h | 11 | ||||
| -rw-r--r-- | binaryninjacore.h | 15 | ||||
| -rw-r--r-- | function.cpp | 44 | ||||
| -rw-r--r-- | mediumlevelil.cpp | 38 | ||||
| -rw-r--r-- | python/function.py | 65 | ||||
| -rw-r--r-- | python/mediumlevelil.py | 38 |
6 files changed, 118 insertions, 93 deletions
diff --git a/binaryninjaapi.h b/binaryninjaapi.h index c6ac8aa3..0371c4ff 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -1812,7 +1812,7 @@ namespace BinaryNinja struct Variable: public BNVariable { Variable(); - Variable(BNVariableSourceType type, uint32_t index, uint64_t identifier); + Variable(BNVariableSourceType type, uint32_t index, uint64_t storage); Variable(const BNVariable& var); Variable& operator=(const Variable& var); @@ -1820,6 +1820,9 @@ namespace BinaryNinja bool operator==(const Variable& var) const; bool operator!=(const Variable& var) const; bool operator<(const Variable& var) const; + + uint64_t ToIdentifier() const; + static Variable FromIdentifier(uint64_t id); }; struct VariableNameAndType @@ -1949,8 +1952,10 @@ namespace BinaryNinja 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 CreateAutoVariable(const Variable& var, Ref<Type> type, const std::string& name, + bool ignoreDisjointUses = false); + void CreateUserVariable(const Variable& var, Ref<Type> type, const std::string& name, + bool ignoreDisjointUses = false); void DeleteAutoVariable(const Variable& var); void DeleteUserVariable(const Variable& var); Ref<Type> GetVariableType(const Variable& var); diff --git a/binaryninjacore.h b/binaryninjacore.h index 68ea4069..1bd97cde 100644 --- a/binaryninjacore.h +++ b/binaryninjacore.h @@ -65,6 +65,9 @@ #define BN_DEFAULT_MIN_STRING_LENGTH 4 #define BN_MAX_STRING_LENGTH 128 +#define BN_MAX_VARIABLE_OFFSET 0x7fffffffffLL +#define BN_MAX_VARIABLE_INDEX 0xfffff + #ifdef __cplusplus extern "C" { @@ -768,16 +771,16 @@ extern "C" enum BNVariableSourceType { + StackVariableSourceType, RegisterVariableSourceType, - FlagVariableSourceType, - StackVariableSourceType + FlagVariableSourceType }; struct BNVariable { BNVariableSourceType type; uint32_t index; - int64_t identifier; + int64_t storage; }; // Callbacks @@ -1941,13 +1944,15 @@ extern "C" BINARYNINJACOREAPI BNVariableNameAndType* BNGetFunctionVariables(BNFunction* func, size_t* count); BINARYNINJACOREAPI void BNCreateAutoVariable(BNFunction* func, const BNVariable* var, BNType* type, - const char* name, bool singleOnly); + const char* name, bool ignoreDisjointUses); BINARYNINJACOREAPI void BNCreateUserVariable(BNFunction* func, const BNVariable* var, BNType* type, - const char* name, bool singleOnly); + const char* name, bool ignoreDisjointUses); 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 uint64_t BNToVariableIdentifier(const BNVariable* var); + BINARYNINJACOREAPI BNVariable BNFromVariableIdentifier(uint64_t id); BINARYNINJACOREAPI void BNSetAutoIndirectBranches(BNFunction* func, BNArchitecture* sourceArch, uint64_t source, BNArchitectureAndAddress* branches, size_t count); diff --git a/function.cpp b/function.cpp index c3402eea..b22f91dc 100644 --- a/function.cpp +++ b/function.cpp @@ -28,15 +28,15 @@ Variable::Variable() { type = RegisterVariableSourceType; index = 0; - identifier = 0; + storage = 0; } -Variable::Variable(BNVariableSourceType t, uint32_t i, uint64_t id) +Variable::Variable(BNVariableSourceType t, uint32_t i, uint64_t s) { type = t; index = i; - identifier = id; + storage = s; } @@ -44,7 +44,7 @@ Variable::Variable(const BNVariable& var) { type = var.type; index = var.index; - identifier = var.identifier; + storage = var.storage; } @@ -52,7 +52,7 @@ Variable& Variable::operator=(const Variable& var) { type = var.type; index = var.index; - identifier = var.identifier; + storage = var.storage; return *this; } @@ -63,7 +63,7 @@ bool Variable::operator==(const Variable& var) const return false; if (index != var.index) return false; - return identifier == var.identifier; + return storage == var.storage; } @@ -75,15 +75,19 @@ bool Variable::operator!=(const Variable& var) const 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; + return ToIdentifier() < var.ToIdentifier(); +} + + +uint64_t Variable::ToIdentifier() const +{ + return BNToVariableIdentifier(this); +} + + +Variable Variable::FromIdentifier(uint64_t id) +{ + return BNFromVariableIdentifier(id); } @@ -490,7 +494,7 @@ map<int64_t, vector<VariableNameAndType>> Function::GetStackLayout() var.type = new Type(BNNewTypeReference(vars[i].type)); var.var = vars[i].var; var.autoDefined = vars[i].autoDefined; - result[vars[i].var.identifier].push_back(var); + result[vars[i].var.storage].push_back(var); } BNFreeVariableList(vars, count); @@ -560,15 +564,15 @@ map<Variable, VariableNameAndType> Function::GetVariables() } -void Function::CreateAutoVariable(const Variable& var, Ref<Type> type, const string& name, bool singleOnly) +void Function::CreateAutoVariable(const Variable& var, Ref<Type> type, const string& name, bool ignoreDisjointUses) { - BNCreateAutoVariable(m_object, &var, type->GetObject(), name.c_str(), singleOnly); + BNCreateAutoVariable(m_object, &var, type->GetObject(), name.c_str(), ignoreDisjointUses); } -void Function::CreateUserVariable(const Variable& var, Ref<Type> type, const string& name, bool singleOnly) +void Function::CreateUserVariable(const Variable& var, Ref<Type> type, const string& name, bool ignoreDisjointUses) { - BNCreateUserVariable(m_object, &var, type->GetObject(), name.c_str(), singleOnly); + BNCreateUserVariable(m_object, &var, type->GetObject(), name.c_str(), ignoreDisjointUses); } diff --git a/mediumlevelil.cpp b/mediumlevelil.cpp index 4ec5d69e..0b420a82 100644 --- a/mediumlevelil.cpp +++ b/mediumlevelil.cpp @@ -75,27 +75,27 @@ ExprId MediumLevelILFunction::AddInstruction(size_t expr) 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); + return AddExpr(MLIL_SET_VAR, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.storage, 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, + return AddExpr(MLIL_SET_VAR_FIELD, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.storage, offset, 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); + return AddExpr(MLIL_SET_VAR_SPLIT, size, ((uint64_t)high.type << 32) | (uint64_t)high.index, high.storage, + ((uint64_t)low.type << 32) | (uint64_t)low.index, low.storage, 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, + return AddExpr(MLIL_SET_VAR_SSA, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.storage, varIndex, src); } @@ -103,7 +103,7 @@ ExprId MediumLevelILFunction::SetVarSSA(size_t size, const Variable& var, size_t 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, + return AddExpr(MLIL_SET_VAR_SSA_FIELD, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.storage, varIndex, offset, src); } @@ -113,16 +113,16 @@ ExprId MediumLevelILFunction::SetVarSplitSSA(size_t size, const Variable& high, { return AddExpr(MLIL_SET_VAR_SPLIT_SSA, size, AddExpr(MLIL_VAR_SPLIT_DEST_SSA, size, ((uint64_t)high.type << 32) | (uint64_t)high.index, - high.identifier, highIndex), + high.storage, highIndex), AddExpr(MLIL_VAR_SPLIT_DEST_SSA, size, ((uint64_t)low.type << 32) | (uint64_t)low.index, - low.identifier, lowIndex), src); + low.storage, lowIndex), src); } 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, + return AddExpr(MLIL_SET_VAR_ALIASED, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.storage, destIndex, srcIndex, src); } @@ -130,60 +130,60 @@ ExprId MediumLevelILFunction::SetVarAliased(size_t size, const Variable& var, si 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, + return AddExpr(MLIL_SET_VAR_ALIASED_FIELD, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.storage, destIndex, srcIndex, offset, src); } 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); + return AddExpr(MLIL_VAR, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.storage); } 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); + return AddExpr(MLIL_VAR_FIELD, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.storage, offset); } 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); + return AddExpr(MLIL_VAR_SSA, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.storage, varIndex); } 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, + return AddExpr(MLIL_VAR_SSA_FIELD, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.storage, offset, varIndex); } 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); + return AddExpr(MLIL_VAR_ALIASED, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.storage, 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, + return AddExpr(MLIL_VAR_ALIASED_FIELD, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.storage, offset, memIndex); } 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); + return AddExpr(MLIL_ADDRESS_OF, size, ((uint64_t)var.type << 32) | (uint64_t)var.index, var.storage); } 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); + var.storage, offset); } @@ -245,7 +245,7 @@ Variable MediumLevelILFunction::GetVariable(ExprId i, size_t varOperand) Variable result; result.type = (BNVariableSourceType)(instr.operands[varOperand] >> 32); result.index = (uint32_t)instr.operands[varOperand]; - result.identifier = instr.operands[varOperand + 1]; + result.storage = instr.operands[varOperand + 1]; return result; } diff --git a/python/function.py b/python/function.py index 74f4b0f8..bca67a44 100644 --- a/python/function.py +++ b/python/function.py @@ -146,25 +146,6 @@ class PossibleValueSet(object): return "<undetermined>" -class VariableNameAndType(object): - def __init__(self, var, name, t): - self.var = var - self.name = name - self.type = t - - def __repr__(self): - 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 - - class StackVariableReference(object): def __init__(self, src_operand, t, name, start_ofs, ref_ofs): self.source_operand = src_operand @@ -186,11 +167,40 @@ class StackVariableReference(object): class Variable(object): - def __init__(self, func, var_type, index, identifier): + def __init__(self, func, source_type, index, storage, name = None, var_type = None): self.function = func - self.type = var_type + self.source_type = source_type self.index = index - self.identifier = identifier + self.storage = storage + + var = core.BNVariable() + var.type = source_type + var.index = index + var.storage = storage + self.identifier = core.BNToVariableIdentifier(var) + + if name is None: + name = core.BNGetVariableName(func.handle, var) + if var_type is None: + var_type = core.BNGetVariableType(func.handle, var) + if var_type: + var_type = types.Type(var_type) + + self.name = name + self.type = var_type + + @classmethod + def from_identifier(self, func, identifier): + var = core.BNFromVariableIdentifier(identifier) + return Variable(func, VariableSourceType(var.type), var.index, var.storage) + + def __repr__(self): + if self.type is None: + return "<var %s>" % self.name + return "<var %s %s%s>" % (self.type.get_string_before_name(), self.name, self.type.get_string_after_name()) + + def __str__(self): + return self.name class ConstantReference(object): @@ -374,9 +384,9 @@ class Function(object): v = core.BNGetStackLayout(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)))) - result.sort(key = lambda x: x.var.identifier) + result.append(Variable(self, v[i].var.type, v[i].var.index, v[i].var.storage, v[i].name, + types.Type(handle = core.BNNewTypeReference(v[i].type)))) + result.sort(key = lambda x: x.identifier) core.BNFreeVariableList(v, count.value) return result @@ -387,8 +397,9 @@ class Function(object): 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)))) + result.append(Variable(self, v[i].var.type, v[i].var.index, v[i].var.storage, v[i].name, + types.Type(handle = core.BNNewTypeReference(v[i].type)))) + result.sort(key = lambda x: x.identifier) core.BNFreeVariableList(v, count.value) return result diff --git a/python/mediumlevelil.py b/python/mediumlevelil.py index f827819f..e959e480 100644 --- a/python/mediumlevelil.py +++ b/python/mediumlevelil.py @@ -159,9 +159,9 @@ class MediumLevelILInstruction(object): elif operand_type == "var": var_type = VariableSourceType(instr.operands[i] >> 32) index = instr.operands[i] & 0xffffffff - identifier = instr.operands[i + 1] + storage = instr.operands[i + 1] i += 1 - value = function.Variable(self.function, var_type, index, identifier) + value = function.Variable(self.function.source_function, var_type, index, storage) elif operand_type == "int_list": count = ctypes.c_ulonglong() operand_list = core.BNMediumLevelILGetOperandList(func.handle, self.expr_index, i, count) @@ -177,8 +177,8 @@ class MediumLevelILInstruction(object): for j in xrange(count.value / 2): var_type = VariableSourceType(operand_list[j * 2] >> 32) index = operand_list[j * 2] & 0xffffffff - identifier = operand_list[(j * 2) + 1] - value.append(function.Variable(self.function, var_type, index, identifier)) + storage = operand_list[(j * 2) + 1] + value.append(function.Variable(self.function.source_function, var_type, index, storage)) core.BNMediumLevelILFreeOperandList(operand_list) elif operand_type == "var_ssa_list": count = ctypes.c_ulonglong() @@ -188,9 +188,9 @@ class MediumLevelILInstruction(object): for j in xrange(count.value / 3): var_type = VariableSourceType(operand_list[j * 3] >> 32) index = operand_list[j * 3] & 0xffffffff - identifier = operand_list[(j * 3) + 1] + storage = operand_list[(j * 3) + 1] var_index = operand_list[(j * 3) + 2] - value.append((function.Variable(self.function, var_type, index, identifier), var_index)) + value.append((function.Variable(self.function.source_function, var_type, index, storage), var_index)) core.BNMediumLevelILFreeOperandList(operand_list) elif operand_type == "expr_list": count = ctypes.c_ulonglong() @@ -296,35 +296,35 @@ class MediumLevelILInstruction(object): def get_ssa_var_possible_values(self, var, index): var_data = core.BNVariable() - var_data.type = var.type + var_data.type = var.source_type var_data.index = var.index - var_data.identifier = var.identifier + var_data.storage = var.storage value = core.BNGetMediumLevelILPossibleSSAVarValues(self.function.handle, var_data, index, self.instr_index) result = function.RegisterValue(self.function.arch, value) return result def get_ssa_var_index(self, var): var_data = core.BNVariable() - var_data.type = var.type + var_data.type = var.source_type var_data.index = var.index - var_data.identifier = var.identifier + var_data.storage = var.storage return core.BNGetMediumLevelILSSAVarIndexAtILInstruction(self.function.handle, var_data, self.instr_index) def get_var_for_reg(self, reg): if isinstance(reg, str): reg = self.function.arch.regs[reg].index result = core.BNGetMediumLevelILVariableForRegisterAtInstruction(self.function.handle, reg, self.instr_index) - return function.Variable(self.function.source_function, result.type, result.index, result.identifier) + return function.Variable(self.function.source_function, result.type, result.index, result.storage) 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.Variable(self.function.source_function, result.type, result.index, result.identifier) + return function.Variable(self.function.source_function, result.type, result.index, result.storage) def get_var_for_stack_location(self, offset): result = core.BNGetMediumLevelILVariableForStackLocationAtInstruction(self.function.handle, offset, self.instr_index) - return function.Variable(self.function.source_function, result.type, result.index, result.identifier) + return function.Variable(self.function.source_function, result.type, result.index, result.storage) def get_reg_value(self, reg): if isinstance(reg, str): @@ -655,9 +655,9 @@ class MediumLevelILFunction(object): def get_ssa_var_definition(self, var, index): var_data = core.BNVariable() - var_data.type = var.type + var_data.type = var.source_type var_data.index = var.index - var_data.identifier = var.identifier + var_data.storage = var.storage result = core.BNGetMediumLevelILSSAVarDefinition(self.handle, var_data, index) if result >= core.BNGetMediumLevelILInstructionCount(self.handle): return None @@ -672,9 +672,9 @@ class MediumLevelILFunction(object): def get_ssa_var_uses(self, var, index): count = ctypes.c_ulonglong() var_data = core.BNVariable() - var_data.type = var.type + var_data.type = var.source_type var_data.index = var.index - var_data.identifier = var.identifier + var_data.storage = var.storage instrs = core.BNGetMediumLevelILSSAVarUses(self.handle, var_data, index, count) result = [] for i in xrange(0, count.value): @@ -693,9 +693,9 @@ class MediumLevelILFunction(object): def get_ssa_var_value(self, var, index): var_data = core.BNVariable() - var_data.type = var.type + var_data.type = var.source_type var_data.index = var.index - var_data.identifier = var.identifier + var_data.storage = var.storage value = core.BNGetMediumLevelILSSAVarValue(self.handle, var_data, index) result = function.RegisterValue(self.arch, value) return result |
