From d8408e56888de83a5befd74f3a43e614150f1edb Mon Sep 17 00:00:00 2001 From: Rusty Wagner Date: Sun, 10 Apr 2016 03:36:44 -0400 Subject: Show stack variables and implement naming, undo, and persistence --- binaryninjaapi.h | 23 ++++++++++++++++++++++- function.cpp | 52 ++++++++++++++++++++++++++++++++++++++++++++++------ lowlevelil.cpp | 7 +++++++ 3 files changed, 75 insertions(+), 7 deletions(-) diff --git a/binaryninjaapi.h b/binaryninjaapi.h index 6ddeaa17..705235fc 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -1235,6 +1235,23 @@ namespace BinaryNinja void MarkRecentUse(); }; + struct StackVariable + { + Ref type; + std::string name; + int64_t offset; + bool autoDefined; + }; + + struct StackVariableReference + { + uint32_t sourceOperand; + Ref type; + std::string name; + int64_t startingOffset; + int64_t referencedOffset; + }; + class FunctionGraph; class Function: public CoreRefCountObject @@ -1267,6 +1284,7 @@ namespace BinaryNinja BNRegisterValue GetRegisterValueAfterLowLevelILInstruction(size_t i, uint32_t reg); std::vector GetRegistersReadByInstruction(Architecture* arch, uint64_t addr); std::vector GetRegistersWrittenByInstruction(Architecture* arch, uint64_t addr); + std::vector GetStackVariablesReferencedByInstruction(Architecture* arch, uint64_t addr); Ref GetType() const; void ApplyImportedTypes(Symbol* sym); @@ -1274,11 +1292,12 @@ namespace BinaryNinja Ref CreateFunctionGraph(); - std::map GetStackLayout(); + std::map GetStackLayout(); void CreateAutoStackVariable(int64_t offset, Type* type, const std::string& name); void CreateUserStackVariable(int64_t offset, Type* type, const std::string& name); void DeleteAutoStackVariable(int64_t offset); void DeleteUserStackVariable(int64_t offset); + bool GetStackVariableAtFrameOffset(int64_t offset, StackVariable& var); }; struct FunctionGraphTextLine @@ -1437,6 +1456,8 @@ namespace BinaryNinja ExprId If(ExprId operand, BNLowLevelILLabel& t, BNLowLevelILLabel& f); void MarkLabel(BNLowLevelILLabel& label); + ExprId Operand(uint32_t n, ExprId expr); + BNLowLevelILInstruction operator[](size_t i) const; size_t GetIndexForInstruction(size_t i) const; size_t GetInstructionCount() const; diff --git a/function.cpp b/function.cpp index df3b5090..8f433b48 100644 --- a/function.cpp +++ b/function.cpp @@ -187,6 +187,28 @@ vector Function::GetRegistersWrittenByInstruction(Architecture* arch, } +vector Function::GetStackVariablesReferencedByInstruction(Architecture* arch, uint64_t addr) +{ + size_t count; + BNStackVariableReference* refs = BNGetStackVariablesReferencedByInstruction(m_object, arch->GetObject(), addr, &count); + + vector result; + for (size_t i = 0; i < count; i++) + { + StackVariableReference ref; + ref.sourceOperand = refs[i].sourceOperand; + ref.type = refs[i].type ? new Type(BNNewTypeReference(refs[i].type)) : nullptr; + ref.name = refs[i].name; + ref.startingOffset = refs[i].startingOffset; + ref.referencedOffset = refs[i].referencedOffset; + result.push_back(ref); + } + + BNFreeStackVariableReferenceList(refs, count); + return result; +} + + Ref Function::GetType() const { return new Type(BNGetFunctionType(m_object)); @@ -212,18 +234,20 @@ Ref Function::CreateFunctionGraph() } -map Function::GetStackLayout() +map Function::GetStackLayout() { size_t count; BNStackVariable* vars = BNGetStackLayout(m_object, &count); - map result; + map result; for (size_t i = 0; i < count; i++) { - NameAndType nt; - nt.name = vars[i].name; - nt.type = new Type(BNNewTypeReference(vars[i].type)); - result[vars[i].offset] = nt; + StackVariable var; + var.name = vars[i].name; + var.type = new Type(BNNewTypeReference(vars[i].type)); + var.offset = vars[i].offset; + var.autoDefined = vars[i].autoDefined; + result[vars[i].offset] = var; } BNFreeStackLayout(vars, count); @@ -253,3 +277,19 @@ void Function::DeleteUserStackVariable(int64_t offset) { BNDeleteUserStackVariable(m_object, offset); } + + +bool Function::GetStackVariableAtFrameOffset(int64_t offset, StackVariable& result) +{ + BNStackVariable var; + if (!BNGetStackVariableAtFrameOffset(m_object, offset, &var)) + return false; + + result.type = new Type(BNNewTypeReference(var.type)); + result.name = var.name; + result.offset = var.offset; + result.autoDefined = var.autoDefined; + + BNFreeStackVariable(&var); + return true; +} diff --git a/lowlevelil.cpp b/lowlevelil.cpp index 9cd5b0a1..29614d3e 100644 --- a/lowlevelil.cpp +++ b/lowlevelil.cpp @@ -443,6 +443,13 @@ void LowLevelILFunction::MarkLabel(BNLowLevelILLabel& label) } +ExprId LowLevelILFunction::Operand(uint32_t n, ExprId expr) +{ + BNLowLevelILSetExprSourceOperand(m_object, expr, n); + return expr; +} + + BNLowLevelILInstruction LowLevelILFunction::operator[](size_t i) const { return BNGetLowLevelILByIndex(m_object, i); -- cgit v1.3.1