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

Function ReadILOperand

arch/x86/il.cpp:193–249  ·  view source on GitHub ↗

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

191// 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
192// Instruction index represents the 'nth' argument/opcode in the instruction, whereas the operand index is index that XED holds that operand in the instruction
193static size_t ReadILOperand(LowLevelILFunction& il, const xed_decoded_inst_t* const xedd,
194 const size_t addr, const size_t instruction_index,
195 const size_t operand_index, size_t sizeToRead = 0)
196{
197 if (sizeToRead == 0)
198 sizeToRead = xed_decoded_inst_operand_length_bits(xedd, (unsigned)operand_index) / 8;
199 const unsigned int immediateSize = xed_decoded_inst_get_operand_width(xedd) / 8;
200 const int64_t relbr = xed_decoded_inst_get_branch_displacement(xedd) + addr + xed_decoded_inst_get_length(xedd);
201 const xed_operand_enum_t op_name = xed_operand_name(xed_inst_operand(xed_decoded_inst_inst(xedd), (unsigned)operand_index));
202 const auto reg1 = xed_decoded_inst_get_reg(xedd, op_name);
203 const size_t addrSize = xed_decoded_inst_get_machine_mode_bits(xedd) / 8;
204
205 switch (op_name)
206 {
207 // Register cases
208 case XED_OPERAND_REG0:
209 case XED_OPERAND_REG1:
210 case XED_OPERAND_REG2:
211 case XED_OPERAND_REG3:
212 case XED_OPERAND_REG4:
213 case XED_OPERAND_REG5:
214 case XED_OPERAND_REG6:
215 case XED_OPERAND_REG7:
216 case XED_OPERAND_REG8:
217 case XED_OPERAND_BASE0:
218 case XED_OPERAND_BASE1:
219 if ((reg1 == XED_REG_RIP) || (reg1 == XED_REG_EIP) || (reg1 == XED_REG_IP))
220 return il.Operand(instruction_index, il.ConstPointer(sizeToRead, addr));
221 return il.Operand(instruction_index, il.Register(sizeToRead, (uint32_t)reg1));
222
223 // Immediates:
224 case XED_OPERAND_IMM0:
225 if (xed_decoded_inst_get_immediate_is_signed(xedd))
226 return il.Operand(instruction_index, il.Const(immediateSize, xed_decoded_inst_get_signed_immediate(xedd)));
227 else
228 return il.Operand(instruction_index, il.Const(immediateSize, xed_decoded_inst_get_unsigned_immediate(xedd)));
229
230 // Second Immdiate Value
231 case XED_OPERAND_IMM1:
232 return il.Operand(instruction_index, il.Const(1, xed_decoded_inst_get_second_immediate(xedd)));
233
234 // Immediate Address Value
235 case XED_OPERAND_PTR:
236 case XED_OPERAND_RELBR:
237 return il.Operand(instruction_index, il.ConstPointer(addrSize, relbr));
238
239 // Memory Acesses
240 case XED_OPERAND_AGEN:
241 case XED_OPERAND_MEM0:
242 case XED_OPERAND_MEM1:
243 return il.Operand(instruction_index, il.Load(sizeToRead, GetILOperandMemoryAddress(il, xedd, addr, instruction_index, operand_index)));
244
245 // Not implimented or error
246 default:
247 return il.Undefined();
248 }
249}
250

Callers 3

CMovFlagCondFunction · 0.70
CMovFlagGroupFunction · 0.70

Calls 7

OperandMethod · 0.80
ConstPointerMethod · 0.45
RegisterMethod · 0.45
ConstMethod · 0.45
LoadMethod · 0.45
UndefinedMethod · 0.45

Tested by

no test coverage detected