From a38edc5197e397f2bec908c14c2f19d9c6347208 Mon Sep 17 00:00:00 2001 From: tinysec Date: Thu, 23 Jul 2026 12:04:59 +0800 Subject: [PATCH] Add custom architecture flag lowering --- ...CustomArchitectureFlagLoweringCallbacks.cs | 138 ++++++++++++++++++ .../CustomArchitectureInstructionCallbacks.cs | 5 +- .../CustomArchitectureRegistration.cs | 1 + 3 files changed, 140 insertions(+), 4 deletions(-) create mode 100644 Architecture/CustomArchitectureFlagLoweringCallbacks.cs diff --git a/Architecture/CustomArchitectureFlagLoweringCallbacks.cs b/Architecture/CustomArchitectureFlagLoweringCallbacks.cs new file mode 100644 index 0000000..909ac24 --- /dev/null +++ b/Architecture/CustomArchitectureFlagLoweringCallbacks.cs @@ -0,0 +1,138 @@ +using System; +using System.Runtime.InteropServices; + +namespace BinaryNinja +{ + public abstract partial class CustomArchitecture + { + [UnmanagedFunctionPointer(System.Runtime.InteropServices.CallingConvention.Cdecl)] + private delegate ulong GetFlagWriteLowLevelILCallback( + IntPtr context, + LowLevelILOperation operation, + ulong size, + uint flagWriteType, + uint flag, + IntPtr operands, + ulong operandCount, + IntPtr il); + + [UnmanagedFunctionPointer(System.Runtime.InteropServices.CallingConvention.Cdecl)] + private delegate ulong GetFlagConditionLowLevelILCallback( + IntPtr context, + LowLevelILFlagCondition condition, + uint semanticClass, + IntPtr il); + + [UnmanagedFunctionPointer(System.Runtime.InteropServices.CallingConvention.Cdecl)] + private delegate ulong GetSemanticFlagGroupLowLevelILCallback( + IntPtr context, + uint semanticGroup, + IntPtr il); + + private void AddFlagLoweringCallbacks(ref BNCustomArchitecture callbacks) + { + callbacks.getFlagWriteLowLevelIL = + UnsafeUtils.PinCallback( + this.GetFlagWriteLowLevelILAdapter); + callbacks.getFlagConditionLowLevelIL = + UnsafeUtils.PinCallback( + this.GetFlagConditionLowLevelILAdapter); + callbacks.getSemanticFlagGroupLowLevelIL = + UnsafeUtils.PinCallback( + this.GetSemanticFlagGroupLowLevelILAdapter); + } + + private ulong GetFlagWriteLowLevelILAdapter( + IntPtr context, + LowLevelILOperation operation, + ulong size, + uint flagWriteType, + uint flag, + IntPtr operands, + ulong operandCount, + IntPtr ilHandle) + { + try + { + RegisterOrConstant[] managedOperands = UnsafeUtils.ReadStructArray< + BNRegisterOrConstant, + RegisterOrConstant>( + operands, + operandCount, + RegisterOrConstant.FromNative); + + using (LowLevelILFunction il = this.CreateCallbackLowLevelIL(ilHandle)) + { + return this.GetFlagWriteLowLevelIL( + operation, + size, + flagWriteType, + flag, + managedOperands, + il); + } + } + catch (Exception exception) + { + Core.LogError( + "Unhandled exception in CustomArchitecture.GetFlagWriteLowLevelIL: {0}", + exception); + + return 0; + } + } + + private ulong GetFlagConditionLowLevelILAdapter( + IntPtr context, + LowLevelILFlagCondition condition, + uint semanticClass, + IntPtr ilHandle) + { + try + { + using (LowLevelILFunction il = this.CreateCallbackLowLevelIL(ilHandle)) + { + return this.GetFlagConditionLowLevelIL(condition, semanticClass, il); + } + } + catch (Exception exception) + { + Core.LogError( + "Unhandled exception in CustomArchitecture.GetFlagConditionLowLevelIL: {0}", + exception); + + return 0; + } + } + + private ulong GetSemanticFlagGroupLowLevelILAdapter( + IntPtr context, + uint semanticGroup, + IntPtr ilHandle) + { + try + { + using (LowLevelILFunction il = this.CreateCallbackLowLevelIL(ilHandle)) + { + return this.GetSemanticFlagGroupLowLevelIL(semanticGroup, il); + } + } + catch (Exception exception) + { + Core.LogError( + "Unhandled exception in CustomArchitecture.GetSemanticFlagGroupLowLevelIL: {0}", + exception); + + return 0; + } + } + + private LowLevelILFunction CreateCallbackLowLevelIL(IntPtr handle) + { + return LowLevelILFunction.MustNewFromHandle( + handle, + false, + this.registeredArchitecture); + } + } +} diff --git a/Architecture/CustomArchitectureInstructionCallbacks.cs b/Architecture/CustomArchitectureInstructionCallbacks.cs index 5608a34..31e411c 100644 --- a/Architecture/CustomArchitectureInstructionCallbacks.cs +++ b/Architecture/CustomArchitectureInstructionCallbacks.cs @@ -112,10 +112,7 @@ private bool GetInstructionLowLevelILAdapter( Marshal.Copy(data, bytes, 0, bytes.Length); } - using (LowLevelILFunction il = LowLevelILFunction.MustNewFromHandle( - ilHandle, - false, - this.registeredArchitecture)) + using (LowLevelILFunction il = this.CreateCallbackLowLevelIL(ilHandle)) { ulong? decodedLength = this.GetInstructionLowLevelIL(bytes, address, il); if (null == decodedLength diff --git a/Architecture/CustomArchitectureRegistration.cs b/Architecture/CustomArchitectureRegistration.cs index ac76dd0..8936d4e 100644 --- a/Architecture/CustomArchitectureRegistration.cs +++ b/Architecture/CustomArchitectureRegistration.cs @@ -64,6 +64,7 @@ public Architecture Register(string name) this.AddInstructionCallbacks(ref callbacks); this.AddAssemblyAndPatchCallbacks(ref callbacks); this.AddIntrinsicCallbacks(ref callbacks); + this.AddFlagLoweringCallbacks(ref callbacks); using (ScopedAllocator allocator = new ScopedAllocator()) {