mirror of
https://github.com/idapython/src
synced 2026-06-08 14:47:00 +00:00
104 lines
2.7 KiB
Python
104 lines
2.7 KiB
Python
'''
|
|
summary: Use bin_search to find the occurences of
|
|
"mov rax, cs:___security_cookie"
|
|
|
|
description:
|
|
This example shows a way of finding the
|
|
"mov rax, cs:___security_cookie" instruction in a x64 database using
|
|
bin_search. For this we:
|
|
* check that the database is, indeed an x64 one
|
|
* build the binary pattern vector
|
|
* search for the pattern
|
|
* for each result we validate that operand 1 (Op2.addr) points to
|
|
__security_cookie
|
|
* once the list is built, print it ([index] func_name @ address)
|
|
'''
|
|
|
|
import ida_bytes
|
|
import ida_idaapi
|
|
import ida_name
|
|
import ida_funcs
|
|
import ida_ua
|
|
import ida_ida
|
|
|
|
message = 'Pattern \"mov rax, cs:__security_cookie\" found:'
|
|
|
|
pattern_bytes = b'\x48\x8B\x05\x56\xAF\x35\x00'
|
|
pattern_mask = b'\x01\x01\x01\x00\x00\x00\x01'
|
|
|
|
def is_pc_64():
|
|
if ida_ida.inf_get_procname() != 'metapc' and not ida_ida.inf_is64bit():
|
|
return False
|
|
return True
|
|
|
|
def build_pattern_vec(bytes, mask = None):
|
|
pattern = ida_bytes.compiled_binpat_t()
|
|
pattern.bytes = bytes
|
|
if mask:
|
|
pattern.mask = mask
|
|
|
|
pattern_vec = ida_bytes.compiled_binpat_vec_t()
|
|
pattern_vec.push_back(pattern)
|
|
|
|
return pattern_vec
|
|
|
|
def is_valid(ea, sc_ea):
|
|
insn = ida_ua.insn_t()
|
|
ida_ua.decode_insn(insn, ea)
|
|
|
|
op = insn.Op2
|
|
if op.type == 2 and op.dtype == 7 and op.addr == sc_ea:
|
|
return True
|
|
|
|
return False
|
|
|
|
def build_ea_list(start_ea, end_ea, pattern_vec, flags, sc_ea):
|
|
ea_list = []
|
|
|
|
while start_ea < end_ea:
|
|
start_ea, _ = ida_bytes.bin_search(start_ea, end_ea, pattern_vec, flags)
|
|
if start_ea == ida_idaapi.BADADDR:
|
|
break
|
|
|
|
if is_valid(start_ea, sc_ea):
|
|
ea_list.append(start_ea)
|
|
|
|
start_ea += 1
|
|
|
|
return ea_list
|
|
|
|
def print_result(str, lst):
|
|
print(str)
|
|
|
|
idx = 0
|
|
for ea in lst:
|
|
fname = ida_funcs.get_func_name(ea)
|
|
dname = ida_name.demangle_name(fname, 0)
|
|
pname = fname
|
|
if dname:
|
|
pname = dname
|
|
|
|
print(f'[{idx}] {pname} @ {ea:x}')
|
|
idx += 1
|
|
|
|
|
|
def main():
|
|
if not is_pc_64():
|
|
print('This script will only work for x64 databases.')
|
|
return
|
|
|
|
security_ea = ida_name.get_name_ea(ida_idaapi.BADADDR, '__security_cookie')
|
|
if security_ea == ida_idaapi.BADADDR:
|
|
print('No reference to __security_cookie.')
|
|
return
|
|
|
|
pv = build_pattern_vec(pattern_bytes, pattern_mask)
|
|
|
|
flags = ida_bytes.BIN_SEARCH_FORWARD | ida_bytes.BIN_SEARCH_NOCASE | ida_bytes.BIN_SEARCH_NOBREAK
|
|
lst = build_ea_list(ida_ida.inf_get_min_ea(), ida_ida.inf_get_max_ea(), pv, flags, security_ea)
|
|
|
|
print_result(message, lst)
|
|
|
|
if __name__ == '__main__':
|
|
main()
|