4

I am trying to get the byte size of all operands in a given instruction from IDA Pro. At first I tried using GetOperandValue(ea,n) to see how large the value was and calculate how many bytes were necessary to store that value, but it doesn't return leading zeros, which means that it doesn't work.

Now I am trying to use OpHex(ea,n) to get the answer, but it's just returning True (as do OpDecimal, OpBinary, and OpOctal).

How can I find the number of bytes used for operands of a particular instruction and why is OpHex returning true?

Edit: My current solution works, but I would still like one that is more technically correct and bulletproof. Right now I am just using GetOperandValue(ea, op) to get both operands for all instructions (even if they have neither or only one) and then checking to make sure the operand value is greater than FF. If It's greater than FF I just assume it is an address, which in this case is four bytes. If both operands meet this condition, I assign the size to be eight bytes.

This works for the moment, but will encounter difficulties in eventual moves to other architectures (right now I'm just working with x86-64).

2
  • 1
    Do you mean a value in an opcode instruction like mov or the size of a data structure to which some pointer is pointing?
    – pudi
    Nov 8, 2018 at 6:10
  • The size of the operand(s) in an opcode instruction, not the size to which it is pointing. To recreate the relocation I need to know how many bytes to overwrite with addresses. Nov 13, 2018 at 17:36

3 Answers 3

1

Module ida_ua now contains a function get_dtype_size, which seems to implement @WHsT's answer.

Assuming you have an instruction i, you can use it e.g. like this:

ida_ua.get_dtype_size(i.Op1.dtype))

1
  • I no longer have the ability to test this; marking as answered, unless someone tags me in the comments that this doesn't work. Thanks @langlauf.io Jun 23, 2022 at 12:15
3

There doesn't seem to be a straightforward way to achieve this. But you can take a look at this page of the IDA SDK documentation.

According to the description of the previous page, we can write a little helper function:

def size_of_operand(op):
    tbyte = 8
    dt_ldbl = 8
    n_bytes = [ 1, 2, 4, 4, 8,
            tbyte, -1, 8, 16, -1,
            -1, 6, -1, 4, 4,
            dt_ldbl, 32, 64 ]
    return n_bytes[op.dtype]

Now we can use command like

insn = idautils.DecodeInstruction(ScreenEA())
index_of_operand = 0
size_of_operand(insn.Operand[index_of_operand])

to get the size of an operand.

For example, for xor al, al, it returns 1. For pop ebp, it returns 4.

Note: refer to Porting from IDAPython 6.x-7.3, to 7.4

2

Are You Loooking for some thing like

Message("%s\n" , GetCurrentLine());
Message("%x\n" , ItemSize(ScreenEA()));

this will give results as below

.text:010328BB 56                            push    esi
1
.text:010328BC BE 10 42 05 01                mov     esi, offset unk_1054210
5
.text:010328C1                               cmp     byte_1054309, bl
6
.text:010328C1 38 1D 09 43 05 01             cmp     byte_1054309, bl
6

Note: refer to Porting from IDAPython 6.x-7.3, to 7.4

2
  • 1
    Seems the inquirer is only interested in the size of the operands, not the instructions overall. But this is close.
    – 0xC0000022L
    Nov 15, 2018 at 21:24
  • Yes, @0xC0000022L is correct. Nov 16, 2018 at 18:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.