diff options
| author | Rusty Wagner <rusty@vector35.com> | 2017-08-31 21:41:25 -0400 |
|---|---|---|
| committer | Rusty Wagner <rusty@vector35.com> | 2017-08-31 21:41:25 -0400 |
| commit | 7cbb40a71ffb2583862191b7999e436807f9a0e8 (patch) | |
| tree | 25846f8d0e811b16b28291aeaf6359bee51e28c4 /function.cpp | |
| parent | 980e2f090fb47f7f71a46b03e8c636819f3214ec (diff) | |
| parent | 0b30396eb319e89e4f69d9cbac12fc3d4b453f53 (diff) | |
Merge branch 'dev'
Diffstat (limited to 'function.cpp')
| -rw-r--r-- | function.cpp | 345 |
1 files changed, 326 insertions, 19 deletions
diff --git a/function.cpp b/function.cpp index b570499c..2d8db04c 100644 --- a/function.cpp +++ b/function.cpp @@ -91,6 +91,20 @@ Variable Variable::FromIdentifier(uint64_t id) } +RegisterValue::RegisterValue(): state(UndeterminedValue), value(0) +{ +} + + +BNRegisterValue RegisterValue::ToAPIObject() +{ + BNRegisterValue result; + result.state = state; + result.value = value; + return result; +} + + Function::Function(BNFunction* func) { m_object = func; @@ -135,9 +149,10 @@ bool Function::WasAutomaticallyDiscovered() const } -bool Function::CanReturn() const +Confidence<bool> Function::CanReturn() const { - return BNCanFunctionReturn(m_object); + BNBoolWithConfidence bc = BNCanFunctionReturn(m_object); + return Confidence<bool>(bc.value, bc.confidence); } @@ -182,6 +197,15 @@ void Function::MarkRecentUse() } +string Function::GetComment() const +{ + char* comment = BNGetFunctionComment(m_object); + string result = comment; + BNFreeString(comment); + return result; +} + + string Function::GetCommentForAddress(uint64_t addr) const { char* comment = BNGetCommentForAddress(m_object, addr); @@ -202,6 +226,12 @@ vector<uint64_t> Function::GetCommentedAddresses() const } +void Function::SetComment(const string& comment) +{ + BNSetFunctionComment(m_object, comment.c_str()); +} + + void Function::SetCommentForAddress(uint64_t addr, const string& comment) { BNSetCommentForAddress(m_object, addr, comment.c_str()); @@ -233,7 +263,7 @@ vector<size_t> Function::GetLowLevelILExitsForInstruction(Architecture* arch, ui } -RegisterValue RegisterValue::FromAPIObject(BNRegisterValue& value) +RegisterValue RegisterValue::FromAPIObject(const BNRegisterValue& value) { RegisterValue result; result.state = value.state; @@ -353,10 +383,12 @@ vector<StackVariableReference> Function::GetStackVariablesReferencedByInstructio { StackVariableReference ref; ref.sourceOperand = refs[i].sourceOperand; - ref.type = refs[i].type ? new Type(BNNewTypeReference(refs[i].type)) : nullptr; + ref.type = Confidence<Ref<Type>>(refs[i].type ? new Type(BNNewTypeReference(refs[i].type)) : nullptr, + refs[i].typeConfidence); ref.name = refs[i].name; ref.var = Variable::FromIdentifier(refs[i].varIdentifier); ref.referencedOffset = refs[i].referencedOffset; + ref.size = refs[i].size; result.push_back(ref); } @@ -450,18 +482,232 @@ Ref<Type> Function::GetType() const } +Confidence<Ref<Type>> Function::GetReturnType() const +{ + BNTypeWithConfidence tc = BNGetFunctionReturnType(m_object); + Ref<Type> type = tc.type ? new Type(tc.type) : nullptr; + return Confidence<Ref<Type>>(type, tc.confidence); +} + + +Confidence<Ref<CallingConvention>> Function::GetCallingConvention() const +{ + BNCallingConventionWithConfidence cc = BNGetFunctionCallingConvention(m_object); + Ref<CallingConvention> convention = cc.convention ? new CoreCallingConvention(cc.convention) : nullptr; + return Confidence<Ref<CallingConvention>>(convention, cc.confidence); +} + + +Confidence<vector<Variable>> Function::GetParameterVariables() const +{ + BNParameterVariablesWithConfidence vars = BNGetFunctionParameterVariables(m_object); + vector<Variable> varList; + for (size_t i = 0; i < vars.count; i++) + { + Variable var; + var.type = vars.vars[i].type; + var.index = vars.vars[i].index; + var.storage = vars.vars[i].storage; + varList.push_back(var); + } + Confidence<vector<Variable>> result(varList, vars.confidence); + BNFreeParameterVariables(&vars); + return result; +} + + +Confidence<bool> Function::HasVariableArguments() const +{ + BNBoolWithConfidence bc = BNFunctionHasVariableArguments(m_object); + return Confidence<bool>(bc.value, bc.confidence); +} + + +Confidence<size_t> Function::GetStackAdjustment() const +{ + BNSizeWithConfidence sc = BNGetFunctionStackAdjustment(m_object); + return Confidence<size_t>(sc.value, sc.confidence); +} + + +Confidence<set<uint32_t>> Function::GetClobberedRegisters() const +{ + BNRegisterSetWithConfidence regs = BNGetFunctionClobberedRegisters(m_object); + set<uint32_t> regSet; + for (size_t i = 0; i < regs.count; i++) + regSet.insert(regs.regs[i]); + Confidence<set<uint32_t>> result(regSet, regs.confidence); + BNFreeClobberedRegisters(®s); + return result; +} + + void Function::SetAutoType(Type* type) { BNSetFunctionAutoType(m_object, type->GetObject()); } +void Function::SetAutoReturnType(const Confidence<Ref<Type>>& type) +{ + BNTypeWithConfidence tc; + tc.type = type ? type->GetObject() : nullptr; + tc.confidence = type.GetConfidence(); + BNSetAutoFunctionReturnType(m_object, &tc); +} + + +void Function::SetAutoCallingConvention(const Confidence<Ref<CallingConvention>>& convention) +{ + BNCallingConventionWithConfidence cc; + cc.convention = convention ? convention->GetObject() : nullptr; + cc.confidence = convention.GetConfidence(); + BNSetAutoFunctionCallingConvention(m_object, &cc); +} + + +void Function::SetAutoParameterVariables(const Confidence<vector<Variable>>& vars) +{ + BNParameterVariablesWithConfidence varConf; + varConf.vars = new BNVariable[vars.GetValue().size()]; + varConf.count = vars.GetValue().size(); + for (size_t i = 0; i < vars.GetValue().size(); i++) + { + varConf.vars[i].type = vars.GetValue()[i].type; + varConf.vars[i].index = vars.GetValue()[i].index; + varConf.vars[i].storage = vars.GetValue()[i].storage; + } + varConf.confidence = vars.GetConfidence(); + + BNSetAutoFunctionParameterVariables(m_object, &varConf); + delete[] varConf.vars; +} + + +void Function::SetAutoHasVariableArguments(const Confidence<bool>& varArgs) +{ + BNBoolWithConfidence bc; + bc.value = varArgs.GetValue(); + bc.confidence = varArgs.GetConfidence(); + BNSetAutoFunctionHasVariableArguments(m_object, &bc); +} + + +void Function::SetAutoCanReturn(const Confidence<bool>& returns) +{ + BNBoolWithConfidence bc; + bc.value = returns.GetValue(); + bc.confidence = returns.GetConfidence(); + BNSetAutoFunctionCanReturn(m_object, &bc); +} + + +void Function::SetAutoStackAdjustment(const Confidence<size_t>& stackAdjust) +{ + BNSizeWithConfidence sc; + sc.value = stackAdjust.GetValue(); + sc.confidence = stackAdjust.GetConfidence(); + BNSetAutoFunctionStackAdjustment(m_object, &sc); +} + + +void Function::SetAutoClobberedRegisters(const Confidence<std::set<uint32_t>>& clobbered) +{ + BNRegisterSetWithConfidence regs; + regs.regs = new uint32_t[clobbered.GetValue().size()]; + regs.count = clobbered.GetValue().size(); + size_t i = 0; + for (auto reg : clobbered.GetValue()) + regs.regs[i++] = reg; + regs.confidence = clobbered.GetConfidence(); + BNSetAutoFunctionClobberedRegisters(m_object, ®s); + delete[] regs.regs; +} + + void Function::SetUserType(Type* type) { BNSetFunctionUserType(m_object, type->GetObject()); } +void Function::SetReturnType(const Confidence<Ref<Type>>& type) +{ + BNTypeWithConfidence tc; + tc.type = type ? type->GetObject() : nullptr; + tc.confidence = type.GetConfidence(); + BNSetUserFunctionReturnType(m_object, &tc); +} + + +void Function::SetCallingConvention(const Confidence<Ref<CallingConvention>>& convention) +{ + BNCallingConventionWithConfidence cc; + cc.convention = convention ? convention->GetObject() : nullptr; + cc.confidence = convention.GetConfidence(); + BNSetUserFunctionCallingConvention(m_object, &cc); +} + + +void Function::SetParameterVariables(const Confidence<vector<Variable>>& vars) +{ + BNParameterVariablesWithConfidence varConf; + varConf.vars = new BNVariable[vars.GetValue().size()]; + varConf.count = vars.GetValue().size(); + for (size_t i = 0; i < vars.GetValue().size(); i++) + { + varConf.vars[i].type = vars.GetValue()[i].type; + varConf.vars[i].index = vars.GetValue()[i].index; + varConf.vars[i].storage = vars.GetValue()[i].storage; + } + varConf.confidence = vars.GetConfidence(); + + BNSetUserFunctionParameterVariables(m_object, &varConf); + delete[] varConf.vars; +} + + +void Function::SetHasVariableArguments(const Confidence<bool>& varArgs) +{ + BNBoolWithConfidence bc; + bc.value = varArgs.GetValue(); + bc.confidence = varArgs.GetConfidence(); + BNSetUserFunctionHasVariableArguments(m_object, &bc); +} + + +void Function::SetCanReturn(const Confidence<bool>& returns) +{ + BNBoolWithConfidence bc; + bc.value = returns.GetValue(); + bc.confidence = returns.GetConfidence(); + BNSetUserFunctionCanReturn(m_object, &bc); +} + + +void Function::SetStackAdjustment(const Confidence<size_t>& stackAdjust) +{ + BNSizeWithConfidence sc; + sc.value = stackAdjust.GetValue(); + sc.confidence = stackAdjust.GetConfidence(); + BNSetUserFunctionStackAdjustment(m_object, &sc); +} + + +void Function::SetClobberedRegisters(const Confidence<std::set<uint32_t>>& clobbered) +{ + BNRegisterSetWithConfidence regs; + regs.regs = new uint32_t[clobbered.GetValue().size()]; + regs.count = clobbered.GetValue().size(); + size_t i = 0; + for (auto reg : clobbered.GetValue()) + regs.regs[i++] = reg; + regs.confidence = clobbered.GetConfidence(); + BNSetUserFunctionClobberedRegisters(m_object, ®s); + delete[] regs.regs; +} + + void Function::ApplyImportedTypes(Symbol* sym) { BNApplyImportedTypes(m_object, sym->GetObject()); @@ -491,7 +737,7 @@ map<int64_t, vector<VariableNameAndType>> Function::GetStackLayout() { VariableNameAndType var; var.name = vars[i].name; - var.type = new Type(BNNewTypeReference(vars[i].type)); + var.type = Confidence<Ref<Type>>(new Type(BNNewTypeReference(vars[i].type)), vars[i].typeConfidence); var.var = vars[i].var; var.autoDefined = vars[i].autoDefined; result[vars[i].var.storage].push_back(var); @@ -502,15 +748,21 @@ map<int64_t, vector<VariableNameAndType>> Function::GetStackLayout() } -void Function::CreateAutoStackVariable(int64_t offset, Ref<Type> type, const string& name) +void Function::CreateAutoStackVariable(int64_t offset, const Confidence<Ref<Type>>& type, const string& name) { - BNCreateAutoStackVariable(m_object, offset, type->GetObject(), name.c_str()); + BNTypeWithConfidence tc; + tc.type = type->GetObject(); + tc.confidence = type.GetConfidence(); + BNCreateAutoStackVariable(m_object, offset, &tc, name.c_str()); } -void Function::CreateUserStackVariable(int64_t offset, Ref<Type> type, const string& name) +void Function::CreateUserStackVariable(int64_t offset, const Confidence<Ref<Type>>& type, const string& name) { - BNCreateUserStackVariable(m_object, offset, type->GetObject(), name.c_str()); + BNTypeWithConfidence tc; + tc.type = type->GetObject(); + tc.confidence = type.GetConfidence(); + BNCreateUserStackVariable(m_object, offset, &tc, name.c_str()); } @@ -533,7 +785,7 @@ bool Function::GetStackVariableAtFrameOffset(Architecture* arch, uint64_t addr, if (!BNGetStackVariableAtFrameOffset(m_object, arch->GetObject(), addr, offset, &var)) return false; - result.type = new Type(BNNewTypeReference(var.type)); + result.type = Confidence<Ref<Type>>(new Type(BNNewTypeReference(var.type)), var.typeConfidence); result.name = var.name; result.var = var.var; result.autoDefined = var.autoDefined; @@ -553,7 +805,7 @@ map<Variable, VariableNameAndType> Function::GetVariables() { VariableNameAndType var; var.name = vars[i].name; - var.type = new Type(BNNewTypeReference(vars[i].type)); + var.type = Confidence<Ref<Type>>(new Type(BNNewTypeReference(vars[i].type)), vars[i].typeConfidence); var.var = vars[i].var; var.autoDefined = vars[i].autoDefined; result[vars[i].var] = var; @@ -564,15 +816,23 @@ map<Variable, VariableNameAndType> Function::GetVariables() } -void Function::CreateAutoVariable(const Variable& var, Ref<Type> type, const string& name, bool ignoreDisjointUses) +void Function::CreateAutoVariable(const Variable& var, const Confidence<Ref<Type>>& type, + const string& name, bool ignoreDisjointUses) { - BNCreateAutoVariable(m_object, &var, type->GetObject(), name.c_str(), ignoreDisjointUses); + BNTypeWithConfidence tc; + tc.type = type->GetObject(); + tc.confidence = type.GetConfidence(); + BNCreateAutoVariable(m_object, &var, &tc, name.c_str(), ignoreDisjointUses); } -void Function::CreateUserVariable(const Variable& var, Ref<Type> type, const string& name, bool ignoreDisjointUses) +void Function::CreateUserVariable(const Variable& var, const Confidence<Ref<Type>>& type, + const string& name, bool ignoreDisjointUses) { - BNCreateUserVariable(m_object, &var, type->GetObject(), name.c_str(), ignoreDisjointUses); + BNTypeWithConfidence tc; + tc.type = type->GetObject(); + tc.confidence = type.GetConfidence(); + BNCreateUserVariable(m_object, &var, &tc, name.c_str(), ignoreDisjointUses); } @@ -588,12 +848,12 @@ void Function::DeleteUserVariable(const Variable& var) } -Ref<Type> Function::GetVariableType(const Variable& var) +Confidence<Ref<Type>> Function::GetVariableType(const Variable& var) { - BNType* type = BNGetVariableType(m_object, &var); - if (!type) + BNTypeWithConfidence type = BNGetVariableType(m_object, &var); + if (!type.type) return nullptr; - return new Type(type); + return Confidence<Ref<Type>>(new Type(type.type), type.confidence); } @@ -694,6 +954,7 @@ vector<vector<InstructionTextToken>> Function::GetBlockAnnotations(Architecture* token.size = lines[i].tokens[j].size; token.operand = lines[i].tokens[j].operand; token.context = lines[i].tokens[j].context; + token.confidence = lines[i].tokens[j].confidence; token.address = lines[i].tokens[j].address; line.push_back(token); } @@ -833,6 +1094,20 @@ void Function::SetUserInstructionHighlight(Architecture* arch, uint64_t addr, ui } +Confidence<RegisterValue> Function::GetGlobalPointerValue() const +{ + BNRegisterValueWithConfidence value = BNGetFunctionGlobalPointerValue(m_object); + return Confidence<RegisterValue>(RegisterValue::FromAPIObject(value.value), value.confidence); +} + + +Confidence<RegisterValue> Function::GetRegisterValueAtExit(uint32_t reg) const +{ + BNRegisterValueWithConfidence value = BNGetFunctionRegisterValueAtExit(m_object, reg); + return Confidence<RegisterValue>(RegisterValue::FromAPIObject(value.value), value.confidence); +} + + void Function::Reanalyze() { BNReanalyzeFunction(m_object); @@ -874,6 +1149,38 @@ map<string, double> Function::GetAnalysisPerformanceInfo() } +vector<DisassemblyTextLine> Function::GetTypeTokens(DisassemblySettings* settings) +{ + size_t count; + BNDisassemblyTextLine* lines = BNGetFunctionTypeTokens(m_object, + settings ? settings->GetObject() : nullptr, &count); + + vector<DisassemblyTextLine> result; + for (size_t i = 0; i < count; i++) + { + DisassemblyTextLine line; + line.addr = lines[i].addr; + for (size_t j = 0; j < lines[i].count; j++) + { + InstructionTextToken token; + token.type = lines[i].tokens[j].type; + token.text = lines[i].tokens[j].text; + token.value = lines[i].tokens[j].value; + token.size = lines[i].tokens[j].size; + token.operand = lines[i].tokens[j].operand; + token.context = lines[i].tokens[j].context; + token.confidence = lines[i].tokens[j].confidence; + token.address = lines[i].tokens[j].address; + line.tokens.push_back(token); + } + result.push_back(line); + } + + BNFreeDisassemblyTextLines(lines, count); + return result; +} + + AdvancedFunctionAnalysisDataRequestor::AdvancedFunctionAnalysisDataRequestor(Function* func): m_func(func) { if (m_func) |
