0

For example:

68 38 30 42 00    push    offset aUser32_dll_0 ; "USER32.DLL"

If I get an operand value using GetOperandValue(), how can I check this immediate value is a valid linear address?

Neitsa
  • 7,693
  • 1
  • 28
  • 45
Keen
  • 1
  • 1
  • 3
  • Usually if the argument is an address it will be somewhere within the image of the currently executing PE image (assuming Windows). You can get the start addresses and ranges of sections in the PE by parsing its header. msdn.com has the PE specification where this is explained. – 500 - Internal Server Error Apr 21 '15 at 22:06

1 Answers1

3

A possible script could be as follow:

#!/usr/bin/env python
from __future__ import print_function
import idaapi 

def main():
    # get instruction at mouse pos
    current_ea = idaapi.get_screen_ea()
    print("[*] Current screen ea: {:#x}".format(current_ea))

    #get instruction operand
    insn = idaapi.decode_insn(current_ea)
    op = idaapi.cmd.Operands[0]

    # check if immediate value
    if op.type == idaapi.idaapi.o_imm:
        # get operand value
        imm_value = op.value
        print("[*] current operand is an immediate: {:#x}".format(imm_value))

        # check if addres is loaded in idb
        print("[*] {:#x} is loaded in IDB? -> {}".format(imm_value,
            idaapi.isLoaded(imm_value)))

        # get segment for immediate value
        seg = idaapi.getseg(imm_value)
        print("[*] Segment start for {:#x} is {:#x}".format(imm_value, 
            seg.startEA))
    else:
        print("[-] Not an immediate")

if __name__ == "__main__":
    main()

Select an address in IDA view and then run the above script.

The script verifies that the instruction first operand is an immediate value. If it is, then it just checkq that the address of this immediate value is known by IDA (there are multiple ways of checking this, I just used isLoaded() and getseg()).

This obviously checks that the address is located inside the IDB. An address might be a valid virtual address in program context but located outside the IDB, and IDA has no way to know this.

Example (selecting the address 0x1019D5B1 in IDA view):

.text:1019D5B1    push    offset aAddr@P  ; " Addr @ %p\n"
.text:1019D5B6    call    pOutputRoutine

The offset aAddr@Pis located at 0x100A4ECC:

.text:100A4ECC aAddr@P         db ' Addr @ %p',0Ah,0 

Script output:

[*] Current screen ea: 0x1019d5b1
[*] current operand is an immediate: 0x100a4ecc
[*] 0x100a4ecc is loaded in IDB? -> True
[*] Segment start for 0x100a4ecc is 0x10001000
Neitsa
  • 7,693
  • 1
  • 28
  • 45
  • You should use is_mapped not is_loaded. is_loaded will only return true if the address has data, not if it's a part of a segment mapped in the IDB – Avery3R Jan 10 '20 at 22:15