diff --git a/HighLevelIL/HLILVariableDeclare.cs b/HighLevelIL/HLILVariableDeclare.cs
index df455ee..7d18bda 100644
--- a/HighLevelIL/HLILVariableDeclare.cs
+++ b/HighLevelIL/HLILVariableDeclare.cs
@@ -11,7 +11,7 @@ BNHighLevelILInstruction native
}
- /*
+ /// The declared variable (Python HighLevelILVarDeclare.var, highlevelil.py).
public HighLevelILVariable Variable
{
get
@@ -19,6 +19,5 @@ public HighLevelILVariable Variable
return this.GetOperandAsVariable((OperandIndex)0);
}
}
- */
}
}
diff --git a/HighLevelIL/HighLevelILDetailedOperandsTable.cs b/HighLevelIL/HighLevelILDetailedOperandsTable.cs
new file mode 100644
index 0000000..345f214
--- /dev/null
+++ b/HighLevelIL/HighLevelILDetailedOperandsTable.cs
@@ -0,0 +1,141 @@
+using System.Collections.Generic;
+
+namespace BinaryNinja
+{
+ // Static table driving HighLevelILInstruction.DetailedOperands. Maps each HighLevelILOperation
+ // to its named operand descriptors (name, kind, raw operand index, Python type name). Generated
+ // from the official Python HighLevelILInstruction.detailed_operands overrides (highlevelil.py),
+ // with abstract-base operands expanded to every concrete op via the Python class hierarchy. Ops
+ // absent from the table have no detailed operands (the base DetailedOperands returns an empty
+ // list). The HLILDetailedOperandsConsistencyTests in the harness assert this table's count +
+ // raw indices still agree with the per-op accessor classes (the guard against the second-table
+ // drift seen with OperationOperands in PR #26/#27/#28).
+ //
+ // ONE intentional divergence from Python: HLIL_ROR. In Python, HighLevelILRor inherits
+ // HighLevelILCarryBase, so its detailed_operands lists a third "carry" operand -- but the core
+ // (highlevelilinstruction.cpp:189) defines HLIL_ROR with only {left, right}; Python's
+ // Ror.carry reads a non-existent slot (garbage). The C# binding follows the core, so ROR has
+ // just {left, right} here and OperationOperands[HLIL_ROR] = 2. RLC/RRC/ADC/SBB genuinely have a
+ // carry slot in the core, so they keep it.
+ internal static class HighLevelILDetailedOperandsTable
+ {
+ internal static readonly Dictionary Table =
+ new Dictionary
+ {
+ { HighLevelILOperation.HLIL_ADC, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("left", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("right", HighLevelILOperandKind.Expression, 1, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("carry", HighLevelILOperandKind.Expression, 2, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_ADD, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("left", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("right", HighLevelILOperandKind.Expression, 1, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_ADDRESS_OF, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("src", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_ADD_OVERFLOW, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("left", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("right", HighLevelILOperandKind.Expression, 1, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_AND, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("left", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("right", HighLevelILOperandKind.Expression, 1, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_ARRAY_INDEX, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("src", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("index", HighLevelILOperandKind.Expression, 1, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_ARRAY_INDEX_SSA, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("src", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("src_memory", HighLevelILOperandKind.Integer, 1, "int"), new HighLevelILOperandDescriptor("index", HighLevelILOperandKind.Expression, 2, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_ASR, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("left", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("right", HighLevelILOperandKind.Expression, 1, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_ASSIGN, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("dest", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("src", HighLevelILOperandKind.Expression, 1, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_ASSIGN_MEM_SSA, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("dest", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("dest_memory", HighLevelILOperandKind.Integer, 1, "int"), new HighLevelILOperandDescriptor("src", HighLevelILOperandKind.Expression, 2, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("src_memory", HighLevelILOperandKind.Integer, 3, "int") } },
+ { HighLevelILOperation.HLIL_ASSIGN_UNPACK, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("dest", HighLevelILOperandKind.ExpressionList, 0, "List[HighLevelILInstruction]"), new HighLevelILOperandDescriptor("src", HighLevelILOperandKind.Expression, 2, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_ASSIGN_UNPACK_MEM_SSA, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("dest", HighLevelILOperandKind.ExpressionList, 0, "List[HighLevelILInstruction]"), new HighLevelILOperandDescriptor("dest_memory", HighLevelILOperandKind.Integer, 2, "int"), new HighLevelILOperandDescriptor("src", HighLevelILOperandKind.Expression, 3, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("src_memory", HighLevelILOperandKind.Integer, 4, "int") } },
+ { HighLevelILOperation.HLIL_BLOCK, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("body", HighLevelILOperandKind.ExpressionList, 0, "List[HighLevelILInstruction]") } },
+ { HighLevelILOperation.HLIL_BOOL_TO_INT, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("src", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_CALL, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("dest", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("params", HighLevelILOperandKind.ExpressionList, 1, "List[HighLevelILInstruction]") } },
+ { HighLevelILOperation.HLIL_CALL_SSA, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("dest", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("params", HighLevelILOperandKind.ExpressionList, 1, "List[HighLevelILInstruction]"), new HighLevelILOperandDescriptor("dest_memory", HighLevelILOperandKind.Integer, 3, "int"), new HighLevelILOperandDescriptor("src_memory", HighLevelILOperandKind.Integer, 4, "int") } },
+ { HighLevelILOperation.HLIL_CASE, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("values", HighLevelILOperandKind.ExpressionList, 0, "List[HighLevelILInstruction]"), new HighLevelILOperandDescriptor("body", HighLevelILOperandKind.Expression, 2, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_CEIL, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("src", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_CMP_E, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("left", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("right", HighLevelILOperandKind.Expression, 1, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_CMP_NE, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("left", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("right", HighLevelILOperandKind.Expression, 1, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_CMP_SGE, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("left", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("right", HighLevelILOperandKind.Expression, 1, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_CMP_SGT, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("left", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("right", HighLevelILOperandKind.Expression, 1, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_CMP_SLE, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("left", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("right", HighLevelILOperandKind.Expression, 1, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_CMP_SLT, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("left", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("right", HighLevelILOperandKind.Expression, 1, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_CMP_UGE, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("left", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("right", HighLevelILOperandKind.Expression, 1, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_CMP_UGT, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("left", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("right", HighLevelILOperandKind.Expression, 1, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_CMP_ULE, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("left", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("right", HighLevelILOperandKind.Expression, 1, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_CMP_ULT, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("left", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("right", HighLevelILOperandKind.Expression, 1, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_CONST, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("constant", HighLevelILOperandKind.Integer, 0, "int") } },
+ { HighLevelILOperation.HLIL_CONST_DATA, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("constant", HighLevelILOperandKind.ConstantData, 0, "ConstantData") } },
+ { HighLevelILOperation.HLIL_CONST_PTR, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("constant", HighLevelILOperandKind.Integer, 0, "int") } },
+ { HighLevelILOperation.HLIL_DEREF, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("src", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_DEREF_FIELD, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("src", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("offset", HighLevelILOperandKind.Integer, 1, "int"), new HighLevelILOperandDescriptor("member_index", HighLevelILOperandKind.Integer, 2, "Optional[int]") } },
+ { HighLevelILOperation.HLIL_DEREF_FIELD_SSA, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("src", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("src_memory", HighLevelILOperandKind.Integer, 1, "int"), new HighLevelILOperandDescriptor("offset", HighLevelILOperandKind.Integer, 2, "int"), new HighLevelILOperandDescriptor("member_index", HighLevelILOperandKind.Integer, 3, "Optional[int]") } },
+ { HighLevelILOperation.HLIL_DEREF_SSA, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("src", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("src_memory", HighLevelILOperandKind.Integer, 1, "int") } },
+ { HighLevelILOperation.HLIL_DIVS, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("left", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("right", HighLevelILOperandKind.Expression, 1, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_DIVS_DP, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("left", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("right", HighLevelILOperandKind.Expression, 1, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_DIVU, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("left", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("right", HighLevelILOperandKind.Expression, 1, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_DIVU_DP, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("left", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("right", HighLevelILOperandKind.Expression, 1, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_DO_WHILE, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("body", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("condition", HighLevelILOperandKind.Expression, 1, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_DO_WHILE_SSA, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("body", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("condition_phi", HighLevelILOperandKind.Expression, 1, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("condition", HighLevelILOperandKind.Expression, 2, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_EXTERN_PTR, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("constant", HighLevelILOperandKind.Integer, 0, "int"), new HighLevelILOperandDescriptor("offset", HighLevelILOperandKind.Integer, 1, "int") } },
+ { HighLevelILOperation.HLIL_FABS, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("src", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_FADD, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("left", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("right", HighLevelILOperandKind.Expression, 1, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_FCMP_E, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("left", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("right", HighLevelILOperandKind.Expression, 1, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_FCMP_GE, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("left", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("right", HighLevelILOperandKind.Expression, 1, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_FCMP_GT, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("left", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("right", HighLevelILOperandKind.Expression, 1, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_FCMP_LE, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("left", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("right", HighLevelILOperandKind.Expression, 1, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_FCMP_LT, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("left", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("right", HighLevelILOperandKind.Expression, 1, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_FCMP_NE, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("left", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("right", HighLevelILOperandKind.Expression, 1, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_FCMP_O, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("left", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("right", HighLevelILOperandKind.Expression, 1, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_FCMP_UO, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("left", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("right", HighLevelILOperandKind.Expression, 1, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_FDIV, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("left", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("right", HighLevelILOperandKind.Expression, 1, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_FLOAT_CONST, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("constant", HighLevelILOperandKind.Float, 0, "float") } },
+ { HighLevelILOperation.HLIL_FLOAT_CONV, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("src", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_FLOAT_TO_INT, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("src", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_FLOOR, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("src", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_FMUL, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("left", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("right", HighLevelILOperandKind.Expression, 1, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_FNEG, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("src", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_FOR, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("init", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("condition", HighLevelILOperandKind.Expression, 1, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("update", HighLevelILOperandKind.Expression, 2, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("body", HighLevelILOperandKind.Expression, 3, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_FOR_SSA, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("init", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("condition_phi", HighLevelILOperandKind.Expression, 1, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("condition", HighLevelILOperandKind.Expression, 2, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("update", HighLevelILOperandKind.Expression, 3, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("body", HighLevelILOperandKind.Expression, 4, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_FSQRT, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("src", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_FSUB, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("left", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("right", HighLevelILOperandKind.Expression, 1, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_FTRUNC, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("src", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_GOTO, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("target", HighLevelILOperandKind.GotoLabel, 0, "GotoLabel") } },
+ { HighLevelILOperation.HLIL_IF, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("condition", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("true", HighLevelILOperandKind.Expression, 1, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("false", HighLevelILOperandKind.Expression, 2, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_IMPORT, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("constant", HighLevelILOperandKind.Integer, 0, "int") } },
+ { HighLevelILOperation.HLIL_INTRINSIC, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("intrinsic", HighLevelILOperandKind.Intrinsic, 0, "ILIntrinsic"), new HighLevelILOperandDescriptor("params", HighLevelILOperandKind.ExpressionList, 1, "List[HighLevelILInstruction]") } },
+ { HighLevelILOperation.HLIL_INTRINSIC_SSA, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("intrinsic", HighLevelILOperandKind.Intrinsic, 0, "ILIntrinsic"), new HighLevelILOperandDescriptor("params", HighLevelILOperandKind.ExpressionList, 1, "List[HighLevelILInstruction]"), new HighLevelILOperandDescriptor("dest_memory", HighLevelILOperandKind.Integer, 3, "int"), new HighLevelILOperandDescriptor("src_memory", HighLevelILOperandKind.Integer, 4, "int") } },
+ { HighLevelILOperation.HLIL_INT_TO_FLOAT, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("src", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_JUMP, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("dest", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_LABEL, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("target", HighLevelILOperandKind.GotoLabel, 0, "GotoLabel") } },
+ { HighLevelILOperation.HLIL_LOW_PART, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("src", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_LSL, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("left", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("right", HighLevelILOperandKind.Expression, 1, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_LSR, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("left", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("right", HighLevelILOperandKind.Expression, 1, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_MEM_PHI, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("dest", HighLevelILOperandKind.Integer, 0, "int"), new HighLevelILOperandDescriptor("src", HighLevelILOperandKind.IntegerList, 1, "List[int]") } },
+ { HighLevelILOperation.HLIL_MODS, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("left", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("right", HighLevelILOperandKind.Expression, 1, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_MODS_DP, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("left", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("right", HighLevelILOperandKind.Expression, 1, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_MODU, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("left", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("right", HighLevelILOperandKind.Expression, 1, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_MODU_DP, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("left", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("right", HighLevelILOperandKind.Expression, 1, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_MUL, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("left", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("right", HighLevelILOperandKind.Expression, 1, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_MULS_DP, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("left", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("right", HighLevelILOperandKind.Expression, 1, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_MULU_DP, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("left", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("right", HighLevelILOperandKind.Expression, 1, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_NEG, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("src", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_NOT, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("src", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_OR, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("left", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("right", HighLevelILOperandKind.Expression, 1, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_RET, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("src", HighLevelILOperandKind.ExpressionList, 0, "List[HighLevelILInstruction]") } },
+ { HighLevelILOperation.HLIL_RLC, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("left", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("right", HighLevelILOperandKind.Expression, 1, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("carry", HighLevelILOperandKind.Expression, 2, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_ROL, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("left", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("right", HighLevelILOperandKind.Expression, 1, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_ROR, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("left", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("right", HighLevelILOperandKind.Expression, 1, "HighLevelILInstruction") } }, // See file header: ROR intentionally omits Python's buggy "carry" (no slot in the core).
+ { HighLevelILOperation.HLIL_ROUND_TO_INT, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("src", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_RRC, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("left", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("right", HighLevelILOperandKind.Expression, 1, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("carry", HighLevelILOperandKind.Expression, 2, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_SBB, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("left", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("right", HighLevelILOperandKind.Expression, 1, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("carry", HighLevelILOperandKind.Expression, 2, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_SPLIT, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("high", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("low", HighLevelILOperandKind.Expression, 1, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_STRUCT_FIELD, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("src", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("offset", HighLevelILOperandKind.Integer, 1, "int"), new HighLevelILOperandDescriptor("member_index", HighLevelILOperandKind.Integer, 2, "Optional[int]") } },
+ { HighLevelILOperation.HLIL_SUB, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("left", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("right", HighLevelILOperandKind.Expression, 1, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_SWITCH, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("condition", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("default", HighLevelILOperandKind.Expression, 1, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("cases", HighLevelILOperandKind.ExpressionList, 2, "List[HighLevelILInstruction]") } },
+ { HighLevelILOperation.HLIL_SX, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("src", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_SYSCALL, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("params", HighLevelILOperandKind.ExpressionList, 0, "List[HighLevelILInstruction]") } },
+ { HighLevelILOperation.HLIL_SYSCALL_SSA, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("params", HighLevelILOperandKind.ExpressionList, 0, "List[HighLevelILInstruction]"), new HighLevelILOperandDescriptor("dest_memory", HighLevelILOperandKind.Integer, 2, "int"), new HighLevelILOperandDescriptor("src_memory", HighLevelILOperandKind.Integer, 3, "int") } },
+ { HighLevelILOperation.HLIL_TAILCALL, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("dest", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("params", HighLevelILOperandKind.ExpressionList, 1, "List[HighLevelILInstruction]") } },
+ { HighLevelILOperation.HLIL_TEST_BIT, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("left", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("right", HighLevelILOperandKind.Expression, 1, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_TRAP, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("vector", HighLevelILOperandKind.Integer, 0, "int") } },
+ { HighLevelILOperation.HLIL_UNIMPL_MEM, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("src", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_VAR, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("var", HighLevelILOperandKind.Variable, 0, "Variable") } },
+ { HighLevelILOperation.HLIL_VAR_DECLARE, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("var", HighLevelILOperandKind.Variable, 0, "Variable") } },
+ { HighLevelILOperation.HLIL_VAR_INIT, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("dest", HighLevelILOperandKind.Variable, 0, "Variable"), new HighLevelILOperandDescriptor("src", HighLevelILOperandKind.Expression, 1, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_VAR_INIT_SSA, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("dest", HighLevelILOperandKind.SSAVariable, 0, "SSAVariable"), new HighLevelILOperandDescriptor("src", HighLevelILOperandKind.Expression, 2, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_VAR_PHI, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("dest", HighLevelILOperandKind.SSAVariable, 0, "SSAVariable"), new HighLevelILOperandDescriptor("src", HighLevelILOperandKind.SSAVariableList, 2, "List[SSAVariable]") } },
+ { HighLevelILOperation.HLIL_VAR_SSA, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("var", HighLevelILOperandKind.SSAVariable, 0, "SSAVariable") } },
+ { HighLevelILOperation.HLIL_WHILE, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("condition", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("body", HighLevelILOperandKind.Expression, 1, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_WHILE_SSA, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("condition_phi", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("condition", HighLevelILOperandKind.Expression, 1, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("body", HighLevelILOperandKind.Expression, 2, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_XOR, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("left", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction"), new HighLevelILOperandDescriptor("right", HighLevelILOperandKind.Expression, 1, "HighLevelILInstruction") } },
+ { HighLevelILOperation.HLIL_ZX, new HighLevelILOperandDescriptor[] { new HighLevelILOperandDescriptor("src", HighLevelILOperandKind.Expression, 0, "HighLevelILInstruction") } },
+ };
+ }
+}
diff --git a/HighLevelIL/HighLevelILOperand.cs b/HighLevelIL/HighLevelILOperand.cs
new file mode 100644
index 0000000..576562e
--- /dev/null
+++ b/HighLevelIL/HighLevelILOperand.cs
@@ -0,0 +1,110 @@
+namespace BinaryNinja
+{
+ ///
+ /// Categorizes one detailed operand of a by how it is read
+ /// from the native instruction's raw operand slots. Mirrors the type strings returned by Python's
+ /// HighLevelILInstruction.detailed_operands (highlevelil.py), collapsed to the reader
+ /// dispatched in .
+ ///
+ public enum HighLevelILOperandKind
+ {
+ /// A single sub-expression (Python type "HighLevelILInstruction").
+ Expression,
+
+ /// A list of sub-expressions (Python type "List[HighLevelILInstruction]").
+ ExpressionList,
+
+ /// A single integer slot (Python type "int" or "Optional[int]").
+ Integer,
+
+ /// A list of integer slots (Python type "List[int]").
+ IntegerList,
+
+ /// A single variable (Python type "Variable").
+ Variable,
+
+ /// A list of variables (Python type "List[Variable]").
+ VariableList,
+
+ /// A single SSA variable occupying two raw slots (Python type "SSAVariable").
+ SSAVariable,
+
+ /// A list of SSA variables (Python type "List[SSAVariable]").
+ SSAVariableList,
+
+ /// A floating-point constant (Python type "float").
+ Float,
+
+ /// A goto label reference (Python type "GotoLabel").
+ GotoLabel,
+
+ /// Constant data (Python type "ConstantData").
+ ConstantData,
+
+ /// An intrinsic reference (Python type "ILIntrinsic").
+ Intrinsic
+ }
+
+ ///
+ /// A named, typed operand of a : the value plus its name,
+ /// kind, and the Python type string. This is the C# equivalent of one
+ /// (name, value, type_str) tuple from Python
+ /// HighLevelILInstruction.detailed_operands (highlevelil.py:795).
+ ///
+ public readonly struct HighLevelILOperand
+ {
+ /// The operand's name, e.g. "left", "src", "condition" (matches Python).
+ public string Name { get; }
+
+ ///
+ /// The operand value. The runtime type follows : a
+ /// , long, ,
+ /// , float, or an array of those. May be null
+ /// when the underlying native operand is absent.
+ ///
+ public object? Value { get; }
+
+ /// How the value was read; drives traversal and variable collection.
+ public HighLevelILOperandKind Kind { get; }
+
+ /// The Python type string, e.g. "HighLevelILInstruction", "int", "Variable".
+ public string TypeName { get; }
+
+ internal HighLevelILOperand(string name, object? value, HighLevelILOperandKind kind, string typeName)
+ {
+ this.Name = name;
+ this.Value = value;
+ this.Kind = kind;
+ this.TypeName = typeName;
+ }
+ }
+
+ ///
+ /// One row of the static detailed-operands table: an operand's name, the reader kind, the raw
+ /// operand index it occupies, and the Python type string. Used to build
+ /// values at query time.
+ ///
+ internal readonly struct HighLevelILOperandDescriptor
+ {
+ internal string Name { get; }
+
+ internal HighLevelILOperandKind Kind { get; }
+
+ ///
+ /// The raw operand slot the value starts at. For
+ /// the version occupies the next slot (index + 1).
+ ///
+ internal int RawIndex { get; }
+
+ internal string TypeName { get; }
+
+ internal HighLevelILOperandDescriptor(
+ string name, HighLevelILOperandKind kind, int rawIndex, string typeName)
+ {
+ this.Name = name;
+ this.Kind = kind;
+ this.RawIndex = rawIndex;
+ this.TypeName = typeName;
+ }
+ }
+}
diff --git a/Struct/BNHighLevelILInstruction.cs b/Struct/BNHighLevelILInstruction.cs
index dc49da3..b632fcd 100644
--- a/Struct/BNHighLevelILInstruction.cs
+++ b/Struct/BNHighLevelILInstruction.cs
@@ -1738,6 +1738,171 @@ public LowLevelILInstruction[] LowLevelILs
}
}
+ ///
+ /// Reads one raw operand slot as a signed integer, mirroring the integer operands exposed by
+ /// Python HighLevelILInstruction detailed_operands (e.g. StructField.offset, Const.constant).
+ ///
+ public long GetOperandAsInteger(OperandIndex operand)
+ {
+ return (long)this.RawOperands[(ulong)operand];
+ }
+
+ ///
+ /// The named, typed operands of this instruction, mirroring Python
+ /// HighLevelILInstruction.detailed_operands (highlevelil.py:795). Each entry pairs the operand
+ /// name (e.g. "left", "src", "condition"), its value, its kind, and the Python type string.
+ /// Operations with no operands return an empty list. This is the foundation for
+ /// and .
+ ///
+ public virtual IList DetailedOperands
+ {
+ get
+ {
+ if (false == HighLevelILDetailedOperandsTable.Table.TryGetValue(
+ this.Operation, out HighLevelILOperandDescriptor[]? descriptors))
+ {
+ return new List();
+ }
+
+ List result = new List(descriptors.Length);
+
+ foreach (HighLevelILOperandDescriptor descriptor in descriptors)
+ {
+ object? value = this.ReadDetailedOperandByKind(descriptor.Kind, descriptor.RawIndex);
+ result.Add(new HighLevelILOperand(
+ descriptor.Name, value, descriptor.Kind, descriptor.TypeName));
+ }
+
+ return result;
+ }
+ }
+
+ ///
+ /// Reads one operand by its descriptor kind. An SSA variable occupies two raw slots -- the
+ /// variable identifier at RawIndex and its version at RawIndex + 1.
+ ///
+ private object? ReadDetailedOperandByKind(HighLevelILOperandKind kind, int rawIndex)
+ {
+ OperandIndex index = (OperandIndex)(ulong)rawIndex;
+
+ switch (kind)
+ {
+ case HighLevelILOperandKind.Expression:
+ return this.GetOperandAsExpression(index);
+
+ case HighLevelILOperandKind.ExpressionList:
+ return this.GetOperandAsExpressionList(index);
+
+ case HighLevelILOperandKind.Integer:
+ return this.GetOperandAsInteger(index);
+
+ case HighLevelILOperandKind.IntegerList:
+ return this.GetOperandAsIntegerArray(index);
+
+ case HighLevelILOperandKind.Variable:
+ return this.GetOperandAsVariable(index);
+
+ case HighLevelILOperandKind.VariableList:
+ return this.GetOperandAsVariableList(index);
+
+ case HighLevelILOperandKind.SSAVariable:
+ return this.GetOperandAsSSAVariable(index, (OperandIndex)(ulong)(rawIndex + 1));
+
+ case HighLevelILOperandKind.SSAVariableList:
+ return this.GetOperandAsSSAVariableList(index);
+
+ case HighLevelILOperandKind.Float:
+ return this.GetOperandAsDouble(index);
+
+ case HighLevelILOperandKind.GotoLabel:
+ return this.GetOperandAsLabel(index);
+
+ case HighLevelILOperandKind.ConstantData:
+ return this.GetOperandAsConstantData(index, (OperandIndex)(ulong)(rawIndex + 1));
+
+ case HighLevelILOperandKind.Intrinsic:
+ return this.GetOperandAsIntrinsic(index);
+
+ default:
+ return null;
+ }
+ }
+
+ ///
+ /// The operand values of this instruction (the value component of
+ /// ), mirroring Python HighLevelILInstruction.operands
+ /// (highlevelil.py:786). Prefer the named accessors (Source, Left, Condition, ...) when the
+ /// operand kind is known at the call site.
+ ///
+ public IList