Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
316 changes: 316 additions & 0 deletions Architecture/CustomArchitectureFlagCallbacks.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,316 @@
using System;
using System.Runtime.InteropServices;

namespace BinaryNinja
{
public abstract partial class CustomArchitecture
{
[UnmanagedFunctionPointer(System.Runtime.InteropServices.CallingConvention.Cdecl)]
private delegate FlagRole GetFlagRoleCallback(
IntPtr context,
uint flag,
uint semanticClass);

[UnmanagedFunctionPointer(System.Runtime.InteropServices.CallingConvention.Cdecl)]
private delegate IntPtr GetFlagsForConditionCallback(
IntPtr context,
LowLevelILFlagCondition condition,
uint semanticClass,
out ulong count);

[UnmanagedFunctionPointer(System.Runtime.InteropServices.CallingConvention.Cdecl)]
private delegate IntPtr GetIndexedListCallback(
IntPtr context,
uint index,
out ulong count);

[UnmanagedFunctionPointer(System.Runtime.InteropServices.CallingConvention.Cdecl)]
private delegate void FreeConditionListCallback(
IntPtr context,
IntPtr conditions,
ulong count);

[UnmanagedFunctionPointer(System.Runtime.InteropServices.CallingConvention.Cdecl)]
private delegate uint GetSemanticClassCallback(IntPtr context, uint writeType);

private void AddFlagCallbacks(ref BNCustomArchitecture callbacks)
{
callbacks.getFlagName = UnsafeUtils.PinCallback<GetRegisterNameCallback>(
this.GetFlagNameAdapter);
callbacks.getFlagWriteTypeName = UnsafeUtils.PinCallback<GetRegisterNameCallback>(
this.GetFlagWriteTypeNameAdapter);
callbacks.getSemanticFlagClassName =
UnsafeUtils.PinCallback<GetRegisterNameCallback>(
this.GetSemanticFlagClassNameAdapter);
callbacks.getSemanticFlagGroupName =
UnsafeUtils.PinCallback<GetRegisterNameCallback>(
this.GetSemanticFlagGroupNameAdapter);
callbacks.getAllFlags = UnsafeUtils.PinCallback<GetRegisterListCallback>(
this.GetAllFlagsAdapter);
callbacks.getAllFlagWriteTypes = UnsafeUtils.PinCallback<GetRegisterListCallback>(
this.GetAllFlagWriteTypesAdapter);
callbacks.getAllSemanticFlagClasses =
UnsafeUtils.PinCallback<GetRegisterListCallback>(
this.GetAllSemanticFlagClassesAdapter);
callbacks.getAllSemanticFlagGroups =
UnsafeUtils.PinCallback<GetRegisterListCallback>(
this.GetAllSemanticFlagGroupsAdapter);
callbacks.getFlagRole = UnsafeUtils.PinCallback<GetFlagRoleCallback>(
this.GetFlagRoleAdapter);
callbacks.getFlagsRequiredForFlagCondition =
UnsafeUtils.PinCallback<GetFlagsForConditionCallback>(
this.GetFlagsRequiredForFlagConditionAdapter);
callbacks.getFlagsRequiredForSemanticFlagGroup =
UnsafeUtils.PinCallback<GetIndexedListCallback>(
this.GetFlagsRequiredForSemanticFlagGroupAdapter);
callbacks.getFlagConditionsForSemanticFlagGroup =
UnsafeUtils.PinCallback<GetIndexedListCallback>(
this.GetFlagConditionsForSemanticFlagGroupAdapter);
callbacks.freeFlagConditionsForSemanticFlagGroup =
UnsafeUtils.PinCallback<FreeConditionListCallback>(
this.FreeConditionListAdapter);
callbacks.getFlagsWrittenByFlagWriteType =
UnsafeUtils.PinCallback<GetIndexedListCallback>(
this.GetFlagsWrittenByFlagWriteTypeAdapter);
callbacks.getSemanticClassForFlagWriteType =
UnsafeUtils.PinCallback<GetSemanticClassCallback>(
this.GetSemanticClassForFlagWriteTypeAdapter);
}

private IntPtr GetFlagNameAdapter(IntPtr context, uint flag)
{
try
{
return NativeMethods.BNAllocString(this.getFlagName((FlagIndex)flag));
}
catch (Exception exception)
{
return this.AllocateEmptyFlagName("getFlagName", exception);
}
}

private IntPtr GetFlagWriteTypeNameAdapter(IntPtr context, uint writeType)
{
try
{
return NativeMethods.BNAllocString(this.GetFlagWriteTypeName(writeType));
}
catch (Exception exception)
{
return this.AllocateEmptyFlagName("GetFlagWriteTypeName", exception);
}
}

private IntPtr GetSemanticFlagClassNameAdapter(IntPtr context, uint semanticClass)
{
try
{
return NativeMethods.BNAllocString(
this.GetSemanticFlagClassName(semanticClass));
}
catch (Exception exception)
{
return this.AllocateEmptyFlagName("GetSemanticFlagClassName", exception);
}
}

private IntPtr GetSemanticFlagGroupNameAdapter(IntPtr context, uint semanticGroup)
{
try
{
return NativeMethods.BNAllocString(
this.GetSemanticFlagGroupName(semanticGroup));
}
catch (Exception exception)
{
return this.AllocateEmptyFlagName("GetSemanticFlagGroupName", exception);
}
}

private IntPtr AllocateEmptyFlagName(string callbackName, Exception exception)
{
Core.LogError(
"Unhandled exception in CustomArchitecture.{0}: {1}",
callbackName,
exception);
return NativeMethods.BNAllocString(string.Empty);
}

private IntPtr GetAllFlagsAdapter(IntPtr context, out ulong count)
{
return this.GetRegisterListAdapter(this.GetAllFlags, "GetAllFlags", out count);
}

private IntPtr GetAllFlagWriteTypesAdapter(IntPtr context, out ulong count)
{
return this.GetRegisterListAdapter(
this.GetAllFlagWriteTypes,
"GetAllFlagWriteTypes",
out count);
}

private IntPtr GetAllSemanticFlagClassesAdapter(IntPtr context, out ulong count)
{
return this.GetRegisterListAdapter(
this.GetAllSemanticFlagClasses,
"GetAllSemanticFlagClasses",
out count);
}

private IntPtr GetAllSemanticFlagGroupsAdapter(IntPtr context, out ulong count)
{
return this.GetRegisterListAdapter(
this.GetAllSemanticFlagGroups,
"GetAllSemanticFlagGroups",
out count);
}

private FlagRole GetFlagRoleAdapter(
IntPtr context,
uint flag,
uint semanticClass)
{
try
{
return this.GetFlagRole(flag, semanticClass);
}
catch (Exception exception)
{
Core.LogError("Unhandled exception in CustomArchitecture.GetFlagRole: {0}", exception);
return FlagRole.SpecialFlagRole;
}
}

private IntPtr GetFlagsRequiredForFlagConditionAdapter(
IntPtr context,
LowLevelILFlagCondition condition,
uint semanticClass,
out ulong count)
{
try
{
uint[] flags = this.GetFlagsRequiredForFlagCondition(condition, semanticClass);
return this.AllocateFlagList(flags, out count);
}
catch (Exception exception)
{
return this.HandleFlagListException(
"GetFlagsRequiredForFlagCondition",
exception,
out count);
}
}

private IntPtr GetFlagsRequiredForSemanticFlagGroupAdapter(
IntPtr context,
uint semanticGroup,
out ulong count)
{
try
{
return this.AllocateFlagList(
this.GetFlagsRequiredForSemanticFlagGroup(semanticGroup),
out count);
}
catch (Exception exception)
{
return this.HandleFlagListException(
"GetFlagsRequiredForSemanticFlagGroup",
exception,
out count);
}
}

private IntPtr GetFlagsWrittenByFlagWriteTypeAdapter(
IntPtr context,
uint writeType,
out ulong count)
{
try
{
return this.AllocateFlagList(
this.GetFlagsWrittenByFlagWriteType(writeType),
out count);
}
catch (Exception exception)
{
return this.HandleFlagListException(
"GetFlagsWrittenByFlagWriteType",
exception,
out count);
}
}

private IntPtr AllocateFlagList(uint[] flags, out ulong count)
{
return this.AllocateRegisterList(flags ?? Array.Empty<uint>(), out count);
}

private IntPtr HandleFlagListException(
string callbackName,
Exception exception,
out ulong count)
{
Core.LogError(
"Unhandled exception in CustomArchitecture.{0}: {1}",
callbackName,
exception);
count = 0;
return IntPtr.Zero;
}

private IntPtr GetFlagConditionsForSemanticFlagGroupAdapter(
IntPtr context,
uint semanticGroup,
out ulong count)
{
try
{
FlagConditionForSemanticClass[] conditions =
this.GetFlagConditionsForSemanticFlagGroup(semanticGroup);
BNFlagConditionForSemanticClass[] native =
new BNFlagConditionForSemanticClass[conditions.Length];
for (int index = 0; index < conditions.Length; index++)
{
native[index] = conditions[index].ToNative();
}

count = (ulong)native.Length;
return UnsafeUtils.AllocStructArray(native);
}
catch (Exception exception)
{
return this.HandleFlagListException(
"GetFlagConditionsForSemanticFlagGroup",
exception,
out count);
}
}

private void FreeConditionListAdapter(
IntPtr context,
IntPtr conditions,
ulong count)
{
if (IntPtr.Zero != conditions)
{
Marshal.FreeHGlobal(conditions);
}
}

private uint GetSemanticClassForFlagWriteTypeAdapter(IntPtr context, uint writeType)
{
try
{
return this.GetSemanticClassForFlagWriteType(writeType);
}
catch (Exception exception)
{
Core.LogError(
"Unhandled exception in CustomArchitecture.GetSemanticClassForFlagWriteType: {0}",
exception);
return 0;
}
}
}
}
39 changes: 22 additions & 17 deletions Architecture/CustomArchitectureRegisterCallbacks.cs
Original file line number Diff line number Diff line change
Expand Up @@ -124,23 +124,7 @@ private IntPtr GetRegisterListAdapter(
try
{
uint[] registers = callback() ?? Array.Empty<uint>();
count = (ulong)registers.Length;
if (0 == registers.Length)
{
return IntPtr.Zero;
}

IntPtr result = Marshal.AllocHGlobal(
checked(registers.Length * sizeof(uint)));
for (int index = 0; index < registers.Length; index++)
{
Marshal.WriteInt32(
result,
checked(index * sizeof(uint)),
unchecked((int)registers[index]));
}

return result;
return this.AllocateRegisterList(registers, out count);
}
catch (Exception exception)
{
Expand All @@ -153,6 +137,27 @@ private IntPtr GetRegisterListAdapter(
}
}

private IntPtr AllocateRegisterList(uint[] registers, out ulong count)
{
count = (ulong)registers.Length;
if (0 == registers.Length)
{
return IntPtr.Zero;
}

IntPtr result = Marshal.AllocHGlobal(
checked(registers.Length * sizeof(uint)));
for (int index = 0; index < registers.Length; index++)
{
Marshal.WriteInt32(
result,
checked(index * sizeof(uint)),
unchecked((int)registers[index]));
}

return result;
}

private void FreeRegisterListAdapter(
IntPtr context,
IntPtr registers,
Expand Down
1 change: 1 addition & 0 deletions Architecture/CustomArchitectureRegistration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ public Architecture Register(string name)
this.GetAssociatedArchitectureAdapter)
};
this.AddRegisterCallbacks(ref callbacks);
this.AddFlagCallbacks(ref callbacks);

using (ScopedAllocator allocator = new ScopedAllocator())
{
Expand Down
10 changes: 9 additions & 1 deletion Struct/BNFlagConditionForSemanticClass.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,14 @@ public sealed class FlagConditionForSemanticClass : INativeWrapper<BNFlagConditi
public uint SemanticClass { get; } = 0;

public LowLevelILFlagCondition Condition { get; } = LowLevelILFlagCondition.LLFC_E;

public FlagConditionForSemanticClass(
uint semanticClass,
LowLevelILFlagCondition condition)
{
this.SemanticClass = semanticClass;
this.Condition = condition;
}

public FlagConditionForSemanticClass(BNFlagConditionForSemanticClass native)
{
Expand All @@ -45,4 +53,4 @@ public BNFlagConditionForSemanticClass ToNative()
};
}
}
}
}
Loading