From 153e9543984751449e64048a5acceff9524221ce Mon Sep 17 00:00:00 2001 From: Chinmay Date: Tue, 7 Jul 2020 14:54:48 -0700 Subject: Changes to implement User-informed dataflow --- function.cpp | 136 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 136 insertions(+) (limited to 'function.cpp') diff --git a/function.cpp b/function.cpp index fd3760b4..9dc9ea21 100644 --- a/function.cpp +++ b/function.cpp @@ -19,6 +19,8 @@ // IN THE SOFTWARE. #include "binaryninjaapi.h" +#include "mediumlevelilinstruction.h" +#include using namespace BinaryNinja; using namespace std; @@ -354,11 +356,68 @@ PossibleValueSet PossibleValueSet::FromAPIObject(BNPossibleValueSet& value) for (size_t i = 0; i < value.count; i++) result.valueSet.insert(value.valueSet[i]); } + + result.count = value.count; BNFreePossibleValueSet(&value); return result; } +BNPossibleValueSet PossibleValueSet::ToAPIObject () +{ + BNPossibleValueSet result; + result.state = state; + result.value = value; + result.offset = offset; + result.count = 0; + + if ((state == SignedRangeValue) || (state == UnsignedRangeValue)) + { + result.ranges = new BNValueRange[ranges.size()]; + result.count = ranges.size(); + for (size_t i = 0; i < ranges.size(); i++) + result.ranges[i] = ranges[i]; + } + else + { + result.ranges = nullptr; + } + + if (state == LookupTableValue) + { + result.table = new BNLookupTableEntry[table.size()]; + result.count = table.size(); + for (size_t i = 0; i < table.size(); i++) + { + result.table[i].fromValues = new int64_t[table[i].fromValues.size()]; + memcpy(result.table[i].fromValues, &table[i].fromValues[0], sizeof(int64_t) * + table[i].fromValues.size()); + result.table[i].fromCount = table[i].fromValues.size(); + result.table[i].toValue = table[i].toValue; + } + } + else + { + result.table = nullptr; + } + + if ((state == InSetOfValues) || (state == NotInSetOfValues)) + { + result.valueSet = new int64_t[valueSet.size()]; + result.count = valueSet.size(); + size_t i = 0; + for (auto j : valueSet) + result.valueSet[i++] = j; + } + else + { + result.valueSet = nullptr; + } + + return result; +} + + RegisterValue Function::GetRegisterValueAtInstruction(Architecture* arch, uint64_t addr, uint32_t reg) { BNRegisterValue value = BNGetRegisterValueAtInstruction(m_object, arch->GetObject(), addr, reg); @@ -1712,6 +1771,83 @@ Ref Function::GetUnresolvedStackAdjustmentGraph() } +void Function::SetVariableValue(const Variable& var, uint64_t defAddr, PossibleValueSet& value) +{ + auto mlil = GetMediumLevelIL(); + auto varDefs = mlil->GetVariableDefinitions(var); + if (varDefs.size() == 0) + { + LogError("Could not get definition for Variable"); + return; + } + bool found = false; + for (const auto& site : varDefs) + { + if (site == defAddr) + { + found = true; + break; + } + } + if (!found) + { + LogError("Could not find definition for variable at given address"); + } + auto defSite = BNArchitectureAndAddress(); + defSite.arch = GetArchitecture()->m_object; + defSite.address = defAddr; + + auto var_data = BNVariable(); + var_data.type = var.type; + var_data.index = var.index; + var_data.storage = var.storage; + + auto valueObj = value.ToAPIObject(); + + BNSetVariableValue(m_object, &var_data, &defSite, &valueObj); +} + + +void Function::ClearInformedVariableValue(const Variable& var, uint64_t defAddr) +{ + auto mlil = GetMediumLevelIL(); + auto varDefs = mlil->GetVariableDefinitions(var); + if (varDefs.size() == 0) + { + LogError("Could not get definition for Variable"); + } + bool found = false; + for (auto site : varDefs) + { + if (site == defAddr) + { + found = true; + break; + } + } + if (!found) + { + LogError("Could not find definition for variable at given address"); + } + auto defSite = BNArchitectureAndAddress(); + defSite.arch = GetArchitecture()->m_object; + defSite.address = defAddr; + + auto var_data = BNVariable(); + var_data.type = var.type; + var_data.index = var.index; + var_data.storage = var.storage; + + BNClearInformedVariableValue(m_object, &var_data, &defSite); +} + + +void Function::ClearInformedVariableValues() +{ + BNClearInformedVariableValues(m_object); +} + + void Function::RequestDebugReport(const string& name) { BNRequestFunctionDebugReport(m_object, name.c_str()); -- cgit v1.3.1