diff --git a/.gitignore b/.gitignore index c43d99b..07d95bc 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,4 @@ obj/ bin/ dist/ build/ -Folder.DotSettings.user/ +Folder.DotSettings.user diff --git a/Handle/BNFlowGraphNode.cs b/Handle/BNFlowGraphNode.cs index bda2106..8fa5f03 100644 --- a/Handle/BNFlowGraphNode.cs +++ b/Handle/BNFlowGraphNode.cs @@ -155,8 +155,5 @@ public void SetOutgoingEdgePoints(ulong edgeNum, Point[] points) (ulong)points.Length ); } - - - } } \ No newline at end of file diff --git a/HighLevelIL/HighLevelILBasicBlock.cs b/HighLevelIL/HighLevelILBasicBlock.cs index babd7b4..42c1900 100644 --- a/HighLevelIL/HighLevelILBasicBlock.cs +++ b/HighLevelIL/HighLevelILBasicBlock.cs @@ -6,7 +6,7 @@ namespace BinaryNinja { public sealed class HighLevelILBasicBlock : AbstractBasicBlock { - internal HighLevelILFunction ILFunction { get; } + public HighLevelILFunction ILFunction { get; } internal HighLevelILBasicBlock( HighLevelILFunction function , @@ -46,7 +46,6 @@ IntPtr handle true ); } - public HighLevelILInstruction this[HighLevelILInstructionIndex index] { @@ -290,7 +289,6 @@ public HighLevelILBasicBlock[] PostDominatorTreeChildren } } - public HighLevelILBasicBlock[] GetDominanceFrontier(bool post) { ulong arrayLength = 0; diff --git a/HighLevelIL/HighLevelILFlowGraph.cs b/HighLevelIL/HighLevelILFlowGraph.cs index ee7f4e3..34496bc 100644 --- a/HighLevelIL/HighLevelILFlowGraph.cs +++ b/HighLevelIL/HighLevelILFlowGraph.cs @@ -4,7 +4,7 @@ namespace BinaryNinja { public sealed class HighLevelILFlowGraph : AbstractFlowGraph { - internal HighLevelILFunction ILFunction { get; set; } + public HighLevelILFunction ILFunction { get; } internal HighLevelILFlowGraph( HighLevelILFunction ilFunction, @@ -95,8 +95,6 @@ internal static HighLevelILFlowGraph MustBorrowHandleEx( return new HighLevelILFlowGraph(ilFunction , handle, false); } - - public HighLevelILFlowGraph? Update() { return HighLevelILFlowGraph.TakeHandleEx( @@ -130,8 +128,7 @@ out ulong arrayLength NativeMethods.BNGetFlowGraphNode(this.handle, index) ); } - - + public HighLevelILFlowGraphNode[] GetNodesInRegion( int left , int top , diff --git a/HighLevelIL/HighLevelILFlowGraphEdge.cs b/HighLevelIL/HighLevelILFlowGraphEdge.cs index a6ec5e8..1f37460 100644 --- a/HighLevelIL/HighLevelILFlowGraphEdge.cs +++ b/HighLevelIL/HighLevelILFlowGraphEdge.cs @@ -1,26 +1,128 @@ +using System; + namespace BinaryNinja { - public sealed class HighLevelILFlowGraphEdge : AbstractFlowGraphEdge + public sealed class HighLevelILFlowGraphEdge + : AbstractFlowGraphEdge, + IEquatable, + IComparable { - internal HighLevelILFunction ILFunction { get; set; } - internal HighLevelILFlowGraphEdge( - HighLevelILFunction ilFunction, - BNFlowGraphEdge native) - : base(native , HighLevelILFlowGraphNode.NewFromHandleEx(ilFunction, native.target)) + BNFlowGraphEdge native, + HighLevelILFlowGraphNode source, + HighLevelILFlowGraphNode target, + bool outgoing + ) : base(native , source, target, outgoing) { - this.ILFunction = ilFunction; + } internal static HighLevelILFlowGraphEdge FromNativeEx( - HighLevelILFunction ilFunction, - BNFlowGraphEdge native + BNFlowGraphEdge native, + HighLevelILFlowGraphNode me, + bool outgoing ) { - return new HighLevelILFlowGraphEdge( - ilFunction , - native + if (outgoing) + { + return new HighLevelILFlowGraphEdge( + native, + me , + HighLevelILFlowGraphNode.MustNewFromHandleEx(me.ILFunction, native.target), + outgoing + ); + } + else + { + return new HighLevelILFlowGraphEdge( + native, + HighLevelILFlowGraphNode.MustNewFromHandleEx(me.ILFunction,native.target) , + me, + outgoing + ); + } + } + + public override bool Equals(object? other) + { + return this.Equals(other as HighLevelILFlowGraphEdge); + } + + public bool Equals(HighLevelILFlowGraphEdge? other) + { + if (other is null) + { + return false; + } + + if (ReferenceEquals(this , other)) + { + return true; + } + + if (this.Type != other.Type) + { + return false; + } + + if (this.Source != other.Source) + { + return false; + } + + if (this.Target != other.Target) + { + return false; + } + + return true; + } + + [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2218:OverrideGetHashCodeOnOverridingEquals")] + public override int GetHashCode() + { + return HashCode.Combine( + (uint)this.Type, + this.Source.GetHashCode(), + this.Target.GetHashCode() ); } + + public static bool operator ==(HighLevelILFlowGraphEdge? left, HighLevelILFlowGraphEdge? right) + { + if (left is null) + { + return right is null; + } + + return left.Equals(right); + } + + public static bool operator !=(HighLevelILFlowGraphEdge? left, HighLevelILFlowGraphEdge? right) + { + return !(left == right); + } + + public int CompareTo(HighLevelILFlowGraphEdge? other) + { + if (other is null) + { + return 1; + } + + int result = this.Type.CompareTo(other.Type); + + if (0 == result) + { + result = this.Source.CompareTo(other.Source); + } + + if (0 == result) + { + result = this.Target.CompareTo(other.Target); + } + + return result; + } } } diff --git a/HighLevelIL/HighLevelILFlowGraphNode.cs b/HighLevelIL/HighLevelILFlowGraphNode.cs index 83a2734..fc19b81 100644 --- a/HighLevelIL/HighLevelILFlowGraphNode.cs +++ b/HighLevelIL/HighLevelILFlowGraphNode.cs @@ -4,7 +4,7 @@ namespace BinaryNinja { public sealed class HighLevelILFlowGraphNode : FlowGraphNode { - internal HighLevelILFunction ILFunction { get; set; } + public HighLevelILFunction ILFunction { get; } internal HighLevelILFlowGraphNode( HighLevelILFunction ilFunction, @@ -107,7 +107,6 @@ internal static HighLevelILFlowGraphNode MustBorrowHandleEx( false); } - public HighLevelILBasicBlock? BasicBlock { get @@ -131,17 +130,19 @@ public HighLevelILFlowGraphEdge[] IncomingEdges { get { - ulong arrayLength = 0; - IntPtr arrayPointer = NativeMethods.BNGetFlowGraphNodeIncomingEdges( this.handle, - out arrayLength + out ulong arrayLength ); return UnsafeUtils.TakeStructArrayEx( arrayPointer, arrayLength, - (_native) => HighLevelILFlowGraphEdge.FromNativeEx(this.ILFunction, _native), + (_native) => HighLevelILFlowGraphEdge.FromNativeEx( + _native, + this, + false + ), NativeMethods.BNFreeFlowGraphNodeEdgeList ); } @@ -151,17 +152,19 @@ public HighLevelILFlowGraphEdge[] OutgoingEdges { get { - ulong arrayLength = 0; - IntPtr arrayPointer = NativeMethods.BNGetFlowGraphNodeOutgoingEdges( this.handle, - out arrayLength + out ulong arrayLength ); return UnsafeUtils.TakeStructArrayEx( arrayPointer, arrayLength, - (_native) => HighLevelILFlowGraphEdge.FromNativeEx(this.ILFunction, _native), + (_native) => HighLevelILFlowGraphEdge.FromNativeEx( + _native, + this, + true + ), NativeMethods.BNFreeFlowGraphNodeEdgeList ); } diff --git a/LowLevelIL/LowLevelILFlowGraphEdge.cs b/LowLevelIL/LowLevelILFlowGraphEdge.cs index d11d20e..d66457e 100644 --- a/LowLevelIL/LowLevelILFlowGraphEdge.cs +++ b/LowLevelIL/LowLevelILFlowGraphEdge.cs @@ -3,22 +3,39 @@ namespace BinaryNinja public sealed class LowLevelILFlowGraphEdge : AbstractFlowGraphEdge { public LowLevelILFlowGraphEdge( - LowLevelILFunction ilFunction, - BNFlowGraphEdge native) - : base(native , LowLevelILFlowGraphNode.NewFromHandleEx(ilFunction, native.target)) + BNFlowGraphEdge native, + LowLevelILFlowGraphNode source, + LowLevelILFlowGraphNode target, + bool outgoing + ) : base(native , source, target, outgoing) { } internal static LowLevelILFlowGraphEdge FromNativeEx( - LowLevelILFunction ilFunction, - BNFlowGraphEdge native + BNFlowGraphEdge native, + LowLevelILFlowGraphNode me, + bool outgoing ) { - return new LowLevelILFlowGraphEdge( - ilFunction , - native - ); + if (outgoing) + { + return new LowLevelILFlowGraphEdge( + native, + me , + LowLevelILFlowGraphNode.MustNewFromHandleEx(me.ILFunction, native.target), + outgoing + ); + } + else + { + return new LowLevelILFlowGraphEdge( + native, + LowLevelILFlowGraphNode.MustNewFromHandleEx(me.ILFunction,native.target) , + me, + outgoing + ); + } } } } diff --git a/LowLevelIL/LowLevelILFlowGraphNode.cs b/LowLevelIL/LowLevelILFlowGraphNode.cs index 6d833df..a59c7b5 100644 --- a/LowLevelIL/LowLevelILFlowGraphNode.cs +++ b/LowLevelIL/LowLevelILFlowGraphNode.cs @@ -131,17 +131,19 @@ public LowLevelILFlowGraphEdge[] IncomingEdges { get { - ulong arrayLength = 0; - IntPtr arrayPointer = NativeMethods.BNGetFlowGraphNodeIncomingEdges( this.handle, - out arrayLength + out ulong arrayLength ); return UnsafeUtils.TakeStructArrayEx( arrayPointer, arrayLength, - (_native) => LowLevelILFlowGraphEdge.FromNativeEx(this.ILFunction, _native), + (_native) => LowLevelILFlowGraphEdge.FromNativeEx( + _native, + this, + false + ), NativeMethods.BNFreeFlowGraphNodeEdgeList ); } @@ -151,17 +153,19 @@ public LowLevelILFlowGraphEdge[] OutgoingEdges { get { - ulong arrayLength = 0; - IntPtr arrayPointer = NativeMethods.BNGetFlowGraphNodeOutgoingEdges( this.handle, - out arrayLength + out ulong arrayLength ); return UnsafeUtils.TakeStructArrayEx( arrayPointer, arrayLength, - (_native) => LowLevelILFlowGraphEdge.FromNativeEx(this.ILFunction, _native), + (_native) => LowLevelILFlowGraphEdge.FromNativeEx( + _native, + this, + true + ), NativeMethods.BNFreeFlowGraphNodeEdgeList ); } diff --git a/MediumLevelIL/MediumLevelILFlowGraphEdge.cs b/MediumLevelIL/MediumLevelILFlowGraphEdge.cs index 3abe90a..cc623d7 100644 --- a/MediumLevelIL/MediumLevelILFlowGraphEdge.cs +++ b/MediumLevelIL/MediumLevelILFlowGraphEdge.cs @@ -2,25 +2,40 @@ namespace BinaryNinja { public sealed class MediumLevelILFlowGraphEdge : AbstractFlowGraphEdge { - internal MediumLevelILFunction ILFunction { get; set; } - public MediumLevelILFlowGraphEdge( - MediumLevelILFunction ilFunction, - BNFlowGraphEdge native) - : base(native , MediumLevelILFlowGraphNode.NewFromHandleEx(ilFunction, native.target)) + BNFlowGraphEdge native, + MediumLevelILFlowGraphNode source, + MediumLevelILFlowGraphNode target, + bool outgoing + ): base(native , source, target, outgoing) { - this.ILFunction = ilFunction; + } internal static MediumLevelILFlowGraphEdge FromNativeEx( - MediumLevelILFunction ilFunction, - BNFlowGraphEdge native + BNFlowGraphEdge native, + MediumLevelILFlowGraphNode me, + bool outgoing ) { - return new MediumLevelILFlowGraphEdge( - ilFunction , - native - ); + if (outgoing) + { + return new MediumLevelILFlowGraphEdge( + native, + me , + MediumLevelILFlowGraphNode.MustNewFromHandleEx(me.ILFunction, native.target), + outgoing + ); + } + else + { + return new MediumLevelILFlowGraphEdge( + native, + MediumLevelILFlowGraphNode.MustNewFromHandleEx(me.ILFunction,native.target) , + me, + outgoing + ); + } } } diff --git a/MediumLevelIL/MediumLevelILFlowGraphNode.cs b/MediumLevelIL/MediumLevelILFlowGraphNode.cs index 5c723b9..1c5a723 100644 --- a/MediumLevelIL/MediumLevelILFlowGraphNode.cs +++ b/MediumLevelIL/MediumLevelILFlowGraphNode.cs @@ -135,17 +135,19 @@ public MediumLevelILFlowGraphEdge[] IncomingEdges { get { - ulong arrayLength = 0; - IntPtr arrayPointer = NativeMethods.BNGetFlowGraphNodeIncomingEdges( this.handle , - out arrayLength + out ulong arrayLength ); return UnsafeUtils.TakeStructArrayEx( arrayPointer , arrayLength , - (_native) => MediumLevelILFlowGraphEdge.FromNativeEx(this.ILFunction , _native) , + (_native) => MediumLevelILFlowGraphEdge.FromNativeEx( + _native, + this, + false + ) , NativeMethods.BNFreeFlowGraphNodeEdgeList ); } @@ -155,17 +157,19 @@ public MediumLevelILFlowGraphEdge[] OutgoingEdges { get { - ulong arrayLength = 0; - IntPtr arrayPointer = NativeMethods.BNGetFlowGraphNodeOutgoingEdges( this.handle , - out arrayLength + out ulong arrayLength ); return UnsafeUtils.TakeStructArrayEx( arrayPointer , arrayLength , - (_native) => MediumLevelILFlowGraphEdge.FromNativeEx(this.ILFunction , _native) , + (_native) => MediumLevelILFlowGraphEdge.FromNativeEx( + _native, + this, + true + ) , NativeMethods.BNFreeFlowGraphNodeEdgeList ); } diff --git a/Struct/BNBasicBlockEdge.cs b/Struct/BNBasicBlockEdge.cs index 3d7d678..8631e06 100644 --- a/Struct/BNBasicBlockEdge.cs +++ b/Struct/BNBasicBlockEdge.cs @@ -36,17 +36,17 @@ public abstract class AbstractBasicBlockEdge where T_SELF : AbstractBasicBlockEdge where T_BASICBLOCK : AbstractBasicBlock { - public BranchType Type { get; } = BranchType.UnconditionalBranch; + public BranchType Type {get;} = BranchType.UnconditionalBranch; - public T_BASICBLOCK Source { get; } + public T_BASICBLOCK Source {get;} - public T_BASICBLOCK Target { get; } + public T_BASICBLOCK Target {get;} - public bool BackEdge { get; } = false; + public bool BackEdge { get;} = false; - public bool FallThrough { get; } = false; + public bool FallThrough { get;} = false; - public bool Outgoing { get; } = false; + public bool Outgoing { get;} = false; internal AbstractBasicBlockEdge( BNBasicBlockEdge native , @@ -188,7 +188,6 @@ bool outgoing } else { - return new BasicBlockEdge( native, BasicBlock.MustNewFromHandle(native.target) , diff --git a/Struct/BNDisassemblyTextLine.cs b/Struct/BNDisassemblyTextLine.cs index dbaab92..e3b4f3c 100644 --- a/Struct/BNDisassemblyTextLine.cs +++ b/Struct/BNDisassemblyTextLine.cs @@ -54,17 +54,17 @@ public sealed class DisassemblyTextLine : INativeWrapperEx, IComparable { - public ulong Address { get; } = 0; + public ulong Address {get;} = 0; - public ulong InstructionIndex { get; } = 0; + public ulong InstructionIndex { get;} = 0; - public InstructionTextToken[] Tokens { get; } = Array.Empty(); + public InstructionTextToken[] Tokens {get;} = Array.Empty(); - public HighlightColor Highlight { get; } = new HighlightColor(); + public HighlightColor Highlight { get;} = new HighlightColor(); - public Tag[] Tags { get; } = Array.Empty(); + public Tag[] Tags { get;} = Array.Empty(); - public DisassemblyTextLineTypeInfo TypeInfo { get; } = new DisassemblyTextLineTypeInfo(); + public DisassemblyTextLineTypeInfo TypeInfo { get;} = new DisassemblyTextLineTypeInfo(); internal DisassemblyTextLine() { diff --git a/Struct/BNEdgeStyle.cs b/Struct/BNEdgeStyle.cs index 2870d67..a8840bb 100644 --- a/Struct/BNEdgeStyle.cs +++ b/Struct/BNEdgeStyle.cs @@ -24,27 +24,31 @@ public unsafe struct BNEdgeStyle internal ThemeColor color; } - public sealed class EdgeStyle : INativeWrapper + public sealed class EdgeStyle : INativeWrapper, + IEquatable, + IComparable { - public EdgePenStyle Style { get; set; } = EdgePenStyle.NoPen; + public EdgePenStyle Style {get;} = EdgePenStyle.NoPen; - public ulong Width { get; set; } = 0; + public ulong Width {get;} = 0; - public ThemeColor Color { get; set; } = ThemeColor.AddressColor; + public ThemeColor Color {get;} = ThemeColor.AddressColor; public EdgeStyle() { } + + public EdgeStyle(BNEdgeStyle native) + { + this.Style = native.style; + this.Width = native.width; + this.Color = native.color; + } - internal static EdgeStyle FromNative(BNEdgeStyle raw) + internal static EdgeStyle FromNative(BNEdgeStyle native) { - return new EdgeStyle() - { - Style = raw.style , - Width = raw.width , - Color = raw.color - }; + return new EdgeStyle(native); } public BNEdgeStyle ToNative() @@ -56,5 +60,92 @@ public BNEdgeStyle ToNative() color = this.Color }; } + + public override bool Equals(object? other) + { + if (other is null) + { + return false; + } + + return this.Equals(other as EdgeStyle); + } + + public bool Equals(EdgeStyle? other) + { + if (other is null) + { + return false; + } + + if (ReferenceEquals(this , other)) + { + return true; + } + + if (this.Style != other.Style) + { + return false; + } + + if (this.Width != other.Width) + { + return false; + } + + if (this.Color != other.Color) + { + return false; + } + + return true; + } + + [System.Diagnostics.CodeAnalysis.SuppressMessage("Usage", "CA2218:OverrideGetHashCodeOnOverridingEquals")] + public override int GetHashCode() + { + return HashCode.Combine( + (uint)this.Style, + this.Width, + (uint)this.Color + ); + } + + public static bool operator ==(EdgeStyle left, EdgeStyle right) + { + if (left is null) + { + return right is null; + } + + return left.Equals(right); + } + + public static bool operator !=(EdgeStyle left, EdgeStyle right) + { + return !(left == right); + } + + public int CompareTo(EdgeStyle? other) + { + if (other is null) + { + return 1; + } + + int result = this.Style.CompareTo(other.Style); + + if (0 == result) + { + result = this.Width.CompareTo(other.Width); + } + + if (0 == result) + { + result = this.Color.CompareTo(other.Color); + } + + return result; + } } } \ No newline at end of file diff --git a/Struct/BNFlowGraphEdge.cs b/Struct/BNFlowGraphEdge.cs index 02258f8..eae5ce6 100644 --- a/Struct/BNFlowGraphEdge.cs +++ b/Struct/BNFlowGraphEdge.cs @@ -39,30 +39,45 @@ public unsafe struct BNFlowGraphEdge internal BNEdgeStyle style; } - public abstract class AbstractFlowGraphEdge : INativeWrapperEx + public abstract class AbstractFlowGraphEdge + : INativeWrapperEx where T_FLOW_GRAPH_NODE : FlowGraphNode { - public BranchType Type { get; set; } = new BranchType(); + public BranchType Type {get;} = BranchType.UnconditionalBranch; - public T_FLOW_GRAPH_NODE? Target { get; set; } = null; + public T_FLOW_GRAPH_NODE Source {get;} - public Point[] Points { get; set; } = Array.Empty(); + public T_FLOW_GRAPH_NODE Target {get;} - public bool BackEdge { get; set; } = false; + public Point[] Points {get;} = Array.Empty(); - public EdgeStyle Style { get; set; } = new EdgeStyle(); + public bool BackEdge {get;} = false; - public AbstractFlowGraphEdge(BNFlowGraphEdge native , T_FLOW_GRAPH_NODE? target ) + public EdgeStyle Style {get;} = new EdgeStyle(); + + public bool Outgoing { get;} = false; + + public AbstractFlowGraphEdge( + BNFlowGraphEdge native , + T_FLOW_GRAPH_NODE source, + T_FLOW_GRAPH_NODE target , + bool outgoing + ) { this.Type = native.type ; + + this.Source = source; this.Target = target ; + + this.Outgoing = outgoing; this.Points = UnsafeUtils.ReadStructArray( native.points , native.pointCount , Point.FromNative ); + this.BackEdge = native.backEdge; this.Style = EdgeStyle.FromNative(native.style) ; } diff --git a/Struct/BNInstructionTextToken.cs b/Struct/BNInstructionTextToken.cs index f221027..a6cf50b 100644 --- a/Struct/BNInstructionTextToken.cs +++ b/Struct/BNInstructionTextToken.cs @@ -90,27 +90,27 @@ public sealed class InstructionTextToken IEquatable, IComparable { - public InstructionTextTokenType Type { get; } = InstructionTextTokenType.TextToken; + public InstructionTextTokenType Type { get;} = InstructionTextTokenType.TextToken; - public string Text { get; } = string.Empty; + public string Text { get;} = string.Empty; - public ulong Value { get; } = 0; + public ulong Value { get;} = 0; - public ulong Width { get; } = 0; + public ulong Width { get;} = 0; - public ulong Size { get; } = 0; + public ulong Size { get;} = 0; - public ulong Operand { get; } = 0; + public ulong Operand { get;} = 0; - public InstructionTextTokenContext Context { get; } = InstructionTextTokenContext.NoTokenContext; + public InstructionTextTokenContext Context { get;} = InstructionTextTokenContext.NoTokenContext; - public byte Confidence { get; } = 0; + public byte Confidence { get;} = 0; - public ulong Address { get; } = 0; + public ulong Address { get;} = 0; - public string[] TypeNames { get; } = Array.Empty(); + public string[] TypeNames { get;} = Array.Empty(); - public ulong ExpressionIndex { get; } = 0; + public ulong ExpressionIndex { get;} = 0; public InstructionTextToken( ) {