Open
Description
The difficulty is designing an API that will be useful. Just returning bytes seems prone to hallucinations, but there are definitely valid use cases (analyzing vtables #47). Here is some code from #46:
@jsonrpc
@idaread
def data_read_byte(
address: Annotated[str, "Address to get 1 byte value from"],
) -> int:
"""Get 1 byte value at the specified address"""
ea = parse_address(address)
return ida_bytes.get_wide_byte(ea)
@jsonrpc
@idaread
def data_read_word(
address: Annotated[str, "Address to get 2 bytes value from"],
) -> int:
"""Get 2 bytes value at the specified address"""
ea = parse_address(address)
return ida_bytes.get_wide_word(ea)
@jsonrpc
@idaread
def data_read_dword(
address: Annotated[str, "Address to get 4 bytes value from"],
) -> int:
"""Get 4 bytes value at the specified address"""
ea = parse_address(address)
return ida_bytes.get_wide_dword(ea)
@jsonrpc
@idaread
def data_read_qword(address: Annotated[str, "Address to get 8 bytes value from"]) -> int:
"""Get 8 bytes value at the specified address"""
ea = parse_address(address)
return ida_bytes.get_qword(ea)
@jsonrpc
@idaread
def data_read_string(address: Annotated[str, "Address to get string from"]):
"""Get string at the specified address"""
try:
return idaapi.get_strlit_contents(parse_address(address),-1,0).decode("utf-8")
except Exception as e:
return "Error:" + str(e)
@jsonrpc
@idaread
def get_memory_bytes(
address: Annotated[str, "Address to get memory bytes from"],
size: Annotated[int, "Number of bytes to read"]
) -> list[int]:
"""Get memory bytes (hex) at the given address"""
address = parse_address(address)
data = idc.get_bytes(address, size)
if not data:
raise IDAError(f"Failed to read memory at {hex(address)}")
return list(data)
I lean towards data_read_uint8
, data_read_uint16
, data_read_uint32
, data_read_uint64
that return hex(value)
and discuss convert_number
in their descriptions. Reading a string is also fine, but get_memory_bytes
seems rather pointless (unless the bytes need to be extracted into a script or something).