Пример #1
0
 def activate(self, ctx):
     f = search_strlit_form_t()
     f, args = f.Compile()
     ok = f.Execute()
     if ok:
         current_ea = ida_kernwin.get_screen_ea()
         patterns = ida_bytes.compiled_binpat_vec_t()
         encoding = ida_nalt.get_default_encoding_idx(
             ida_nalt.BPU_2B if f.Encoding.value else ida_nalt.BPU_1B)
         # string literals must be quoted. That's how parse_binpat_str
         # recognizes them (we want to be careful though: the user
         # might type in something like 'L"hello"', which should
         # decode to the IDB-specific wide-char set of bytes)
         text = f.Text.value
         if text.find('"') < 0:
             text = '"%s"' % text
         err = ida_bytes.parse_binpat_str(
             patterns,
             current_ea,
             text,
             10,  # radix (not that it matters though, since we're all about string literals)
             encoding)
         if not err:
             ea = ida_bytes.bin_search(
                 current_ea, ida_ida.inf_get_max_ea(), patterns,
                 ida_bytes.BIN_SEARCH_FORWARD
                 | ida_bytes.BIN_SEARCH_NOBREAK
                 | ida_bytes.BIN_SEARCH_NOSHOW)
             ok = ea != ida_idaapi.BADADDR
             if ok:
                 ida_kernwin.jumpto(ea)
         else:
             print("Failed parsing binary pattern: \"%s\"" % err)
     return ok
Пример #2
0
def bin_search(bin_str: str) -> List[int]:
    if not isinstance(bin_str, str):
        raise ValueError('bin_str must be a string')

    if bin_str in cached_patterns:
        return cached_patterns[bin_str]

    bin_list = bin_str.split()
    image = bytearray()
    mask = bytearray()

    # Create the mask and convert '?' to 'CC'.
    for i in range(len(bin_list)):
        byte = bin_list[i]
        if byte == '?':
            image.append(int('CC', 16))
            mask.append(0)
        else:
            image.append(int(byte, 16))
            mask.append(1)

    image = bytes(image)
    mask = bytes(mask)

    start = ida_nalt.get_imagebase()
    end = ida_idaapi.BADADDR

    addrs: List[int] = []

    ea = ida_bytes.bin_search(start, end, image, mask, 0,
                              ida_bytes.BIN_SEARCH_FORWARD)
    while ea != ida_idaapi.BADADDR:
        addrs.append(ea)
        ea = ida_bytes.bin_search(ea + len(image), end, image, mask, 0,
                                  ida_bytes.BIN_SEARCH_FORWARD)

    cached_patterns[bin_str] = addrs
    return cached_patterns[bin_str]
Пример #3
0
def masked_search(start_addr: int, end_addr: int, bytes_data: bytes, masks_data: bytes) -> Tuple[int, Optional[bytes]]:
    def prepare_first_search(bd: bytes, md: bytes) -> bytes:
        bd_str = binascii.hexlify(bd, ' ').split(b' ')
        md_str = binascii.hexlify(md, ' ').split(b' ')

        for ii, md_token in enumerate(md_str):
            if md_token != b'ff':
                bd_str[ii] = b'?'

        bd_str = b' '.join(bd_str)

        return bd_str

    len_bytes = len(bytes_data)

    bytes_data_prep = prepare_first_search(bytes_data, masks_data)

    if idaapi.IDA_SDK_VERSION >= 760:
        patterns = ida_bytes.compiled_binpat_vec_t()
        idaapi.parse_binpat_str(patterns, start_addr, bytes_data_prep.decode(), 16)
        ea = ida_bytes.bin_search(start_addr, end_addr, patterns,
                                  ida_bytes.BIN_SEARCH_FORWARD |
                                  ida_bytes.BIN_SEARCH_NOBREAK |
                                  ida_bytes.BIN_SEARCH_NOSHOW)
    else:
        ea = ida_search.find_binary(start_addr, end_addr, bytes_data_prep.decode(), 16, idaapi.SEARCH_DOWN)

    if ea == idaapi.BADADDR:
        return idaapi.BADADDR, None

    found_bytes = idaapi.get_bytes(ea, len_bytes)

    equal = True
    for i in range(len_bytes):
        m = masks_data[i]
        if found_bytes[i] & m != bytes_data[i] & m:
            equal = False
            break

    if equal:
        return ea, found_bytes

    return idaapi.BADADDR, None