OALabs/hashdb-ida

give user feedback about hashdb background thread

herrcore opened this issue · 1 comments

Problem Statement
Give the user some indication that there is a hashdb thread running in the background.

Currently IDA will freeze up when adding a large enum which can cause a poor user experience if the user forgets that there is a background thread running.

Proposed Solution
IDA is limited in the type of feedback we can give the user so the current idea is to temporarily add a toolbar when the thread is active and remove it once the thread completes (or crashes). The toolbar could also be used to kill the thread if the user wants.

Brutal IDA has template code that could re-used.

After some testing, it looks like the freezing part can be avoided altogether. I finally figured out how the type parsing window works when inserting new types into the TIL.
I've written a POC with a sample size of 16384 enum values which loads relatively quickly on my machine (0.83 seconds):

import random
import string
from time import perf_counter

import ida_enum
import ida_idaapi
import ida_typeinf


def generate_values() -> tuple[str, int, bool]:
    return "".join(random.choice(string.ascii_letters) for _ in range(16)), random.randint(0, 0xFFFFFFFF), False


def add_enum(name: str, is_64_bit: bool, hash_count: int) -> None:
    enum_name: str = name + (": unsigned __int64" if is_64_bit else "")
    hash_list: tuple[tuple[str, int, bool], ...] = tuple(generate_values() for _ in range(hash_count))

    values: str = ",".join(f"{name} = {value:#x}" for name, value, _ in hash_list)
    enum_source: str = f"enum {enum_name} {{ {values} }};"
    
    begin: float = perf_counter()
    
    ida_typeinf.idc_parse_types(enum_source, 0)  # parse the types
    enum_id = ida_typeinf.import_type(ida_typeinf.get_idati(), -1, name, 0)  # sync the types with the IDB
    
    time_to_parse: float = perf_counter() - begin
    print(f"Added {hash_count} enum values in {time_to_parse:.2f} seconds. {enum_id=:#x}")


def main() -> None:
    add_enum("hashdb_strings_crc32", False, 2**4)
    add_enum("hashdb_strings_crc64", True, 2**4)


if __name__ == "__main__":
    main()

The sample size is dramatically increased from any real world sample that might be provided by HashDB to show this method's effectiveness.
I'll look into implementing it when I can.