MCPcopy Create free account
hub / github.com/Vector35/binaryninja-api / GetILOperandMemoryAddress

Function GetILOperandMemoryAddress

arch/x86/il.cpp:54–188  ·  view source on GitHub ↗

TODO handle imms for MPX args For most instructions, instruction_index == operand_index, but some instructions (floating point, some others) have an implicit first operand (st0), so we have to remap things a bit Instruction index represents the 'nth' argument/opcode in the instruction, whereas the operand index is index that XED holds that operand in the instruction

Source from the content-addressed store, hash-verified

52// For most instructions, instruction_index == operand_index, but some instructions (floating point, some others) have an implicit first operand (st0), so we have to remap things a bit
53// Instruction index represents the 'nth' argument/opcode in the instruction, whereas the operand index is index that XED holds that operand in the instruction
54static size_t GetILOperandMemoryAddress(LowLevelILFunction& il, const xed_decoded_inst_t* xedd, const uint64_t addr, const size_t instruction_index, const size_t operand_index)
55{
56 const xed_inst_t* xi = xed_decoded_inst_inst(xedd);
57 const xed_operand_t* op = xed_inst_operand(xi, (unsigned)operand_index);
58 const xed_operand_values_t* ov = xed_decoded_inst_operands_const(xedd);
59 const xed_operand_enum_t op_name = xed_operand_name(op);
60 size_t offset = BN_INVALID_EXPR;
61 const size_t addrSize = xed_decoded_inst_get_machine_mode_bits(xedd) / 8;
62
63 switch(op_name)
64 {
65 case XED_OPERAND_AGEN:
66 case XED_OPERAND_MEM0:
67 {
68 const int64_t disp = xed_decoded_inst_get_memory_displacement(xedd, 0);
69
70 // [reg] if reg != instruction_pointer
71 const xed_reg_enum_t base = xed_decoded_inst_get_base_reg(xedd, 0);
72 if ((base != XED_REG_INVALID) && !((base == XED_REG_RIP) || (base == XED_REG_EIP) || (base == XED_REG_IP)))
73 {
74 offset = il.Register(addrSize, base);
75 }
76 else if ((base == XED_REG_RIP) || (base == XED_REG_EIP) || (base == XED_REG_IP)) // Resolve RIP to a constant
77 {
78 if (xed_operand_values_has_memory_displacement(ov) && (disp != 0))
79 return il.Operand(instruction_index, il.ConstPointer(addrSize, disp + addr + xed_decoded_inst_get_length(xedd)));
80 else
81 return il.Operand(instruction_index, il.ConstPointer(addrSize, addr + xed_decoded_inst_get_length(xedd)));
82 }
83
84 // [...+reg] or [...+reg*const] or [reg*const]
85 const xed_reg_enum_t index = xed_decoded_inst_get_index_reg(xedd, 0);
86 bool constIsPointer = false;
87 if (index != XED_REG_INVALID)
88 if (!xed_decoded_inst_get_attribute(xedd, XED_ATTRIBUTE_INDEX_REG_IS_POINTER)) // MPX...TODO (extra registers)
89 {
90 const unsigned int scale = xed_decoded_inst_get_scale(xedd, 0);
91 if (scale != 1)
92 {
93 unsigned short shift = 0;
94 if (scale == 2)
95 shift = 1;
96 else if (scale == 4)
97 shift = 2;
98 else if (scale == 8)
99 shift = 3;
100 if (offset != BN_INVALID_EXPR)
101 offset = il.Add(addrSize,
102 offset,
103 il.ShiftLeft(addrSize,
104 il.Register(addrSize, index),
105 il.Const(1, shift)));
106 else
107 {
108 // case for [...+reg*const] so we know that the const must be a pointer
109 constIsPointer = true;
110 offset = il.ShiftLeft(addrSize,
111 il.Register(addrSize, index),

Callers 4

ReadILOperandFunction · 0.70
ReadFloatILOperandFunction · 0.70
WriteILOperandFunction · 0.70

Calls 6

OperandMethod · 0.80
RegisterMethod · 0.45
ConstPointerMethod · 0.45
AddMethod · 0.45
ShiftLeftMethod · 0.45
ConstMethod · 0.45

Tested by

no test coverage detected