例如:
68 38 30 42 00 push offset aUser32_dll_0 ; "USER32.DLL"
如果使用GetOperandValue()获取操作数值,如何检查此立即值是否为有效的线性地址?
答案 0 :(得分:2)
可能的脚本如下:
#!/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()
在IDA视图中选择一个地址,然后运行上面的脚本。
该脚本验证指令第一个操作数是否为立即值。如果是,那么只需检查IDA是否知道该直接值的地址(有多种方法可以检查这一点,我只使用了isLoaded()
和getseg()
)。
这显然会检查地址是否位于IDB内。地址可能是程序上下文中的有效虚拟地址,但位于IDB之外,IDA无法知道这一点。
示例(在IDA视图中选择地址0x1019D5B1):
.text:1019D5B1 push offset aAddr@P ; " Addr @ %p\n"
.text:1019D5B6 call pOutputRoutine
offset aAddr@P
位于0x100A4ECC:
.text:100A4ECC aAddr@P db ' Addr @ %p',0Ah,0
脚本输出:
[*] Current screen ea: 0x1019d5b1
[*] current operand is an immediate: 0x100a4ecc
[*] 0x100a4ecc is loaded in IDB? -> True
[*] Segment start for 0x100a4ecc is 0x10001000