summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRusty Wagner <rusty@vector35.com>2016-04-10 03:36:44 -0400
committerRusty Wagner <rusty@vector35.com>2016-04-10 03:41:54 -0400
commitd8408e56888de83a5befd74f3a43e614150f1edb (patch)
treeee44ed93e68503071842406a84db51df700f1657
parentb505e0464383284e7ce8fefeffc18713488c2c48 (diff)
Show stack variables and implement naming, undo, and persistence
-rw-r--r--binaryninjaapi.h23
-rw-r--r--function.cpp52
-rw-r--r--lowlevelil.cpp7
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> type;
+ std::string name;
+ int64_t offset;
+ bool autoDefined;
+ };
+
+ struct StackVariableReference
+ {
+ uint32_t sourceOperand;
+ Ref<Type> type;
+ std::string name;
+ int64_t startingOffset;
+ int64_t referencedOffset;
+ };
+
class FunctionGraph;
class Function: public CoreRefCountObject<BNFunction, BNNewFunctionReference, BNFreeFunction>
@@ -1267,6 +1284,7 @@ namespace BinaryNinja
BNRegisterValue GetRegisterValueAfterLowLevelILInstruction(size_t i, uint32_t reg);
std::vector<uint32_t> GetRegistersReadByInstruction(Architecture* arch, uint64_t addr);
std::vector<uint32_t> GetRegistersWrittenByInstruction(Architecture* arch, uint64_t addr);
+ std::vector<StackVariableReference> GetStackVariablesReferencedByInstruction(Architecture* arch, uint64_t addr);
Ref<Type> GetType() const;
void ApplyImportedTypes(Symbol* sym);
@@ -1274,11 +1292,12 @@ namespace BinaryNinja
Ref<FunctionGraph> CreateFunctionGraph();
- std::map<int64_t, NameAndType> GetStackLayout();
+ std::map<int64_t, StackVariable> 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<uint32_t> Function::GetRegistersWrittenByInstruction(Architecture* arch,
}
+vector<StackVariableReference> Function::GetStackVariablesReferencedByInstruction(Architecture* arch, uint64_t addr)
+{
+ size_t count;
+ BNStackVariableReference* refs = BNGetStackVariablesReferencedByInstruction(m_object, arch->GetObject(), addr, &count);
+
+ vector<StackVariableReference> 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<Type> Function::GetType() const
{
return new Type(BNGetFunctionType(m_object));
@@ -212,18 +234,20 @@ Ref<FunctionGraph> Function::CreateFunctionGraph()
}
-map<int64_t, NameAndType> Function::GetStackLayout()
+map<int64_t, StackVariable> Function::GetStackLayout()
{
size_t count;
BNStackVariable* vars = BNGetStackLayout(m_object, &count);
- map<int64_t, NameAndType> result;
+ map<int64_t, StackVariable> 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);