mirror of
https://github.com/idapython/src
synced 2026-06-08 14:47:00 +00:00
IDAPython for IDA 9.1
This commit is contained in:
@@ -0,0 +1 @@
|
||||
from PySide6.QtCore import *
|
||||
@@ -0,0 +1 @@
|
||||
from PySide6.QtGui import *
|
||||
@@ -0,0 +1 @@
|
||||
from PySide6.QtWidgets import *
|
||||
@@ -0,0 +1,17 @@
|
||||
print("#" * 70)
|
||||
print("""# Please note that IDA is now using Qt 6, and PyQt5
|
||||
# support will be dropped eventually.
|
||||
# It is recommended to port your scripts/plugins to PySide6
|
||||
# as soon as possible.
|
||||
# Essentially, that means rewriting statement such as:
|
||||
#
|
||||
# import PyQt5
|
||||
# import PyQt5.QtWidgets
|
||||
# from PyQt5.QtGui import QGuiApplication
|
||||
#
|
||||
# into:
|
||||
#
|
||||
# import PySide6
|
||||
# import PySide6.QtWidgets
|
||||
# from PySide6.QtGui import QGuiApplication""")
|
||||
print("#" * 70)
|
||||
@@ -0,0 +1 @@
|
||||
# Placeholder
|
||||
@@ -15,7 +15,7 @@ Latest stable versions of IDAPython are available from
|
||||
## Resources
|
||||
|
||||
The full function cross-reference is readable online at
|
||||
https://www.hex-rays.com/products/ida/support/idapython_docs/
|
||||
https://python.docs.hex-rays.com
|
||||
|
||||
Mailing list for the project is hosted by Google Groups at
|
||||
https://groups.google.com/g/idapython
|
||||
|
||||
@@ -13,8 +13,3 @@ please run `idapyswitch` from the IDA directory. It will scan for Python
|
||||
installs present in the system's standard locations and offer you to choose one.
|
||||
It also supports optional command-line switches to handle non-standard installs.
|
||||
Run `idapyswitch -h` to see them.
|
||||
|
||||
On Windows, you may need to run it as administrator
|
||||
so it can patch sip.pyd (library required for PyQt bindings).
|
||||
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@ dbg.hpp - INCOMPLETE (SWIGs and lot of fixing to do)
|
||||
demangle.hpp - EXCLUDED
|
||||
diskio.hpp - INCOMPLETE (no SWIGs, some unwrapped)
|
||||
entry.hpp - COMPLETE
|
||||
enum.hpp - COMPLETE
|
||||
err.h - EXCLUDED
|
||||
exehdr.h - EXCLUDED
|
||||
expr.hpp - COMPLETE (necessary SWIGs)
|
||||
@@ -57,7 +56,6 @@ segment.hpp - COMPLETE
|
||||
sistack.hpp - EXCLUDED
|
||||
segregs.hpp - INCOMPLETE (not wrapped at all)
|
||||
strlist.hpp - COMPLETE
|
||||
struct.hpp - COMPLETE
|
||||
typeinf.hpp - INCOMPLETE (no SWIGs, lot of fixing to do)
|
||||
ua.hpp - INCOMPLETE (SWIGs and lot of fixing to do)
|
||||
va.hpp - EXCLUDED
|
||||
|
||||
@@ -4,7 +4,7 @@ A script that tries to determine the call stack
|
||||
|
||||
Run the application with the debugger, suspend the debugger, select a thread and finally run the script.
|
||||
|
||||
Copyright (c) 1990-2024 Hex-Rays
|
||||
Copyright (c) 1990-2025 Hex-Rays
|
||||
ALL RIGHTS RESERVED.
|
||||
"""
|
||||
import ida_ua
|
||||
@@ -169,7 +169,7 @@ def main():
|
||||
return
|
||||
|
||||
# get all debug namesp
|
||||
dn = ida_name.get_debug_names(ida_ida.cvar.inf.min_ea, ida_ida.cvar.inf.max_ea)
|
||||
dn = ida_name.get_debug_names(ida_ida.inf_get_min_ea(), ida_ida.inf_get_max_ea())
|
||||
# initiate a nearest name search (using debug names)
|
||||
nn = ida_name.NearestName(dn)
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
A script to demonstrate how to send commands to the debugger and then parse and use the output in IDA
|
||||
|
||||
Copyright (c) 1990-2024 Hex-Rays
|
||||
Copyright (c) 1990-2025 Hex-Rays
|
||||
ALL RIGHTS RESERVED.
|
||||
|
||||
"""
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
This script shows how to send debugger commands and use the result in IDA
|
||||
|
||||
Copyright (c) 1990-2024 Hex-Rays
|
||||
Copyright (c) 1990-2025 Hex-Rays
|
||||
ALL RIGHTS RESERVED.
|
||||
|
||||
"""
|
||||
|
||||
@@ -13,7 +13,7 @@ The general syntax is:
|
||||
* To specify in which context the instructions should be assembled, pass asm_where=ea:
|
||||
find("jmp dword ptr [esp]", asm_where=here())
|
||||
|
||||
Copyright (c) 1990-2024 Hex-Rays
|
||||
Copyright (c) 1990-2025 Hex-Rays
|
||||
ALL RIGHTS RESERVED.
|
||||
"""
|
||||
from __future__ import print_function
|
||||
@@ -27,7 +27,6 @@ import ida_kernwin
|
||||
import ida_bytes
|
||||
import ida_ua
|
||||
import ida_ida
|
||||
import ida_search
|
||||
import ida_funcs
|
||||
|
||||
import idautils
|
||||
@@ -76,10 +75,10 @@ def FindInstructions(instr, asm_where=None):
|
||||
|
||||
# find all binary strings
|
||||
print("Searching for: [%s]" % bin_str)
|
||||
ea = ida_ida.cvar.inf.min_ea
|
||||
ea = ida_ida.inf_get_min_ea()
|
||||
ret = []
|
||||
while True:
|
||||
ea = ida_search.find_binary(ea, ida_idaapi.BADADDR, bin_str, 16, ida_search.SEARCH_DOWN)
|
||||
ea = ida_bytes.find_bytes(bin_str, ea, radix=16)
|
||||
if ea == ida_idaapi.BADADDR:
|
||||
break
|
||||
ret.append(ea)
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@ A script that graphs all the exception handlers in a given process
|
||||
|
||||
It will be easy to see what thread uses what handler and what handlers are commonly used between threads
|
||||
|
||||
Copyright (c) 1990-2024 Hex-Rays
|
||||
Copyright (c) 1990-2025 Hex-Rays
|
||||
ALL RIGHTS RESERVED.
|
||||
"""
|
||||
from __future__ import print_function
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
|
||||
This script shows how to send debugger commands and use the result in IDA
|
||||
|
||||
Copyright (c) 1990-2024 Hex-Rays
|
||||
Copyright (c) 1990-2025 Hex-Rays
|
||||
ALL RIGHTS RESERVED.
|
||||
|
||||
"""
|
||||
|
||||
@@ -2,7 +2,7 @@ from __future__ import print_function
|
||||
# -----------------------------------------------------------------------
|
||||
# VirusTotal IDA Plugin
|
||||
# By Elias Bachaalany <elias at hex-rays.com>
|
||||
# (c) Hex-Rays 2011-2024
|
||||
# (c) Hex-Rays 2011-2025
|
||||
#
|
||||
# Special thanks:
|
||||
# - VirusTotal team
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
# API examples
|
||||
|
||||
|
||||
This file contains the list of all the IDA python examples.
|
||||
|
||||
|
||||
## func
|
||||
|
||||
* decompile_func_and_callees.py
|
||||
* list_func_callees.py
|
||||
* print_location_info.py
|
||||
* sort_func_by_calls.py
|
||||
|
||||
## gdl
|
||||
|
||||
* colorize_graph_node.py
|
||||
|
||||
## hexrays
|
||||
|
||||
* hr_decompile_func_and_callees.py
|
||||
|
||||
## idb
|
||||
|
||||
* frame_event_listener.py
|
||||
* lt_event_listener.py
|
||||
|
||||
## idp
|
||||
|
||||
* log_idp_events.py
|
||||
|
||||
## inf
|
||||
|
||||
* print_basic_info.py
|
||||
* print_basic_info_plugin.py
|
||||
|
||||
## misc
|
||||
|
||||
* find_binary_pattern.py
|
||||
|
||||
## segm
|
||||
|
||||
* list_imports.py
|
||||
|
||||
## typeinf
|
||||
|
||||
* add_frame_member.py
|
||||
* apply_callee_tinfo.py
|
||||
* change_stkvar_name.py
|
||||
* change_stkvar_type.py
|
||||
* create_array.py
|
||||
* create_bfstruct.py
|
||||
* create_bmenum.py
|
||||
* create_libssh2_til.py
|
||||
* create_structs.py
|
||||
* create_user_shared_data.py
|
||||
* del_struct_members.py
|
||||
* func_ti_changed_listener.py
|
||||
* gap_size_align_snippet.py
|
||||
* import_type_from_til.py
|
||||
* insert_gap.py
|
||||
* list_enum_member.py
|
||||
* list_frame_info.py
|
||||
* list_func_details.py
|
||||
* list_stkvar_xrefs.py
|
||||
* list_struct_accesses.py
|
||||
* list_struct_member.py
|
||||
* list_struct_xrefs.py
|
||||
* list_union_member.py
|
||||
* mark_func_spoiled.py
|
||||
* operand_to_struct_member.py
|
||||
* setpehdr.py
|
||||
* visit_tinfo.py
|
||||
@@ -0,0 +1,104 @@
|
||||
import ida_idaapi
|
||||
import ida_dbg
|
||||
import ida_kernwin
|
||||
import ida_name
|
||||
import ida_idd
|
||||
import ida_bytes
|
||||
import ida_ida
|
||||
import ida_ua
|
||||
import idc
|
||||
import os
|
||||
|
||||
ST_NONE = 0
|
||||
ST_RUNTO = 1
|
||||
ST_ADD_BPT = 2
|
||||
ST_MONITOR = 3
|
||||
|
||||
func_name = 'kernelbase_CreateFileW'
|
||||
|
||||
class filemon_dbg_hook_t(ida_dbg.DBG_Hooks):
|
||||
def __init__(self):
|
||||
ida_dbg.DBG_Hooks.__init__(self)
|
||||
self.func_entry_ea = ida_idaapi.BADADDR
|
||||
ida_dbg.run_to(ida_ida.inf_get_start_ea())
|
||||
self.stage = ST_RUNTO
|
||||
|
||||
def dbg_process_start(self, pid, tid, ea, path, base, size):
|
||||
name = os.path.basename(path)
|
||||
ida_kernwin.msg(f'Process started: {name}.\n\tLoad address: {base:x}\n\tPID: {pid:x}\n')
|
||||
|
||||
def dbg_run_to(self, pid, tid=0, ea=0):
|
||||
if self.stage == ST_RUNTO:
|
||||
ida_kernwin.msg(f'Run to: {ea:x}\n')
|
||||
self.stage = ST_ADD_BPT
|
||||
|
||||
def dbg_suspend_process(self):
|
||||
all_good = True
|
||||
if self.stage == ST_ADD_BPT:
|
||||
ida_dbg.refresh_debugger_memory()
|
||||
|
||||
self.func_entry_ea = ida_name.get_name_ea(ida_idaapi.BADADDR, func_name)
|
||||
if self.func_entry_ea == ida_idaapi.BADADDR:
|
||||
all_good = False
|
||||
ida_kernwin.msg('Could not resolve \n')
|
||||
else:
|
||||
ida_kernwin.msg(f'{func_name} found @ {self.func_entry_ea:x}. Setting breakpoint.\n')
|
||||
if ida_dbg.add_bpt(self.func_entry_ea):
|
||||
ida_kernwin.msg('Breakpoint added\n')
|
||||
else:
|
||||
ida_kernwin.msg('Failed to add the breakpoint.\n')
|
||||
|
||||
if not all_good:
|
||||
ida_dbg.request_exit_process()
|
||||
ida_dbg.run_requests()
|
||||
else:
|
||||
ida_dbg.continue_process()
|
||||
self.stage = ST_MONITOR
|
||||
|
||||
def dbg_bpt(self, tid, bpt_ea):
|
||||
if self.stage == ST_MONITOR:
|
||||
ida_kernwin.msg(f'In dbg_bpt {bpt_ea:x}.\n')
|
||||
|
||||
if bpt_ea == self.func_entry_ea:
|
||||
ida_kernwin.msg('Trying to retreive RCX: ')
|
||||
rcx_val = ida_idd.regval_t()
|
||||
if not ida_dbg.get_reg_val('rcx', rcx_val):
|
||||
ida_kernwin.msg('Could not get rcx register.\n')
|
||||
return 0
|
||||
|
||||
fn_ea = rcx_val.ival
|
||||
ida_kernwin.msg(f'{fn_ea:x}\n')
|
||||
if not ida_bytes.is_mapped(fn_ea):
|
||||
ida_dbg.invalidate_dbgmem_config()
|
||||
|
||||
ida_dbg.invalidate_dbgmem_contents(fn_ea, 1024)
|
||||
len = ida_bytes.get_max_strlit_length(fn_ea, idc.STRTYPE_C_16)
|
||||
ida_kernwin.msg(f'String length: {len}.\n')
|
||||
if len:
|
||||
raw = ida_bytes.get_strlit_contents(fn_ea, len, idc.STRTYPE_C_16)
|
||||
ida_kernwin.msg(f' CreateFile -> {raw.decode('UTF-8')}\n')
|
||||
|
||||
ida_dbg.continue_process()
|
||||
|
||||
return 0
|
||||
|
||||
def dbg_process_exit(self, pid, tid, ea, code):
|
||||
if not self.func_entry_ea == ida_idaapi.BADADDR:
|
||||
ida_dbg.del_bpt(self.func_entry_ea)
|
||||
self.func_entry_ea = ida_idaapi.BADADDR
|
||||
self.stage = ST_NONE
|
||||
|
||||
try:
|
||||
dbg_hook_stat = "un"
|
||||
print("Filemon DBG hook: checking for hook...")
|
||||
dbg_hook
|
||||
print("Filemon DBG hook: unhooking....")
|
||||
dbg_hook_stat2 = ""
|
||||
dbg_hook.unhook()
|
||||
del dbg_hook
|
||||
except:
|
||||
print("Filemon DBG hook: not installed, installing now....")
|
||||
dbg_hook_stat = ""
|
||||
dbg_hook_stat2 = "un"
|
||||
dbg_hook = filemon_dbg_hook_t()
|
||||
dbg_hook.hook()
|
||||
@@ -0,0 +1,56 @@
|
||||
"""
|
||||
summary: This script shows an example of function clasification
|
||||
using the dirtree API.
|
||||
|
||||
description:
|
||||
In this example we calssify the functions of ntdll.dll into
|
||||
three categories (there are more but three is enough for this
|
||||
example):
|
||||
* Runtime library (Rtl).
|
||||
* System calls (Zw).
|
||||
* Kernel internal (Ki)
|
||||
For each category we create a corresponding folder in the functions
|
||||
dirtreee. Then we iterates through all the functions and use the
|
||||
folder name as filter: namely if a function name starts with 'Rtl'
|
||||
it is moved to the Rtl folder and so on.
|
||||
|
||||
level: intermediate.
|
||||
"""
|
||||
import ida_funcs
|
||||
import ida_dirtree
|
||||
import idautils
|
||||
|
||||
lst = ['Rtl', 'Zw', 'Ki']
|
||||
|
||||
def main():
|
||||
#
|
||||
# Get the functions standard dirtree.
|
||||
#
|
||||
dt = ida_dirtree.get_std_dirtree(ida_dirtree.DIRTREE_FUNCS)
|
||||
|
||||
#
|
||||
# Create the folders.
|
||||
#
|
||||
for folder in lst:
|
||||
result = dt.mkdir(folder)
|
||||
if result != ida_dirtree.DTE_OK and result != ida_dirtree.DTE_ALREADY_EXISTS:
|
||||
print(f'Not able to create folder {folder} ({result:x})')
|
||||
return
|
||||
|
||||
#
|
||||
# For all the function in the base directory, check that the function name
|
||||
# starts with the provided prefix. If it does we try to move it to the
|
||||
# corresponding folder.
|
||||
#
|
||||
for func_ea in idautils.Functions():
|
||||
name = ida_funcs.get_func_name(func_ea)
|
||||
for func_prefix in lst:
|
||||
if name and name.startswith(func_prefix):
|
||||
if dt.isfile(name):
|
||||
if dt.rename(name, f'{func_prefix}/{name}') != ida_dirtree.DTE_OK:
|
||||
print(f'Not able to move {name} inside {func_prefix} folder')
|
||||
else:
|
||||
print(f'{name} moved in {func_prefix} folder')
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -0,0 +1,76 @@
|
||||
import idautils
|
||||
import ida_kernwin
|
||||
import ida_funcs
|
||||
import ida_ua
|
||||
import ida_allins
|
||||
import ida_ida
|
||||
import ida_hexrays
|
||||
import ida_lines
|
||||
import idc
|
||||
|
||||
def build_function_list(func):
|
||||
func_list = []
|
||||
|
||||
items = ida_funcs.func_item_iterator_t(func)
|
||||
for item in items:
|
||||
is_jmp = False
|
||||
|
||||
insn = ida_ua.insn_t()
|
||||
if not ida_ua.decode_insn(insn, item):
|
||||
continue
|
||||
|
||||
if not insn.itype == ida_allins.NN_call and not insn.itype == ida_allins.NN_jmp:
|
||||
continue
|
||||
|
||||
if insn.itype == ida_allins.NN_jmp:
|
||||
is_jmp = True
|
||||
|
||||
for xref in idautils.CodeRefsFrom(item, 0):
|
||||
callee = ida_funcs.get_func(xref)
|
||||
if not callee:
|
||||
print(f'Unable to retrieve function object for {xref:x}. Skipping.')
|
||||
continue
|
||||
|
||||
if is_jmp and callee.start_ea == func.start_ea:
|
||||
continue
|
||||
|
||||
if callee not in func_list:
|
||||
func_list.append(callee)
|
||||
|
||||
return func_list
|
||||
|
||||
|
||||
def print_pseudo_code(cfunc):
|
||||
sv = cfunc.get_pseudocode()
|
||||
for sline in sv:
|
||||
print(ida_lines.tag_remove(sline.line))
|
||||
print('')
|
||||
|
||||
|
||||
def decompile_and_print(func):
|
||||
func_list = build_function_list(func)
|
||||
func_list = [func, *func_list]
|
||||
|
||||
for item in func_list:
|
||||
cfunc = ida_hexrays.decompile(item)
|
||||
if not cfunc:
|
||||
print(f'Unable to decompile function {ida_funcs.get_func_name(item.start_ea)}')
|
||||
return False
|
||||
print_pseudo_code(cfunc)
|
||||
|
||||
|
||||
def main():
|
||||
if not ida_ida.inf_get_procname() == 'metapc':
|
||||
return False
|
||||
|
||||
if not ida_hexrays.init_hexrays_plugin():
|
||||
return False
|
||||
|
||||
func = ida_funcs.get_func(idc.here())
|
||||
if not func:
|
||||
print('Please put the cursor inside a function and retry.')
|
||||
|
||||
decompile_and_print(func)
|
||||
|
||||
ida_kernwin.msg_clear()
|
||||
main()
|
||||
@@ -0,0 +1,55 @@
|
||||
"""
|
||||
summary: List all the functions called by the one in which the
|
||||
cursor is currently located.
|
||||
|
||||
description:
|
||||
If the cursor is located inside a function:
|
||||
* get the function object
|
||||
* get the function name
|
||||
* get a function item iterator
|
||||
* iterate through the items, and for each one decode it
|
||||
* if the item is a call get the address of the callee
|
||||
- get its name
|
||||
- display its name its address and address of the call.
|
||||
* if no calle is found print a statement indicating this fact.
|
||||
"""
|
||||
import idautils
|
||||
import ida_kernwin
|
||||
import ida_funcs
|
||||
import ida_ua
|
||||
import ida_allins
|
||||
import ida_ida
|
||||
import idc
|
||||
|
||||
ida_kernwin.msg_clear()
|
||||
|
||||
if ida_ida.inf_get_procname() == 'metapc':
|
||||
func = ida_funcs.get_func(idc.here())
|
||||
if func:
|
||||
has_callee = False
|
||||
func_name = ida_funcs.get_func_name(func.start_ea)
|
||||
if not func_name:
|
||||
func_name = hex(func.start_ea)
|
||||
print(f'Function {func_name} [{func.start_ea:x}] calls:')
|
||||
|
||||
items = ida_funcs.func_item_iterator_t(func)
|
||||
for item in items:
|
||||
insn = ida_ua.insn_t()
|
||||
if not ida_ua.decode_insn(insn, item):
|
||||
continue
|
||||
|
||||
if not insn.itype == ida_allins.NN_call:
|
||||
continue
|
||||
|
||||
if not has_callee:
|
||||
has_callee = True
|
||||
|
||||
for xref in idautils.CodeRefsFrom(item, 0):
|
||||
print(f'\t- {ida_funcs.get_func_name(xref)} [{xref:x}] @{item:x}')
|
||||
|
||||
if not has_callee:
|
||||
print('\t- no function.')
|
||||
else:
|
||||
print('Please place the cursor inside a function and retry.')
|
||||
else:
|
||||
print('This script will propely work for "metapc" procmod only.')
|
||||
@@ -0,0 +1,50 @@
|
||||
"""
|
||||
summary: Print argument location information.
|
||||
|
||||
description:
|
||||
In this script, we iterate through a function
|
||||
arguments and display information about their
|
||||
location and size. For this we:
|
||||
* get the function type information
|
||||
* iterate through the arguments
|
||||
* for each of them we print its location (register or stack),
|
||||
offset (if in stack) and size
|
||||
"""
|
||||
import ida_nalt
|
||||
import ida_funcs
|
||||
import ida_typeinf
|
||||
import idc
|
||||
import ida_kernwin
|
||||
|
||||
def print_argument_locations(func):
|
||||
tif = ida_typeinf.tinfo_t()
|
||||
if ida_nalt.get_tinfo(tif, func.start_ea):
|
||||
fi = ida_typeinf.func_type_data_t()
|
||||
if tif.get_func_details(fi):
|
||||
if fi.size():
|
||||
print('Argument location:')
|
||||
for item in fi:
|
||||
if item.name:
|
||||
ida_kernwin.msg(f'\t{item.name}: ')
|
||||
else:
|
||||
ida_kernwin.msg(f'\t????: ')
|
||||
location = ida_typeinf.print_argloc(item.argloc)
|
||||
if location:
|
||||
ida_kernwin.msg(f'{location}.')
|
||||
elif item.argloc.in_stack:
|
||||
ida_kernwin.msg(f'stack({item.argloc.stkoff():x}).')
|
||||
print(f'{item.type.get_size()}')
|
||||
else:
|
||||
print('No arguments')
|
||||
else:
|
||||
print('Problems retrieving function details')
|
||||
else:
|
||||
print('Problem retrieving function type info.')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
func = ida_funcs.get_func(idc.here())
|
||||
if not func:
|
||||
print('Place the cursor inside a function and retry.')
|
||||
else:
|
||||
print_argument_locations(func)
|
||||
@@ -0,0 +1,38 @@
|
||||
"""
|
||||
summary: Print the list of the functions in the currently loaded
|
||||
IDB sorted (descending) by the number of code reference to
|
||||
each of them.
|
||||
|
||||
description:
|
||||
In this script, we iterate through the list of function entry
|
||||
points and fore each of them we:
|
||||
* get its name
|
||||
* get the number of code reference made to it
|
||||
* put it in the map.
|
||||
Once done we:
|
||||
* sort the map in descending number of calls
|
||||
* print it.
|
||||
"""
|
||||
import ida_kernwin
|
||||
import ida_funcs
|
||||
import idc
|
||||
import idautils
|
||||
|
||||
ida_kernwin.msg_clear()
|
||||
|
||||
func_map = {}
|
||||
for funcea in idautils.Functions():
|
||||
func_name = ida_funcs.get_func_name(funcea)
|
||||
if not func_name:
|
||||
func_name = hex(funcea)
|
||||
else:
|
||||
func_name = idc.demangle_name(func_name, idc.get_inf_attr(idc.INF_LONG_DN))
|
||||
call_count = 0
|
||||
for xref in idautils.CodeRefsTo(funcea, 1):
|
||||
call_count += 1
|
||||
if call_count:
|
||||
func_map[func_name] = call_count
|
||||
|
||||
func_map_by_calls = sorted(func_map.items(), key=lambda x:x[1], reverse=True)
|
||||
for func, calls in func_map_by_calls:
|
||||
print(f'{func} called {calls} time(s)')
|
||||
@@ -0,0 +1,15 @@
|
||||
import ida_graph
|
||||
import ida_funcs
|
||||
import ida_gdl
|
||||
import ida_kernwin
|
||||
import idc
|
||||
|
||||
func = ida_funcs.get_func(idc.here())
|
||||
qflow = ida_gdl.qflow_chart_t("", func, 0, 0, 0)
|
||||
for n in range(qflow.size()):
|
||||
node = qflow[n]
|
||||
print(f'Start ea : {node.start_ea:x}, end ea: {node.end_ea:x}, index: {n}')
|
||||
ni = ida_graph.node_info_t()
|
||||
ni.bg_color = 0xFF00
|
||||
ida_graph.set_node_info(func.start_ea, n, ni, ida_graph.NIF_BG_COLOR)
|
||||
ida_kernwin.refresh_idaview_anyway()
|
||||
@@ -0,0 +1,74 @@
|
||||
"""
|
||||
summary: Python plugin that decompiles a function and its callees.
|
||||
|
||||
description:
|
||||
This script does the same as decompile_func_and_callee but instead
|
||||
of using the cross-references, uses a ctree visitor to build the
|
||||
list of callees.
|
||||
"""
|
||||
import ida_hexrays
|
||||
import ida_lines
|
||||
import ida_funcs
|
||||
import ida_kernwin
|
||||
|
||||
|
||||
def find_calls(cfunc):
|
||||
class finder_t(ida_hexrays.ctree_visitor_t):
|
||||
def __init__(self):
|
||||
ida_hexrays.ctree_visitor_t.__init__(self, ida_hexrays.CV_FAST | ida_hexrays.CV_INSNS)
|
||||
|
||||
self.results = []
|
||||
return
|
||||
|
||||
def visit_insn(self, inst):
|
||||
if inst.op == ida_hexrays.cit_expr and inst.cexpr.op == ida_hexrays.cot_call:
|
||||
self.results.append(inst.cexpr.x.obj_ea)
|
||||
return 0
|
||||
|
||||
finder = finder_t()
|
||||
finder.apply_to(cfunc.body, None)
|
||||
return finder.results
|
||||
|
||||
|
||||
def print_pseudo_code(cfunc):
|
||||
sv = cfunc.get_pseudocode();
|
||||
for sline in sv:
|
||||
print(ida_lines.tag_remove(sline.line))
|
||||
|
||||
|
||||
def main():
|
||||
if not ida_hexrays.init_hexrays_plugin():
|
||||
return False
|
||||
|
||||
print("Hex-rays version %s has been detected" % ida_hexrays.get_hexrays_version())
|
||||
|
||||
f = ida_funcs.get_func(ida_kernwin.get_screen_ea())
|
||||
if f is None:
|
||||
print("Please position the cursor within a function")
|
||||
return True
|
||||
|
||||
cfunc = ida_hexrays.decompile(f);
|
||||
if cfunc is None:
|
||||
print("Failed to decompile!")
|
||||
return True
|
||||
|
||||
print_pseudo_code(cfunc)
|
||||
|
||||
lst = find_calls(cfunc)
|
||||
lst = list(set(lst))
|
||||
already = []
|
||||
for ea in lst:
|
||||
f = ida_funcs.get_func(ea)
|
||||
if f is None:
|
||||
continue
|
||||
|
||||
cfunc = ida_hexrays.decompile(f);
|
||||
if cfunc is None:
|
||||
print("Failed to decompile!")
|
||||
return True
|
||||
print_pseudo_code(cfunc)
|
||||
|
||||
return True
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -0,0 +1,65 @@
|
||||
"""
|
||||
summary: log various frame events.
|
||||
|
||||
description:
|
||||
hooks to be notified about frame IDP events, and
|
||||
dump their information to the "Output" window.
|
||||
"""
|
||||
import inspect
|
||||
import ida_idp
|
||||
import ida_ua
|
||||
|
||||
class frame_logger_hooks_t(ida_idp.IDB_Hooks):
|
||||
def __init__(self):
|
||||
ida_idp.IDB_Hooks.__init__(self)
|
||||
self.inhibit_log = 0
|
||||
|
||||
def _format_value(self, v):
|
||||
return str(v)
|
||||
|
||||
def _log(self, msg=None):
|
||||
if self.inhibit_log <= 0:
|
||||
if msg:
|
||||
print(f'>>> frame_logger_hooks_f: {msg}')
|
||||
else:
|
||||
stack = inspect.stack()
|
||||
frame, _, _, _, _, _ = stack[1]
|
||||
args, _, _, values = inspect.getargvalues(frame)
|
||||
method_name = inspect.getframeinfo(frame)[2]
|
||||
argstrs = []
|
||||
for arg in args[1:]:
|
||||
argstrs.append("%s=%s" % (arg, self._format_value(values[arg])))
|
||||
print(f'>>> frame_logger_hooks_t.{method_name}: {", ".join(args)}')
|
||||
return 0
|
||||
|
||||
def frame_udm_created(self, func_ea, udm):
|
||||
return self._log()
|
||||
|
||||
def frame_udm_deleted(self, func_ea, udm_tid, udm):
|
||||
return self._log()
|
||||
|
||||
def frame_udm_renamed(self, func_ea, udm, oldname):
|
||||
return self._log()
|
||||
|
||||
def frame_udm_changed(self, func_ea, udm_tid, udmold, udmnew):
|
||||
return self._log()
|
||||
|
||||
|
||||
|
||||
# Remove an existing hook on second run
|
||||
try:
|
||||
frame_idp_hook_stat = "un"
|
||||
print("Frame IDP hook: checking for hook...")
|
||||
framehook
|
||||
print("Frame IDP hook: unhooking....")
|
||||
frame_idp_hook_stat2 = ""
|
||||
framehook.unhook()
|
||||
del framehook
|
||||
except:
|
||||
print("Frame IDP hook: not installed, installing now....")
|
||||
frame_idp_hook_stat = ""
|
||||
frame_idp_hook_stat2 = "un"
|
||||
framehook = frame_logger_hooks_t()
|
||||
framehook.hook()
|
||||
|
||||
print(f'Frame IDB hook {frame_idp_hook_stat}installed. Run the script again to {frame_idp_hook_stat2}install')
|
||||
@@ -0,0 +1,68 @@
|
||||
"""
|
||||
summary: log various local type events.
|
||||
|
||||
description:
|
||||
hooks to be notified about local type IDP events,
|
||||
and dump their information to the "Output" window
|
||||
"""
|
||||
import inspect
|
||||
import ida_idp
|
||||
import ida_ua
|
||||
|
||||
class lt_logger_hooks_t(ida_idp.IDB_Hooks):
|
||||
def __init__(self):
|
||||
ida_idp.IDB_Hooks.__init__(self)
|
||||
self.inhibit_log = 0
|
||||
|
||||
def _format_value(self, v):
|
||||
return str(v)
|
||||
|
||||
def _log(self, msg=None):
|
||||
if self.inhibit_log <= 0:
|
||||
if msg:
|
||||
print(f'>>> lt_logger_hooks_f: {msg}')
|
||||
else:
|
||||
stack = inspect.stack()
|
||||
frame, _, _, _, _, _ = stack[1]
|
||||
args, _, _, values = inspect.getargvalues(frame)
|
||||
method_name = inspect.getframeinfo(frame)[2]
|
||||
argstrs = []
|
||||
for arg in args[1:]:
|
||||
argstrs.append("%s=%s" % (arg, self._format_value(values[arg])))
|
||||
print(f'>>> lt_logger_hooks_t.{method_name}: {", ".join(args)}')
|
||||
return 0
|
||||
|
||||
def lt_udm_created(self, udtname, udm):
|
||||
msg = f'UDM {udm.name} has been created in UDT {udtname}'
|
||||
return self._log(msg)
|
||||
|
||||
def lt_udm_deleted(self, udtname, udm_tid):
|
||||
msg = f'UDM tid {udm_tid:x} has been deleted from {udtname}'
|
||||
return self._log(msg)
|
||||
|
||||
def lt_udm_renamed(self, udtname, udm, oldname):
|
||||
msg = f'UDM {oldname} from UDT {udtname} has been renamed to {udm.name}'
|
||||
return self._log(msg)
|
||||
|
||||
def lt_udm_changed(self, udtname, udm_tid, udmold, udmnew):
|
||||
return self._log()
|
||||
|
||||
|
||||
|
||||
# Remove an existing hook on second run
|
||||
try:
|
||||
idp_hook_stat = "un"
|
||||
print("Local type IDB hook: checking for hook...")
|
||||
lthook
|
||||
print("Local type IDB hook: unhooking....")
|
||||
idp_hook_stat2 = ""
|
||||
lthook.unhook()
|
||||
del lthook
|
||||
except:
|
||||
print("local type IDB hook: not installed, installing now....")
|
||||
idp_hook_stat = ""
|
||||
idp_hook_stat2 = "un"
|
||||
lthook = lt_logger_hooks_t()
|
||||
lthook.hook()
|
||||
|
||||
print(f'Local type IDB hook {idp_hook_stat}installed. Run the script again to {idp_hook_stat2}install')
|
||||
@@ -0,0 +1,677 @@
|
||||
"""
|
||||
summary: being notified, and logging some IDP events
|
||||
|
||||
description:
|
||||
hooks to be notified about certain IDP events, and
|
||||
dump their information to the "Output" window
|
||||
See enum event_t in idp.hpp for additional.
|
||||
"""
|
||||
import inspect
|
||||
import ida_idp
|
||||
import ida_ua
|
||||
|
||||
class idp_logger_hooks_t(ida_idp.IDP_Hooks):
|
||||
def __init__(self):
|
||||
ida_idp.IDP_Hooks.__init__(self)
|
||||
self.inhibit_log = 0
|
||||
|
||||
def _format_value(self, v):
|
||||
return str(v)
|
||||
|
||||
def _log(self, msg=None):
|
||||
if self.inhibit_log <= 0:
|
||||
if msg:
|
||||
print(f'>>> idp_logger_hooks_f: {msg}')
|
||||
else:
|
||||
stack = inspect.stack()
|
||||
frame, _, _, _, _, _ = stack[1]
|
||||
args, _, _, values = inspect.getargvalues(frame)
|
||||
method_name = inspect.getframeinfo(frame)[2]
|
||||
argstrs = []
|
||||
for arg in args[1:]:
|
||||
argstrs.append("%s=%s" % (arg, self._format_value(values[arg])))
|
||||
print(f'>>> idp_logger_hooks_t.{method_name}: {", ".join(args)}')
|
||||
return 0
|
||||
|
||||
def ev_init(self, idp_modname):
|
||||
"""
|
||||
The IDP module is just loaded.
|
||||
idp_modname - processor module name
|
||||
Returns: <0 on failure
|
||||
"""
|
||||
return self._log(f'idp_logger_hooks_t.ev_init(self, {idp_modname})')
|
||||
|
||||
def ev_term(self):
|
||||
"""
|
||||
The IDP module is being unloaded
|
||||
"""
|
||||
return self._log()
|
||||
|
||||
def ev_newprc(self, nproc, keep_cfg):
|
||||
"""
|
||||
Before changing proccesor type
|
||||
nproc - processor number in the array of processor names
|
||||
Returns: >=0-ok,<0-prohibit
|
||||
"""
|
||||
return self._log()
|
||||
|
||||
def ev_newasm(self, asmnum):
|
||||
"""
|
||||
Before setting a new assembler.
|
||||
"""
|
||||
return self._log()
|
||||
|
||||
def ev_newfile(self, fname):
|
||||
"""
|
||||
A new file has been loaded.
|
||||
"""
|
||||
return self._log()
|
||||
|
||||
def ev_oldfile(self, filename):
|
||||
"""
|
||||
An old file has been loaded.
|
||||
"""
|
||||
return self._log()
|
||||
|
||||
def ev_newbinary(self, filename, fileoff, basepara, binoff, nbytes):
|
||||
"""
|
||||
Before loading a binary file
|
||||
"""
|
||||
return self._log()
|
||||
|
||||
def ev_endbinary(self, ok):
|
||||
"""
|
||||
After loading a binary file
|
||||
Returns: >=0-ok
|
||||
"""
|
||||
return self._log()
|
||||
|
||||
def ev_set_idp_options(self, keyword, value_type, value, idb_loaded):
|
||||
"""
|
||||
Set IDP-specific option
|
||||
Returns: 1-ok, 0-not implemented, -1-error
|
||||
"""
|
||||
#msg = f'KEY: {keyword}, TYPE: {value_type}, value: {value}, loaded: {idb_loaded}'
|
||||
return self._log()
|
||||
|
||||
def ev_set_proc_options(self, options, confidence):
|
||||
"""
|
||||
Called if the user specified an option string in the command line:
|
||||
Returns: <0-bad option string
|
||||
"""
|
||||
return self._log()
|
||||
|
||||
def ev_ana_insn(self, insn):
|
||||
"""
|
||||
Decodes an instruction into insn
|
||||
Returns: insn.size (=the size of the decoded instruction) or zero
|
||||
"""
|
||||
self._log()
|
||||
return insn.size
|
||||
|
||||
def ev_emu_insn(self, insn):
|
||||
"""
|
||||
Emulate instruction, create cross-references, plan to analyze
|
||||
subsequent instructions, modify flags etc. Upon entrance to this function
|
||||
all information about the instruction is in 'insn' structure.
|
||||
Returns: -1, the kernel will delete the instruction.
|
||||
"""
|
||||
return self._log()
|
||||
|
||||
def ev_out_header(self, ctx):
|
||||
"""
|
||||
Function to produce start of disassembled text
|
||||
"""
|
||||
self._log()
|
||||
|
||||
def ev_out_footer(self, ctx):
|
||||
"""
|
||||
Function to produce end of disassembled text
|
||||
"""
|
||||
self._log()
|
||||
|
||||
def ev_out_segstart(self, ctx, segment):
|
||||
"""
|
||||
Function to produce start of segment
|
||||
Returns: 1-ok, 0-not implemented
|
||||
"""
|
||||
return self._log()
|
||||
|
||||
def ev_out_insn(self, ctx):
|
||||
"""
|
||||
Generate text representation of an instruction in 'ctx.insn' structure.
|
||||
This function shouldn't change the database, flags or anything else.
|
||||
All these actions should be performed only by u_emu() function.
|
||||
Returns: nothing
|
||||
"""
|
||||
self._log()
|
||||
|
||||
def ev_out_segstart(self, ctx, segment):
|
||||
"""
|
||||
Function to produce start of segment
|
||||
Returns: 1-ok, 0-not implemented
|
||||
"""
|
||||
return self._log()
|
||||
|
||||
def ev_out_segend(self, ctx, segment):
|
||||
"""
|
||||
Function to produce end of segment
|
||||
Returns: 1-ok, 0-not implemented
|
||||
"""
|
||||
return self._log()
|
||||
|
||||
def ev_out_assumes(self, ctx):
|
||||
"""
|
||||
Function to produce assume directives
|
||||
Returns: 1-ok, 0-not implemented
|
||||
"""
|
||||
return self._log()
|
||||
|
||||
def ev_out_mnem(self, ctx):
|
||||
"""
|
||||
Generate text representation of an instruction in 'ctx.insn'
|
||||
Returns: 1-if appended the mnemonics, 0-not implemented.
|
||||
"""
|
||||
return self._log()
|
||||
|
||||
def ev_out_operand(self, ctx, op):
|
||||
"""
|
||||
Generate text representation of an instructon operand.
|
||||
This function shouldn't change the database, flags or anything else.
|
||||
All these actions should be performed only by u_emu() function.
|
||||
Returns: 1-ok, -1-operand is hidden
|
||||
"""
|
||||
return self._log()
|
||||
|
||||
def ev_out_data(self, ctx, analyze_only):
|
||||
"""
|
||||
Generate text represenation of data items
|
||||
This function MAY change the database and create cross-references, etc.
|
||||
Returns: 1-ok, 0-not implemented
|
||||
"""
|
||||
return self._log()
|
||||
|
||||
def ev_out_label(self, ctx, label):
|
||||
"""
|
||||
The kernel is going to generate an instruction label line
|
||||
or a function header.
|
||||
Returns: <0-the kernel should not generate the label, 0-not implemented/continue
|
||||
"""
|
||||
return self._log()
|
||||
|
||||
def ev_out_special_item(self, ctx, segtype):
|
||||
"""
|
||||
Generate text representation of an item in a special segment
|
||||
i.e. absolute symbols, externs, communal definitions etc.
|
||||
Returns: 1-ok, 0-not implemented, -1-overflow
|
||||
"""
|
||||
return self._log()
|
||||
|
||||
def ev_gen_stkvar_def(self, ctx, mptr, v):
|
||||
"""
|
||||
Generate stack variable definition line.
|
||||
Default line is varname = type ptr value,
|
||||
where 'type' is one of byte,word,dword,qword,tbyte.
|
||||
Returns: 1-ok, 0-not implemented.
|
||||
"""
|
||||
return self._log()
|
||||
|
||||
def ev_gen_regvar_def(self, ctx, v):
|
||||
"""
|
||||
Generate register variable definition line.
|
||||
Returns: >0-ok, 0-not implemented.
|
||||
"""
|
||||
return self._log()
|
||||
|
||||
def ev_gen_src_file_lnnum(self, ctx, filename, lnnum):
|
||||
"""
|
||||
Callback: generate analog of#line "file.c" 123
|
||||
directive.
|
||||
Returns: 1-ok, 0-not implemented
|
||||
"""
|
||||
return self._log()
|
||||
|
||||
def ev_creating_segm(self, s):
|
||||
"""
|
||||
A new segment is about to be created.
|
||||
Returns 1-ok, <0-should not be created
|
||||
"""
|
||||
return self._log()
|
||||
|
||||
def ev_moving_segm(self, segment, to, flags):
|
||||
"""
|
||||
May the kernel move the segment?
|
||||
returns: 0-yes, <0-the kernel should stop
|
||||
"""
|
||||
return self._log()
|
||||
|
||||
def ev_coagulate(self, start_ea):
|
||||
"""
|
||||
Try to define some unexplored bytes
|
||||
This notification will be called if the
|
||||
kernel tried all possibilities and could
|
||||
not find anything more useful than to
|
||||
convert to array of bytes.
|
||||
The module can help the kernel and convert
|
||||
the bytes into something more useful.
|
||||
Returns: number of converted bytes
|
||||
"""
|
||||
return self._log()
|
||||
|
||||
def ev_undefine(self, ea):
|
||||
"""
|
||||
An item in the database (insn or data) is being deleted.
|
||||
Returns: >=0-ok, <0-the kernel should stop
|
||||
"""
|
||||
return self._log()
|
||||
|
||||
def ev_treat_hindering_item(self, hindering_item_ea, new_item_flags, new_item_ea, new_item_length):
|
||||
"""
|
||||
An item hinders creation of another item
|
||||
Returns: 0-no reaction, <0-the kernel may delete the hindering item
|
||||
"""
|
||||
return self._log()
|
||||
|
||||
def ev_rename(self, ea, new_name):
|
||||
"""
|
||||
The kernel is going to rename a byte
|
||||
Returns: <0-then the kernel should not rename it
|
||||
"""
|
||||
return self._log()
|
||||
|
||||
def ev_is_far_jump(self, icode):
|
||||
"""
|
||||
Is indirect far jump or call instruction?
|
||||
meaningful only if the processor has 'near' and 'far' reference types.
|
||||
Returns: 0-not implemented, 1-yes, -1-no
|
||||
"""
|
||||
return self._log()
|
||||
|
||||
def ev_is_sane_insn(self, insn, no_crefs):
|
||||
"""
|
||||
Is the instruction sane for the current file type?
|
||||
Returns: >=0-ok, <0-no
|
||||
"""
|
||||
return self._log()
|
||||
|
||||
def ev_is_cond_insn(self, insn):
|
||||
"""
|
||||
Is conditional instruction?
|
||||
Returns: 1-yes, -1-no, 0-not implemented.
|
||||
"""
|
||||
return self._log()
|
||||
|
||||
def ev_is_call_insn(self, insn):
|
||||
"""
|
||||
Is the instruction a "call"?
|
||||
Returns: 0-unknown, <0-no, 1-yes
|
||||
"""
|
||||
return self._log()
|
||||
|
||||
def ev_is_ret_insn(self, insn, flags):
|
||||
"""
|
||||
Is the instruction a "return"?
|
||||
Returns: 0-unknown, <0-no, 1-yes
|
||||
"""
|
||||
return self._log()
|
||||
|
||||
def ev_may_be_func(self, insn, state):
|
||||
"""
|
||||
Can a function start here?
|
||||
Returns: probability 0..100
|
||||
"""
|
||||
return self._log()
|
||||
|
||||
def ev_is_basic_block_end(self, insn, call_insn_stops_block):
|
||||
"""
|
||||
Is the current instruction end of a basic block?
|
||||
Returns: 0-unknown, -1-no, 1-yes
|
||||
"""
|
||||
return self._log()
|
||||
|
||||
def ev_is_indirect_jump(self, insn):
|
||||
"""
|
||||
Callback: determine if instruction is an indrect jump
|
||||
If CF_JUMP bit cannot describe all jump types
|
||||
jumps, please define this callback.
|
||||
Returns: 0-use CF_JUMP, 1-no, 2-yes
|
||||
"""
|
||||
return self._log()
|
||||
|
||||
def ev_is_switch(self, swi, insn):
|
||||
"""
|
||||
Find 'switch' idiom or override processor module's
|
||||
decision.
|
||||
Returns: 1-switch found, -1-no switch found, 0-not implmented
|
||||
"""
|
||||
return self._log()
|
||||
|
||||
def ev_calc_switch_cases(self, casevec, targets, insn_ea, si):
|
||||
"""
|
||||
Calculate case values and targets for a custom jump table.
|
||||
Returns: 1-ok, <=0-failed
|
||||
"""
|
||||
return self._log()
|
||||
|
||||
def ev_create_switch_xrefs(self, jumpea, swi):
|
||||
"""
|
||||
Create xrefs for a custom jump table
|
||||
Must return 1
|
||||
"""
|
||||
self._log()
|
||||
return 1
|
||||
|
||||
def ev_is_align_insn(self, ea):
|
||||
"""
|
||||
Is the instruction created only for alignment purposes?
|
||||
Returns: number of bytes in the instruction
|
||||
"""
|
||||
return self._log()
|
||||
|
||||
def ev_is_alloca_probe(self, ea):
|
||||
"""
|
||||
Does the function at 'ea' behave as __alloca_probe?
|
||||
Returns: 1-yes, 0-no
|
||||
"""
|
||||
return self._log()
|
||||
|
||||
def ev_delay_slot_insn(self, ea, bexec, fexec):
|
||||
"""
|
||||
Get delay slot instruction.
|
||||
Returns 1-yes, <=O-ordianry insn.
|
||||
"""
|
||||
return self._log()
|
||||
|
||||
def ev_is_sp_based(self, mode, insn, op):
|
||||
"""
|
||||
Check whether the operand is relative to stack pointer or frame pointer.
|
||||
This function is used to determine how to output a stack variable
|
||||
This function may be absent. If it is absent, then all operands
|
||||
are sp based by default.
|
||||
Define this function only if some stack references use frame pointer
|
||||
instead of stack pointer.
|
||||
Returns: 0-not implemented, 1-ok
|
||||
"""
|
||||
return self._log()
|
||||
|
||||
def ev_can_have_type(self, op):
|
||||
"""
|
||||
Can the operand have a type as offset, segment, decimal, etc?
|
||||
(for example, a register AX can't have a type, meaning that the user can't
|
||||
change its representation. see bytes.hpp for information about types and flags)
|
||||
Returns: 0-unknown, <0-no, 1-yes
|
||||
"""
|
||||
return self._log()
|
||||
|
||||
def ev_cmp_operands(self, op1, op2):
|
||||
"""
|
||||
Compare instruction operands.
|
||||
Returns 1-equal, -1-not equal, 0-not implemented
|
||||
"""
|
||||
return self._log()
|
||||
|
||||
def ev_adjust_refinfo(self, ri, ea, n, fd):
|
||||
"""
|
||||
Called from apply_fixup before converting operand to reference.
|
||||
Can be used for changing the reference info.
|
||||
Returns: <0-do not create an offset, 0-not implemented
|
||||
"""
|
||||
return self._log()
|
||||
|
||||
def ev_get_operand_string(self, buf, insn, opnum):
|
||||
"""
|
||||
Request text string for operand.
|
||||
Returns: 0-no string (or empty), >0-original string length (without final 0)
|
||||
"""
|
||||
return self._log()
|
||||
|
||||
def ev_get_reg_name(self, buf, reg, width, reghi):
|
||||
"""
|
||||
Generate text representation of a register.
|
||||
Most processor modules do not need to implement this callback.
|
||||
Returns: -1-error, strlen(buf)-success
|
||||
"""
|
||||
return self._log()
|
||||
|
||||
def ev_str2reg(self, regname):
|
||||
"""
|
||||
Convert a register name to a register number
|
||||
Returns: 0-not implemented, register number + 1
|
||||
"""
|
||||
return self._log()
|
||||
|
||||
def ev_get_autocmt(self, insn):
|
||||
"""
|
||||
Get instruction comment. 'insn' describes the instruction in question
|
||||
@return: 1-new comment has been generated, 0-not been handled.
|
||||
"""
|
||||
return self._log()
|
||||
|
||||
def ev_get_bg_color(self, color, ea):
|
||||
"""
|
||||
Get item background color.
|
||||
Plugins can hook this callback to color disassembly lines dynamically.
|
||||
Returns: 0-not implemented, 1-color set
|
||||
"""
|
||||
return self._log()
|
||||
|
||||
def ev_is_jump_func(self, pfn, jump_target, func_pointer):
|
||||
"""
|
||||
Is the function a trivial "jump" function?
|
||||
Returns: <0-no, 0-don't know, 1-yes
|
||||
"""
|
||||
return self._log()
|
||||
|
||||
def ev_func_bounds(self, possible_return_code, pfn, max_func_end_ea):
|
||||
"""
|
||||
Find_func_bounds() finished its work.
|
||||
The module may fine tune the function bounds.
|
||||
Returns: None
|
||||
"""
|
||||
return self._log()
|
||||
|
||||
def ev_verify_sp(self, pfn):
|
||||
"""
|
||||
All function instructions have been analyzed.
|
||||
Now the processor module can analyze the stack pointer
|
||||
for the whole function
|
||||
Returns: 0-ok, <0-bad stack pointer
|
||||
"""
|
||||
return self._log()
|
||||
|
||||
def ev_verify_noreturn(self, pfn):
|
||||
"""
|
||||
The kernel wants to set 'noreturn' flags for a function
|
||||
Returns: 0-ok, <0-do not set 'noreturn' flag
|
||||
"""
|
||||
return self._log()
|
||||
|
||||
def ev_create_func_frame(self, pfn):
|
||||
"""
|
||||
Create a function frame for a newly created function.
|
||||
Set up frame size, its attributes etc.
|
||||
Returns: 1-ok, 0-not implemented
|
||||
"""
|
||||
return self._log()
|
||||
|
||||
def ev_get_frame_retsize(self, frsize, pfn):
|
||||
"""
|
||||
Get size of function return address in bytes
|
||||
If this function is absent, the kernel will assume
|
||||
8 bytes for 64-bit function,4 bytes for 32-bit
|
||||
function, c2 bytes otherwise.
|
||||
Returns 1-ok, 0-not implemented
|
||||
"""
|
||||
return self._log()
|
||||
|
||||
def ev_get_stkvar_scale_factor(self):
|
||||
"""
|
||||
Should stack variable references be multiplied by
|
||||
a coefficient before being used in the stack frame?
|
||||
Currently used by TMS320C55 because the references into
|
||||
the stack should be multiplied by 2.
|
||||
Returns: 0-not implemented, >0-scaling factor
|
||||
"""
|
||||
return self._log()
|
||||
|
||||
def ev_demangle_name(self, out, res , demreq):
|
||||
"""
|
||||
Demangle a C++ (or another language) name into a user-readable string.
|
||||
This event is called by ::demangle_name().
|
||||
Returns: 0-not implemented, 1-success
|
||||
"""
|
||||
return self._log()
|
||||
|
||||
def ev_add_cref(self, frm, to, type):
|
||||
"""
|
||||
A code reference is being created.
|
||||
Returns: 0-not implemented, <0-cancel cref creation
|
||||
"""
|
||||
return self._log()
|
||||
|
||||
def ev_add_dref(self, frm, to, type):
|
||||
"""
|
||||
A data reference is being created.
|
||||
Returns: 0-not implemented, <0-cancel dref creation
|
||||
"""
|
||||
return self._log()
|
||||
|
||||
def ev_del_cref(self, frm, to, expand):
|
||||
"""
|
||||
A code reference is being deleted.
|
||||
Returns: 0-not implemented, <0-cancel cref deletion
|
||||
"""
|
||||
return self._log()
|
||||
|
||||
def ev_del_dref(self, frm, to):
|
||||
"""
|
||||
A data reference is being deleted.
|
||||
Retuns: 0-not implemented, <0-cancel dref deletion
|
||||
"""
|
||||
return self._log()
|
||||
|
||||
def ev_coagulate_dref(self, from_ea, to_ea, may_define, code_ea):
|
||||
"""
|
||||
Data reference is being analyzed.
|
||||
plugin may correct code_ea (e.g. for thumb mode refs, we clear the last bit)
|
||||
Returns: >0-new code_ea, -1-cancel dref analysis
|
||||
"""
|
||||
return self._log()
|
||||
|
||||
def ev_may_show_sreg(self, current_ea):
|
||||
"""
|
||||
The kernel wants to display the segment registers
|
||||
in the messages window.
|
||||
Returns: 0-not implemented, <0-kernel should not show.
|
||||
"""
|
||||
return self._log()
|
||||
|
||||
def ev_loader_elf_machine(self, li, machine_type, p_procname, p_pd, loader, reader):
|
||||
"""
|
||||
ELF loader machine type checkpoint.
|
||||
A plugin check of the 'machine_type'. If it is the desired one,
|
||||
the the plugin fills 'p_procname' with the processor name.
|
||||
Returns: e_machine value
|
||||
"""
|
||||
pass
|
||||
|
||||
def ev_auto_queue_empty(self, atype):
|
||||
"""
|
||||
One analysis queue is empty.
|
||||
Returns: an int (?)
|
||||
"""
|
||||
return self._log()
|
||||
|
||||
def ev_validate_flirt_func(self, start_ea, func_name):
|
||||
"""
|
||||
FLIRT has recognized a library function.
|
||||
This callback can be used by a plugin or proc module
|
||||
to intercept it and validate such a function.
|
||||
Returns: -1-do not create, 0-validated
|
||||
"""
|
||||
return self._log()
|
||||
|
||||
def ev_adjust_libfunc_ea(self, sig, libfun, ea):
|
||||
"""
|
||||
Called when a signature module has been matched against
|
||||
bytes in the database. This is used to compute the
|
||||
offset at which a particular module's libfunc should
|
||||
be applied.
|
||||
Returns: 1-ea has been modified, <=0 not modified
|
||||
"""
|
||||
return self._log()
|
||||
|
||||
def ev_assemble(self, ea, cs, ip, use32, line):
|
||||
"""
|
||||
Assemble an instruction
|
||||
(make sure that PR_ASSEMBLE flag is set in the processor flags)
|
||||
(display a warning if an error occurs)
|
||||
Returns opcode string-ok, None-failed
|
||||
"""
|
||||
return self._log()
|
||||
|
||||
def ev_extract_address(self, out_ea, screen_ea, string, position):
|
||||
"""
|
||||
Extract address from a string.
|
||||
Returns: 1-ok, 0-use standard algorithm, -1-error
|
||||
"""
|
||||
return self._log()
|
||||
|
||||
def ev_realcvt(self, m,e, swt):
|
||||
"""
|
||||
Floating point -> IEEE conversion
|
||||
Returns: 1-ok, 0-not implemented, REAL_ERROR_-error
|
||||
"""
|
||||
return self._log()
|
||||
|
||||
def ev_gen_asm_or_lst(self, starting, fp, is_asm, flags, outline):
|
||||
"""
|
||||
Callback generating asm orlst file.
|
||||
The kernel calls this callback twice, at the beginning
|
||||
and at the end of listing generation. The processor
|
||||
module can intercept this event and adjust its output.
|
||||
Returns: None
|
||||
"""
|
||||
return self._log()
|
||||
|
||||
def ev_gen_map_file(self, nlines, fp):
|
||||
"""
|
||||
Generate a map file. If not implemented
|
||||
the kernel itself will create the map file.
|
||||
Returns: 1-ok, 0-not implemented, -1-write error
|
||||
"""
|
||||
return self._log()
|
||||
|
||||
def ev_create_flat_group(self, image_base, bitness, dataseg_sel):
|
||||
"""
|
||||
Create special segment representing the flat group.
|
||||
Returns: return value ignored.
|
||||
"""
|
||||
return self._log()
|
||||
|
||||
def ev_analyze_prolog(self, ea):
|
||||
"""
|
||||
Analyzes function prolog, epilog, and updates
|
||||
purge, and function attributes
|
||||
Returns: 1-ok, 0-not implemented.
|
||||
"""
|
||||
return self._log()
|
||||
|
||||
|
||||
# Remove an existing hook on second run
|
||||
try:
|
||||
idp_hook_stat = "un"
|
||||
print("IDP hook: checking for hook...")
|
||||
idphook
|
||||
print("IDP hook: unhooking....")
|
||||
idp_hook_stat2 = ""
|
||||
idphook.unhook()
|
||||
del idphook
|
||||
except:
|
||||
print("IDP hook: not installed, installing now....")
|
||||
idp_hook_stat = ""
|
||||
idp_hook_stat2 = "un"
|
||||
idphook = idp_logger_hooks_t()
|
||||
idphook.hook()
|
||||
|
||||
print(f'IDP hook {idp_hook_stat}installed. Run the script again to {idp_hook_stat2}install')
|
||||
@@ -0,0 +1,84 @@
|
||||
"""
|
||||
summary: Print basic information about the currently loaded IDB.
|
||||
|
||||
description:
|
||||
In this script we display some basic information about the
|
||||
current IDB:
|
||||
* the compiler name and the size of some datatypes
|
||||
* Other general IDB information including: application bitness,
|
||||
file type, various address ranges, main address and start
|
||||
addresses if exist.
|
||||
For this we use some of the inf_get_xxx functions from the
|
||||
ida_ida module.
|
||||
"""
|
||||
import ida_ida
|
||||
import ida_kernwin
|
||||
import ida_typeinf
|
||||
import ida_idaapi
|
||||
|
||||
ft_dict = {
|
||||
ida_ida.f_EXE_old: 'MS DOS EXE File',
|
||||
ida_ida.f_COM_old: 'MS DOS COM File',
|
||||
ida_ida.f_BIN: 'Binary File',
|
||||
ida_ida.f_DRV: 'MS DOS Driver',
|
||||
ida_ida.f_WIN: 'New Executable (NE)',
|
||||
ida_ida.f_HEX: 'Intel Hex Object File',
|
||||
ida_ida.f_MEX: 'MOS Technology Hex Object File',
|
||||
ida_ida.f_LX: 'Linear Executable (LX)',
|
||||
ida_ida.f_LE: 'Linear Executable (LE)',
|
||||
ida_ida.f_NLM: 'Netware Loadable Module (NLM)',
|
||||
ida_ida.f_COFF: 'Common Object File Format (COFF)',
|
||||
ida_ida.f_PE: 'Portable Executable (PE)',
|
||||
ida_ida.f_OMF: 'Object Module Format',
|
||||
ida_ida.f_SREC: 'Motorola SREC (S-record)',
|
||||
ida_ida.f_ZIP: 'ZIP file (this file is never loaded to IDA database)',
|
||||
ida_ida.f_OMFLIB: 'Library of OMF Modules',
|
||||
ida_ida.f_AR: 'ar library',
|
||||
ida_ida.f_LOADER: 'file is loaded using LOADER DLL',
|
||||
ida_ida.f_ELF: 'Executable and Linkable Format (ELF)',
|
||||
ida_ida.f_W32RUN: 'Watcom DOS32 Extender (W32RUN)',
|
||||
ida_ida.f_AOUT: 'Linux a.out (AOUT)',
|
||||
ida_ida.f_PRC: 'PalmPilot program file',
|
||||
ida_ida.f_EXE: 'MS DOS EXE File',
|
||||
ida_ida.f_COM: 'MS DOS COM File',
|
||||
ida_ida.f_AIXAR: 'AIX ar library',
|
||||
ida_ida.f_MACHO: 'Mac OS X Mach-O',
|
||||
ida_ida.f_PSXOBJ: 'Sony Playstation PSX object file',
|
||||
ida_ida.f_MD1IMG: 'Mediatek Firmware Image'
|
||||
}
|
||||
|
||||
def main():
|
||||
print('\nCompiler info:')
|
||||
cc = ida_ida.compiler_info_t()
|
||||
ida_ida.inf_get_cc(cc)
|
||||
print(f'\tCompilateur: {ida_typeinf.get_compiler_name(cc.id)}')
|
||||
print(f'\t\tByte size: {ida_ida.inf_get_cc_size_b()}')
|
||||
print(f'\t\tShort size: {ida_ida.inf_get_cc_size_s()}')
|
||||
print(f'\t\tEnum size: {ida_ida.inf_get_cc_size_e()}')
|
||||
print(f'\t\tInteger size: {ida_ida.inf_get_cc_size_i()}')
|
||||
print(f'\t\tLong size: {ida_ida.inf_get_cc_size_l()}')
|
||||
print(f'\t\tLong double size: {ida_ida.inf_get_cc_size_ldbl()}')
|
||||
print(f'\t\tLong long size: {ida_ida.inf_get_cc_size_ll()}')
|
||||
|
||||
print('\nGeneral IDB information:')
|
||||
print(f'\tApplication bitness: {ida_ida.inf_get_app_bitness()}-bit')
|
||||
if ida_ida.inf_is_kernel_mode():
|
||||
land = 'Kernel'
|
||||
else:
|
||||
land = 'User'
|
||||
print(f'\tExecution mode: {land}')
|
||||
print(f'\tFile type: {ft_dict[ida_ida.inf_get_filetype()]}')
|
||||
main_ea = ida_ida.inf_get_main()
|
||||
if not main_ea == ida_idaapi.BADADDR:
|
||||
print(f'\tMain entry point: {main_ea:x}')
|
||||
start_ea = ida_ida.inf_get_start_ea()
|
||||
if not start_ea == ida_idaapi.BADADDR:
|
||||
print(f'Start entry: {start_ea:x}')
|
||||
print(f'\tMinimum effective address: {ida_ida.inf_get_min_ea():x}')
|
||||
print(f'\tMaximum effective address: {ida_ida.inf_get_max_ea():x}')
|
||||
print(f'\tPrivate range start: {ida_ida.inf_get_privrange_start_ea():x}')
|
||||
print(f'\tPrivate range end: {ida_ida.inf_get_privrange_end_ea():x}')
|
||||
|
||||
|
||||
ida_kernwin.msg_clear()
|
||||
main()
|
||||
@@ -0,0 +1,37 @@
|
||||
"""
|
||||
summary: Python plugin that print basic IDB information.
|
||||
|
||||
description:
|
||||
Demonstrates how to turn an IDA python script into
|
||||
an IDA Python plugin.
|
||||
"""
|
||||
import ida_idaapi
|
||||
import ida_kernwin
|
||||
import print_basic_info
|
||||
|
||||
class pbi_plugmod_t(ida_idaapi.plugmod_t):
|
||||
def __del__(self):
|
||||
ida_kernwin.msg("PBI >> unloaded pbi_plugmod\n")
|
||||
|
||||
def run(self, arg):
|
||||
ida_kernwin.msg("PBI >> run() called with %d!\n" % arg)
|
||||
print_basic_info.main()
|
||||
return True
|
||||
|
||||
class pbi_plugin_t(ida_idaapi.plugin_t):
|
||||
flags = ida_idaapi.PLUGIN_UNL | ida_idaapi.PLUGIN_MULTI
|
||||
comment = "This is a simple plugin printing basic info"
|
||||
help = ""
|
||||
wanted_name = "Print Basic Info (PBI) plugin"
|
||||
wanted_hotkey = "Ctrl-Alt-F12"
|
||||
|
||||
|
||||
def init(self):
|
||||
ida_kernwin.msg("PBI >> init() called!\n")
|
||||
return pbi_plugmod_t()
|
||||
|
||||
def term(self):
|
||||
ida_kernwin.msg("PBI >> ERROR: term() called (should never be called)\n")
|
||||
|
||||
def PLUGIN_ENTRY():
|
||||
return pbi_plugin_t()
|
||||
@@ -0,0 +1,103 @@
|
||||
'''
|
||||
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()
|
||||
@@ -0,0 +1,27 @@
|
||||
import ida_ida
|
||||
import ida_idaapi
|
||||
import ida_bytes
|
||||
import ida_funcs
|
||||
|
||||
def main():
|
||||
if ida_ida.inf_get_filetype() != ida_ida.f_PE or not ida_ida.inf_is_64bit() or ida_ida.inf_get_procname() != 'metapc':
|
||||
return
|
||||
|
||||
pattern_bytes = b'\x75\x03\x0F\x05'
|
||||
rstart = ida_ida.inf_get_min_ea()
|
||||
|
||||
found = False
|
||||
while True:
|
||||
rstart = ida_bytes.find_bytes(pattern_bytes, rstart)
|
||||
if rstart == ida_idaapi.BADADDR:
|
||||
break
|
||||
fname = ida_funcs.get_func_name(rstart)
|
||||
if fname and not found:
|
||||
found = True
|
||||
print('Syscall found:')
|
||||
if fname:
|
||||
print(f'\t@ {rstart + 2:x} ({fname})')
|
||||
rstart += 1
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -0,0 +1,21 @@
|
||||
# TIL API examples:
|
||||
|
||||
## Beginner level examples:
|
||||
* list_enum_member.py
|
||||
* list_struct_member.py
|
||||
* list_union_member.py
|
||||
* import_type_from_til.py
|
||||
* list_struct_xref.py
|
||||
* create_array.py
|
||||
|
||||
## Intermediate level examples:
|
||||
* create_structs.py
|
||||
* create_libssh2.py
|
||||
* create_bmenum.py
|
||||
* create_bfstruct.py
|
||||
* func_ti_changed_listener.py
|
||||
* mark_func_spoiled.py
|
||||
* setpehdr.py
|
||||
|
||||
## Advanced level examples:
|
||||
* operand_to_struct_member.py
|
||||
@@ -0,0 +1,71 @@
|
||||
"""
|
||||
summary: List the .idata section content and the corresponding
|
||||
data and code references when it applies.
|
||||
|
||||
description:
|
||||
In this script, we iterate through the .idata PE section.
|
||||
For each imported function we display:
|
||||
* its name
|
||||
* the data references to it (when applying)
|
||||
* the code references to it (when applying,
|
||||
"""
|
||||
import ida_segment
|
||||
import ida_name
|
||||
import idautils
|
||||
import ida_kernwin
|
||||
import ida_funcs
|
||||
|
||||
def is_code(ea):
|
||||
return ida_segment.segtype(ea) == ida_segment.SEG_CODE
|
||||
|
||||
def newline():
|
||||
print('')
|
||||
|
||||
def list_refs(refs, code):
|
||||
first = True
|
||||
if code:
|
||||
type = 'code'
|
||||
else:
|
||||
type = 'data'
|
||||
|
||||
idx = 1
|
||||
for ref in refs:
|
||||
if first:
|
||||
print(f'\tList of {type} references:')
|
||||
first = False
|
||||
ida_kernwin.msg(f'\t* [{idx}] @ {ref:x}')
|
||||
if is_code(ref):
|
||||
name = ida_funcs.get_func_name(ref)
|
||||
if name:
|
||||
print(f' ({name})')
|
||||
else:
|
||||
newline()
|
||||
else:
|
||||
newline()
|
||||
idx += 1
|
||||
|
||||
|
||||
def main():
|
||||
import_seg = ida_segment.get_segm_by_name('.idata')
|
||||
|
||||
if import_seg:
|
||||
curr_ea = import_seg.start_ea
|
||||
end_ea = import_seg.end_ea
|
||||
idx = 1
|
||||
while curr_ea < end_ea:
|
||||
name = ida_name.get_ea_name(curr_ea)
|
||||
print(f'Imported function [{idx}]: {name}')
|
||||
|
||||
list_refs(idautils.DataRefsTo(curr_ea), False)
|
||||
|
||||
list_refs(idautils.CodeRefsTo(curr_ea, 0), True)
|
||||
|
||||
if import_seg.is_64bit():
|
||||
curr_ea += 8
|
||||
else:
|
||||
curr_ea += 4
|
||||
idx += 1
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
+15070
-14561
File diff suppressed because it is too large
Load Diff
+28019
-49668
File diff suppressed because it is too large
Load Diff
-14228
File diff suppressed because it is too large
Load Diff
-67968
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,242 @@
|
||||
|
||||
class data_type_t(object):
|
||||
"""
|
||||
Information about a data type
|
||||
"""
|
||||
|
||||
def may_create_at(self, ea, nbytes):
|
||||
"""May create data?
|
||||
No such callback means: always succeed (i.e., no restriction where
|
||||
such a data type can be created.)
|
||||
@param ea: candidate address for the data item
|
||||
@param nbytes: candidate size for the data item
|
||||
@return: True/False
|
||||
"""
|
||||
return True
|
||||
|
||||
def calc_item_size(self, ea, maxsize):
|
||||
"""This callback is used to determine size of the (possible)
|
||||
item at `ea`.
|
||||
No such callback means that datatype is of fixed size `value_size`.
|
||||
(thus, this callback is required only for varsize datatypes.)
|
||||
@param ea: address of the item
|
||||
@param maxsize: maximum size of the item
|
||||
@return: 0 - no such item can be created/displayed
|
||||
"""
|
||||
return 0
|
||||
|
||||
|
||||
class data_format_t(object):
|
||||
"""
|
||||
Information about a data format
|
||||
"""
|
||||
|
||||
def printf(self, value, current_ea, operand_num, dtid):
|
||||
"""Convert `value` to colored string using custom format.
|
||||
@param value: value to print (of type 'str', sequence of bytes)
|
||||
@param current_ea: current address (BADADDR if unknown)
|
||||
@param operand_num: current operand number
|
||||
@param dtid: custom data type id
|
||||
@return: string representing data
|
||||
"""
|
||||
return None
|
||||
|
||||
def scan(self, input, current_ea, operand_num):
|
||||
"""Convert uncolored string (user input) to the value.
|
||||
This callback is called from the debugger when an user enters a
|
||||
new value for a register with a custom data representation (e.g.,
|
||||
an MMX register.)
|
||||
@param input: input string
|
||||
@param current_ea: current address (BADADDR if unknown)
|
||||
@param operand_num: current operand number (-1 if unknown)
|
||||
@return: tuple(bool, string)
|
||||
(True, output value) or
|
||||
(False, error message)
|
||||
"""
|
||||
return (False, "Not implemented")
|
||||
|
||||
def analyze(self, current_ea, operand_num):
|
||||
"""Analyze custom data format occurrence.
|
||||
This callback is called in 2 cases:
|
||||
- after emulating an instruction (after a call of
|
||||
'ev_emu_insn') if its operand is marked as "custom data
|
||||
representation"
|
||||
- when emulating data (this is done using a call of
|
||||
'ev_out_data' with analyze_only == true). This is the right
|
||||
place to create cross references from the current item.
|
||||
@param current_ea: current address (BADADDR if unknown)
|
||||
@param operand_num: current operand number
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
def register_custom_data_type(dt):
|
||||
"""
|
||||
Registers a custom data type.
|
||||
|
||||
@param dt: an instance of the data_type_t class
|
||||
@return:
|
||||
< 0 if failed to register
|
||||
> 0 data type id
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
def unregister_custom_data_type(dtid):
|
||||
"""
|
||||
Unregisters a custom data type.
|
||||
|
||||
@param dtid: the data type id
|
||||
@return: Boolean
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
def register_custom_data_format(df):
|
||||
"""
|
||||
Registers a custom data format with a given data type.
|
||||
|
||||
@param df: an instance of data_format_t
|
||||
@return:
|
||||
< 0 if failed to register
|
||||
> 0 data format id
|
||||
"""
|
||||
pass
|
||||
|
||||
def unregister_custom_data_format(dfid):
|
||||
"""
|
||||
Unregisters a custom data format
|
||||
|
||||
@param dfid: data format id
|
||||
@return: Boolean
|
||||
"""
|
||||
pass
|
||||
|
||||
def visit_patched_bytes(ea1: ida_idaapi.ea_t, ea2: ida_idaapi.ea_t, callable):
|
||||
"""
|
||||
Enumerates patched bytes in the given range and invokes a callable
|
||||
|
||||
@param ea1: start address
|
||||
@param ea2: end address
|
||||
@param callable: a Python callable with the following prototype:
|
||||
callable(ea, fpos, org_val, patch_val).
|
||||
If the callable returns non-zero then that value will be
|
||||
returned to the caller and the enumeration will be
|
||||
interrupted.
|
||||
@return: Zero if the enumeration was successful or the return
|
||||
value of the callback if enumeration was interrupted.
|
||||
"""
|
||||
pass
|
||||
|
||||
def get_bytes(ea: ida_idaapi.ea_t, size: int, gmb_flags: int=GMB_READALL):
|
||||
"""
|
||||
Get the specified number of bytes of the program.
|
||||
|
||||
@param ea: program address
|
||||
@param size: number of bytes to return
|
||||
@param gmb_flags: OR'ed combination of GMB_* values (defaults to GMB_READALL)
|
||||
@return: the bytes (as bytes object), or None in case of failure
|
||||
"""
|
||||
pass
|
||||
|
||||
def get_bytes_and_mask(ea: ida_idaapi.ea_t, size: int, gmb_flags: int=GMB_READALL):
|
||||
"""
|
||||
Get the specified number of bytes of the program, and a bitmask
|
||||
specifying what bytes are defined and what bytes are not.
|
||||
|
||||
@param ea: program address
|
||||
@param size: number of bytes to return
|
||||
@param gmb_flags: OR'ed combination of GMB_* values (defaults to GMB_READALL)
|
||||
@return: a tuple (bytes, mask), or None in case of failure.
|
||||
Both 'bytes' and 'mask' are 'str' instances.
|
||||
"""
|
||||
pass
|
||||
|
||||
# Conversion options for get_strlit_contents():
|
||||
STRCONV_ESCAPE = 0x00000001 # convert non-printable characters to C escapes (\n, \xNN, \uNNNN)
|
||||
|
||||
def get_strlit_contents(ea: ida_idaapi.ea_t, len: int, type: int, flags: int = 0):
|
||||
"""
|
||||
Get contents of string literal, as UTF-8-encoded codepoints.
|
||||
It works even if the string has not been created in the database yet.
|
||||
|
||||
Note that the returned value will be of type 'bytes'; if
|
||||
you want auto-conversion to unicode strings (that is: real Python
|
||||
strings), you should probably be using the idautils.Strings class.
|
||||
|
||||
@param ea: linear address of the string
|
||||
@param len: length of the string in bytes (including terminating 0)
|
||||
@param type: type of the string. Represents both the character encoding,
|
||||
<u>and</u> the 'type' of string at the given location.
|
||||
@param flags: combination of STRCONV_..., to perform output conversion.
|
||||
@return: a bytes-filled str object.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
def op_stroff(*args) -> bool:
|
||||
"""
|
||||
Set operand representation to be 'struct offset'.
|
||||
|
||||
This function has the following signatures:
|
||||
|
||||
1. op_stroff(ins: ida_ua.insn_t, n: int, path: List[int], delta: int)
|
||||
2. op_stroff(ins: ida_ua.insn_t, n: int, path: ida_pro.tid_array, path_len: int, delta: int) (backward-compatibility only)
|
||||
|
||||
Here is an example using this function:
|
||||
|
||||
ins = ida_ua.insn_t()
|
||||
if ida_ua.decode_insn(ins, some_address):
|
||||
operand = 0
|
||||
path = [ida_typeinf.get_named_type_tid("my_stucture_t")] # a one-element path
|
||||
ida_bytes.op_stroff(ins, operand, path, 0)
|
||||
"""
|
||||
pass
|
||||
|
||||
def get_stroff_path(*args):
|
||||
"""
|
||||
Get the structure offset path for operand `n`, at the
|
||||
specified address.
|
||||
|
||||
This function has the following signatures:
|
||||
|
||||
1. get_stroff_path(ea: ida_idaapi.ea_t, n : int) -> Tuple[List[int], int]
|
||||
2. get_stroff_path(path: tid_array, delta: sval_pointer, ea: ida_idaapi.ea_t, n : int) (backward-compatibility only)
|
||||
|
||||
@param ea address where the operand holds a path to a structure offset (1st form)
|
||||
@param n operand number (1st form)
|
||||
@return a tuple holding a (list_of_tid_t's, delta_within_the_last_type), or (None, None)
|
||||
"""
|
||||
pass
|
||||
|
||||
def bin_search(*args):
|
||||
"""
|
||||
Search for a set of bytes in the program
|
||||
|
||||
This function has the following signatures:
|
||||
|
||||
1. bin_search(start_ea: ida_idaapi.ea_t, end_ea: ida_idaapi.ea_t, data: compiled_binpat_vec_t, flags: int) -> Tuple[ida_idaapi.ea_t, int]
|
||||
2. bin_search(start_ea: ida_idaapi.ea_t, end_ea: ida_idaapi.ea_t, image: bytes, mask: bytes, len: int, flags: int) -> ida_idaapi.ea_t
|
||||
|
||||
The return value type will differ depending on the form:
|
||||
|
||||
1. a tuple `(matched-address, index-in-compiled_binpat_vec_t)` (1st form)
|
||||
2. the address of a match, or ida_idaapi.BADADDR if not found (2nd form)
|
||||
|
||||
This is a low-level function; more user-friendly alternatives
|
||||
are available. Please see 'find_bytes' and 'find_string'.
|
||||
|
||||
@param start_ea: linear address, start of range to search
|
||||
@param end_ea: linear address, end of range to search (exclusive)
|
||||
@param data: (1st form) the prepared data to search for (see parse_binpat_str())
|
||||
@param bytes: (2nd form) a set of bytes to match
|
||||
@param mask: (2nd form) a mask to apply to the set of bytes
|
||||
@param flags: combination of BIN_SEARCH_* flags
|
||||
@return: either a tuple holding both the address of the match and the index of the compiled pattern that matched, or the address of a match (ida_idaapi.BADADDR if not found)
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,125 @@
|
||||
|
||||
def get_manual_regions(*args):
|
||||
"""
|
||||
Returns the manual memory regions
|
||||
|
||||
This function has the following signatures:
|
||||
|
||||
1. get_manual_regions() -> List[Tuple(ida_idaapi.ea_t, ida_idaapi.ea_t, str, str, ida_idaapi.ea_t, int, int)]
|
||||
Where each tuple holds (start_ea, end_ea, name, sclass, sbase, bitness, perm)
|
||||
2. get_manual_regions(storage: meminfo_vec_t) -> None
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
def dbg_is_loaded():
|
||||
"""
|
||||
Checks if a debugger is loaded
|
||||
|
||||
@return: Boolean
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
def refresh_debugger_memory():
|
||||
"""
|
||||
Refreshes the debugger memory
|
||||
|
||||
@return: Nothing
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
def py_list_bptgrps():
|
||||
"""
|
||||
Returns list of breakpoint group names
|
||||
|
||||
@return: A list of strings or None on failure
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
def internal_get_sreg_base(tid: int, sreg_value: int):
|
||||
"""
|
||||
Get the sreg base, for the given thread.
|
||||
|
||||
@param tid: the thread ID
|
||||
@param sreg_value: the sreg value
|
||||
@return: The sreg base, or BADADDR on failure.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
def dbg_can_query():
|
||||
"""
|
||||
This function can be used to check if the debugger can be queried:
|
||||
- debugger is loaded
|
||||
- process is suspended
|
||||
- process is not suspended but can take requests. In this case some requests like
|
||||
memory read/write, bpt management succeed and register querying will fail.
|
||||
Check if idaapi.get_process_state() < 0 to tell if the process is suspended
|
||||
|
||||
@return: Boolean
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
def get_reg_vals(tid: int, clsmask: int=-1) -> 'ida_idd.regvals_t':
|
||||
"""
|
||||
Fetch live registers values for the thread
|
||||
|
||||
@param tid The ID of the thread to read registers for
|
||||
@param clsmask An OR'ed mask of register classes to
|
||||
read values for (can be used to speed up the
|
||||
retrieval process)
|
||||
|
||||
@return: a list of register values (empty if an error occurs)
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
def get_reg_val(*args):
|
||||
"""
|
||||
Get a register value.
|
||||
|
||||
This function has the following signatures:
|
||||
|
||||
1. get_reg_val(name: str) -> Union[int, float, bytes]
|
||||
2. get_reg_val(name: str, regval: regval_t) -> bool
|
||||
|
||||
The first (and most user-friendly) form will return
|
||||
a value whose type is related to the register type.
|
||||
I.e., either an integer, a float or, in the case of large
|
||||
vector registers, a bytes sequence.
|
||||
|
||||
@param name the register name
|
||||
@return the register value (1st form)
|
||||
"""
|
||||
pass
|
||||
|
||||
def set_reg_val(*args) -> bool:
|
||||
"""
|
||||
Set a register value by name
|
||||
|
||||
This function has the following signatures:
|
||||
1. set_reg_val(name: str, value: Union[int, float, bytes]) -> bool
|
||||
1. set_reg_val(tid: int, regidx: int, value: Union[int, float, bytes]) -> bool
|
||||
|
||||
Depending on the register type, this will expect
|
||||
either an integer, a float or, in the case of large
|
||||
vector registers, a bytes sequence.
|
||||
|
||||
@param name (1st form) the register name
|
||||
@param tid (2nd form) the thread ID
|
||||
@param regidx (2nd form) the register index
|
||||
@param value the register value
|
||||
@return success
|
||||
"""
|
||||
pass
|
||||
|
||||
def list_bptgrps() -> List[str]:
|
||||
"""
|
||||
Retrieve the list of absolute path of all folders of bpt dirtree.
|
||||
Synchronous function, Notification, none (synchronous function)
|
||||
"""
|
||||
pass
|
||||
@@ -0,0 +1,16 @@
|
||||
|
||||
def enumerate_files(path, fname, callback):
|
||||
"""
|
||||
Enumerate files in the specified directory while the callback returns 0.
|
||||
|
||||
@param path: directory to enumerate files in
|
||||
@param fname: mask of file names to enumerate
|
||||
@param callback: a callable object that takes the filename as
|
||||
its first argument and it returns 0 to continue
|
||||
enumeration or non-zero to stop enumeration.
|
||||
@return:
|
||||
None in case of script errors
|
||||
tuple(code, fname) : If the callback returns non-zero
|
||||
"""
|
||||
pass
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
|
||||
class qfile_t(pyidc_opaque_object_t):
|
||||
|
||||
"""A helper class to work with FILE related functions."""
|
||||
|
||||
def __init__(self, *args):
|
||||
pass
|
||||
|
||||
def close(self):
|
||||
"""Closes the file"""
|
||||
pass
|
||||
|
||||
def open(self, filename, mode):
|
||||
"""
|
||||
Opens a file
|
||||
|
||||
@param filename: the file name
|
||||
@param mode: The mode string, ala fopen() style
|
||||
@return: Boolean
|
||||
"""
|
||||
pass
|
||||
|
||||
def set_linput(self, linput):
|
||||
"""Links the current loader_input_t instance to a linput_t instance"""
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def tmpfile():
|
||||
"""A static method to construct an instance using a temporary file"""
|
||||
pass
|
||||
|
||||
def seek(self, offset, whence = ida_idaapi.SEEK_SET):
|
||||
"""
|
||||
Set input source position
|
||||
|
||||
@param offset: the seek offset
|
||||
@param whence: the position to seek from
|
||||
@return: the new position (not 0 as fseek!)
|
||||
"""
|
||||
pass
|
||||
|
||||
def tell(self):
|
||||
"""Returns the current position"""
|
||||
pass
|
||||
|
||||
def gets(self, len):
|
||||
"""
|
||||
Reads a line from the input file. Returns the read line or None
|
||||
|
||||
@param len: the maximum line length
|
||||
"""
|
||||
pass
|
||||
|
||||
def read(self, size):
|
||||
"""
|
||||
Reads from the file. Returns the buffer or None
|
||||
|
||||
@param size: the maximum number of bytes to read
|
||||
@return: a str, or None
|
||||
"""
|
||||
pass
|
||||
|
||||
def write(self, buf):
|
||||
"""
|
||||
Writes to the file. Returns 0 or the number of bytes written
|
||||
|
||||
@param buf: the str to write
|
||||
@return: result code
|
||||
"""
|
||||
pass
|
||||
|
||||
def readbytes(self, size, big_endian):
|
||||
"""
|
||||
Similar to read() but it respect the endianness
|
||||
|
||||
@param size: the maximum number of bytes to read
|
||||
@param big_endian: endianness
|
||||
@return a str, or None
|
||||
"""
|
||||
pass
|
||||
|
||||
def writebytes(self, size, big_endian):
|
||||
"""
|
||||
Similar to write() but it respect the endianness
|
||||
|
||||
@param buf: the str to write
|
||||
@param big_endian: endianness
|
||||
@return: result code
|
||||
"""
|
||||
pass
|
||||
|
||||
def flush(self):
|
||||
pass
|
||||
|
||||
def get_byte(self):
|
||||
"""Reads a single byte from the file. Returns None if EOF or the read byte"""
|
||||
pass
|
||||
|
||||
def put_byte(self):
|
||||
"""
|
||||
Writes a single byte to the file
|
||||
|
||||
@param chr: the byte value
|
||||
"""
|
||||
pass
|
||||
|
||||
def opened(self):
|
||||
"""Checks if the file is opened or not"""
|
||||
pass
|
||||
@@ -0,0 +1,63 @@
|
||||
|
||||
def get_fchunk_referer(ea: int, idx):
|
||||
pass
|
||||
|
||||
def get_idasgn_desc(n):
|
||||
"""
|
||||
Get information about a signature in the list.
|
||||
It returns: (name of signature, names of optional libraries)
|
||||
|
||||
See also: get_idasgn_desc_with_matches
|
||||
|
||||
@param n: number of signature in the list (0..get_idasgn_qty()-1)
|
||||
@return: None on failure or tuple(signame, optlibs)
|
||||
"""
|
||||
pass
|
||||
|
||||
def get_idasgn_desc_with_matches(n):
|
||||
"""
|
||||
Get information about a signature in the list.
|
||||
It returns: (name of signature, names of optional libraries, number of matches)
|
||||
|
||||
@param n: number of signature in the list (0..get_idasgn_qty()-1)
|
||||
@return: None on failure or tuple(signame, optlibs, nmatches)
|
||||
"""
|
||||
pass
|
||||
|
||||
class func_t(object):
|
||||
def get_name(self):
|
||||
"""
|
||||
Get the function name
|
||||
|
||||
@return the function name
|
||||
"""
|
||||
pass
|
||||
|
||||
def get_frame_object(self):
|
||||
"""
|
||||
Retrieve the function frame, in the form of a structure
|
||||
where frame offsets that are accessed by the program, as well
|
||||
as areas for "saved registers" and "return address", are
|
||||
represented by structure members.
|
||||
|
||||
If the function has no associated frame, return None
|
||||
|
||||
@return a ida_typeinf.tinfo_t object representing the frame, or None
|
||||
"""
|
||||
pass
|
||||
|
||||
def get_prototype(self):
|
||||
"""
|
||||
Retrieve the function prototype.
|
||||
|
||||
Once you have obtained the prototype, you can:
|
||||
|
||||
* retrieve the return type through ida_typeinf.tinfo_t.get_rettype()
|
||||
* iterate on the arguments using ida_typeinf.tinfo_t.iter_func()
|
||||
|
||||
If the function has no associated prototype, return None
|
||||
|
||||
@return a ida_typeinf.tinfo_t object representing the prototype, or None
|
||||
"""
|
||||
pass
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
|
||||
class GraphViewer(ida_kernwin.CustomIDAMemo):
|
||||
|
||||
def OnGetText(self, node_id):
|
||||
"""
|
||||
Triggered when the graph viewer wants the text and color for a given node.
|
||||
This callback is triggered one time for a given node (the value will be cached and used later without callin Python).
|
||||
When you call refresh then again this callback will be called for each node.
|
||||
|
||||
This callback is mandatory.
|
||||
|
||||
@return: Return a string to describe the node text or return a tuple (node_text, node_color) to describe bot text and color
|
||||
"""
|
||||
return str(self[node_id])
|
||||
|
||||
def OnActivate(self):
|
||||
"""
|
||||
Triggered when the graph window gets the focus
|
||||
@return: None
|
||||
"""
|
||||
print("Activated....")
|
||||
|
||||
def OnDeactivate(self):
|
||||
"""Triggered when the graph window loses the focus
|
||||
@return: None
|
||||
"""
|
||||
print("Deactivated....")
|
||||
|
||||
def OnHint(self, node_id):
|
||||
"""
|
||||
Triggered when the graph viewer wants to retrieve hint text associated with a given node
|
||||
|
||||
@return: None if no hint is avail or a string designating the hint
|
||||
"""
|
||||
return "hint for " + str(node_id)
|
||||
|
||||
def OnEdgeHint(self, src, dst):
|
||||
"""
|
||||
Triggered when the graph viewer wants to retrieve hint text associated with a edge
|
||||
|
||||
@return: None if no hint is avail or a string designating the hint
|
||||
"""
|
||||
return "hint for edge %d -> %d" % (src, dst)
|
||||
|
||||
def OnClose(self):
|
||||
"""Triggered when the graph viewer window is being closed
|
||||
@return: None
|
||||
"""
|
||||
print("Closing.......")
|
||||
|
||||
def OnClick(self, node_id):
|
||||
"""
|
||||
Triggered when a node is clicked
|
||||
@return: False to ignore the click and True otherwise
|
||||
"""
|
||||
print("clicked on", self[node_id])
|
||||
return True
|
||||
|
||||
def OnDblClick(self, node_id):
|
||||
"""
|
||||
Triggerd when a node is double-clicked.
|
||||
@return: False to ignore the click and True otherwise
|
||||
"""
|
||||
print("dblclicked on", self[node_id])
|
||||
return True
|
||||
@@ -0,0 +1,31 @@
|
||||
|
||||
class cfunc_t(object):
|
||||
def find_item_coords(self, *args):
|
||||
"""
|
||||
This method has the following signatures:
|
||||
|
||||
1. find_item_coords(item: citem_t) -> Tuple[int, int]
|
||||
2. find_item_coords(item: citem_t, x: int_pointer, y: int_pointer) -> bool
|
||||
|
||||
NOTE: The second form is retained for backward-compatibility,
|
||||
but we strongly recommend using the first.
|
||||
|
||||
@param item The item to find coordinates for in the pseudocode listing
|
||||
"""
|
||||
pass
|
||||
|
||||
class cfuncptr_t(object):
|
||||
def find_item_coords(self, *args):
|
||||
"""
|
||||
This method has the following signatures:
|
||||
|
||||
1. find_item_coords(item: citem_t) -> Tuple[int, int]
|
||||
2. find_item_coords(item: citem_t, x: int_pointer, y: int_pointer) -> bool
|
||||
|
||||
NOTE: The second form is retained for backward-compatibility,
|
||||
but we strongly recommend using the first.
|
||||
|
||||
@param item The item to find coordinates for in the pseudocode listing
|
||||
"""
|
||||
pass
|
||||
|
||||
@@ -0,0 +1,171 @@
|
||||
def parse_command_line(cmdline):
|
||||
"""
|
||||
Parses a space separated string (quotes and escape character are supported)
|
||||
@param cmdline: The command line to parse
|
||||
@return: A list of strings or None on failure
|
||||
"""
|
||||
pass
|
||||
|
||||
def set_script_timeout(timeout):
|
||||
"""
|
||||
Changes the script timeout value. The script wait box dialog will be hidden and shown again when the timeout elapses.
|
||||
See also L{disable_script_timeout}.
|
||||
|
||||
@param timeout: This value is in seconds.
|
||||
If this value is set to zero then the script will never timeout.
|
||||
@return: Returns the old timeout value
|
||||
"""
|
||||
pass
|
||||
|
||||
def disable_script_timeout():
|
||||
"""
|
||||
Disables the script timeout and hides the script wait box.
|
||||
Calling L{set_script_timeout} will not have any effects until the script is compiled and executed again
|
||||
|
||||
@return: None
|
||||
"""
|
||||
pass
|
||||
|
||||
def enable_extlang_python(enable):
|
||||
"""
|
||||
Enables or disables Python extlang.
|
||||
When enabled, all expressions will be evaluated by Python.
|
||||
|
||||
@param enable: Set to True to enable, False otherwise
|
||||
"""
|
||||
pass
|
||||
|
||||
def RunPythonStatement(stmt):
|
||||
"""
|
||||
This is an IDC function exported from the Python plugin.
|
||||
It is used to evaluate Python statements from IDC.
|
||||
@param stmt: The statement to evaluate
|
||||
@return: 0 - on success otherwise a string containing the error
|
||||
"""
|
||||
pass
|
||||
|
||||
class loader_input_t(pyidc_opaque_object_t):
|
||||
"""
|
||||
A helper class to work with linput_t related functions.
|
||||
This class is also used by file loaders scripts.
|
||||
"""
|
||||
def __init__(self, pycapsule=None):
|
||||
pass
|
||||
|
||||
def close(self):
|
||||
"""Closes the file"""
|
||||
pass
|
||||
|
||||
def open(self, filename, remote = False):
|
||||
"""
|
||||
Opens a file (or a remote file)
|
||||
|
||||
@param filename: the file name
|
||||
@param remote: whether the file is local, or remote
|
||||
@return: Boolean
|
||||
"""
|
||||
pass
|
||||
|
||||
def set_linput(self, linput):
|
||||
"""
|
||||
Links the current loader_input_t instance to a linput_t instance
|
||||
|
||||
@param linput: the linput_t to link to
|
||||
"""
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def from_fp(fp):
|
||||
"""
|
||||
A static method to construct an instance from a FILE*
|
||||
|
||||
@param fp: a FILE pointer
|
||||
@return: a new instance, or None
|
||||
"""
|
||||
pass
|
||||
|
||||
def open_memory(self, start: ea_t, size: int):
|
||||
"""
|
||||
Create a linput for process memory (By internally calling idaapi.create_memory_linput())
|
||||
This linput will use dbg->read_memory() to read data
|
||||
|
||||
@param start: starting address of the input
|
||||
@param size: size of the memory range to represent as linput
|
||||
if unknown, may be passed as 0
|
||||
"""
|
||||
pass
|
||||
|
||||
def seek(self, offset: int, whence = SEEK_SET):
|
||||
"""
|
||||
Set input source position
|
||||
|
||||
@param offset: the seek offset
|
||||
@param whence: the position to seek from
|
||||
@return: the new position (not 0 as fseek!)
|
||||
"""
|
||||
pass
|
||||
|
||||
def tell(self):
|
||||
"""Returns the current position"""
|
||||
pass
|
||||
|
||||
def getz(self, size: int, fpos: int=-1):
|
||||
"""
|
||||
Returns a zero terminated string at the given position
|
||||
|
||||
@param size: maximum size of the string
|
||||
@param fpos: if != -1 then seek will be performed before reading
|
||||
@return: The string or None on failure.
|
||||
"""
|
||||
pass
|
||||
|
||||
def gets(self, len: int):
|
||||
"""
|
||||
Reads a line from the input file. Returns the read line or None
|
||||
|
||||
@param len: the maximum line length
|
||||
@return: a str, or None
|
||||
"""
|
||||
pass
|
||||
|
||||
def read(self, size: int=-1):
|
||||
"""
|
||||
Read up to size bytes (all data if size is negative). Return an empty bytes object on EOF.
|
||||
|
||||
@param size: the maximum number of bytes to read
|
||||
@return a bytes object
|
||||
"""
|
||||
pass
|
||||
|
||||
def readbytes(self, size: int, big_endian: bool):
|
||||
"""
|
||||
Similar to read() but it respect the endianness
|
||||
|
||||
@param size: the maximum number of bytes to read
|
||||
@param big_endian: endianness
|
||||
@return a str, or None
|
||||
"""
|
||||
pass
|
||||
|
||||
def file2base(self, pos: int, ea1: ea_t, ea2: ea_t, patchable: bool):
|
||||
"""
|
||||
Load portion of file into the database
|
||||
This function will include (ea1..ea2) into the addressing space of the
|
||||
program (make it enabled)
|
||||
|
||||
@param li: pointer ot input source
|
||||
@param pos: position in the file
|
||||
@param (ea1..ea2): range of destination linear addresses
|
||||
@param patchable: should the kernel remember correspondance of
|
||||
file offsets to linear addresses.
|
||||
@return: 1-ok,0-read error, a warning is displayed
|
||||
"""
|
||||
pass
|
||||
|
||||
def get_byte(self):
|
||||
"""Reads a single byte from the file. Returns None if EOF or the read byte"""
|
||||
pass
|
||||
|
||||
def opened(self):
|
||||
"""Checks if the file is opened or not"""
|
||||
pass
|
||||
@@ -0,0 +1,71 @@
|
||||
|
||||
def dbg_get_registers():
|
||||
"""
|
||||
This function returns the register definition from the currently loaded debugger.
|
||||
Basically, it returns an array of structure similar to to idd.hpp / register_info_t
|
||||
|
||||
@return:
|
||||
None if no debugger is loaded
|
||||
tuple(name, flags, class, dtype, bit_strings, default_bit_strings_mask)
|
||||
The bit_strings can be a tuple of strings or None (if the register does not have bit_strings)
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
def dbg_get_thread_sreg_base(tid, sreg_value):
|
||||
"""
|
||||
Returns the segment register base value
|
||||
|
||||
@param tid: thread id
|
||||
@param sreg_value: segment register (selector) value
|
||||
@return:
|
||||
- The base as an 'ea'
|
||||
- Or None on failure
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
def dbg_read_memory(ea, sz):
|
||||
"""
|
||||
Reads from the debugee's memory at the specified ea
|
||||
|
||||
@param ea: the debuggee's memory address
|
||||
@param sz: the amount of data to read
|
||||
@return:
|
||||
- The read buffer (as bytes)
|
||||
- Or None on failure
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
def dbg_write_memory(ea, buffer):
|
||||
"""
|
||||
Writes a buffer to the debugee's memory
|
||||
|
||||
@param ea: the debuggee's memory address
|
||||
@param buf: a bytes object to write
|
||||
@return: Boolean
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
def dbg_get_name():
|
||||
"""
|
||||
This function returns the current debugger's name.
|
||||
|
||||
@return: Debugger name or None if no debugger is active
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
def dbg_get_memory_info():
|
||||
"""
|
||||
This function returns the memory configuration of a debugged process.
|
||||
|
||||
@return:
|
||||
None if no debugger is active
|
||||
tuple(start_ea, end_ea, name, sclass, sbase, bitness, perm)
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
@@ -0,0 +1,138 @@
|
||||
|
||||
def AssembleLine(ea, cs, ip, use32, line):
|
||||
"""
|
||||
Assemble an instruction to a string (display a warning if an error is found)
|
||||
|
||||
@param ea: linear address of instruction
|
||||
@param cs: cs of instruction
|
||||
@param ip: ip of instruction
|
||||
@param use32: is 32bit segment
|
||||
@param line: line to assemble
|
||||
@return:
|
||||
- None on failure
|
||||
- or a string containing the assembled instruction
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
def assemble(ea, cs, ip, use32, line):
|
||||
"""
|
||||
Assemble an instruction into the database (display a warning if an error is found)
|
||||
|
||||
@param ea: linear address of instruction
|
||||
@param cs: cs of instruction
|
||||
@param ip: ip of instruction
|
||||
@param use32: is 32bit segment?
|
||||
@param line: line to assemble
|
||||
|
||||
@return: Boolean. True on success.
|
||||
"""
|
||||
|
||||
def ph_get_id():
|
||||
"""
|
||||
Returns the 'ph.id' field
|
||||
"""
|
||||
pass
|
||||
|
||||
def ph_get_version():
|
||||
"""
|
||||
Returns the 'ph.version'
|
||||
"""
|
||||
pass
|
||||
|
||||
def ph_get_flag():
|
||||
"""
|
||||
Returns the 'ph.flag'
|
||||
"""
|
||||
pass
|
||||
|
||||
def ph_get_cnbits():
|
||||
"""
|
||||
Returns the 'ph.cnbits'
|
||||
"""
|
||||
pass
|
||||
|
||||
def ph_get_dnbits():
|
||||
"""
|
||||
Returns the 'ph.dnbits'
|
||||
"""
|
||||
pass
|
||||
|
||||
def ph_get_reg_first_sreg():
|
||||
"""
|
||||
Returns the 'ph.reg_first_sreg'
|
||||
"""
|
||||
pass
|
||||
|
||||
def ph_get_reg_last_sreg():
|
||||
"""
|
||||
Returns the 'ph.reg_last_sreg'
|
||||
"""
|
||||
pass
|
||||
|
||||
def ph_get_segreg_size():
|
||||
"""
|
||||
Returns the 'ph.segreg_size'
|
||||
"""
|
||||
pass
|
||||
|
||||
def ph_get_reg_code_sreg():
|
||||
"""
|
||||
Returns the 'ph.reg_code_sreg'
|
||||
"""
|
||||
pass
|
||||
|
||||
def ph_get_reg_data_sreg():
|
||||
"""
|
||||
Returns the 'ph.reg_data_sreg'
|
||||
"""
|
||||
pass
|
||||
|
||||
def ph_get_icode_return():
|
||||
"""
|
||||
Returns the 'ph.icode_return'
|
||||
"""
|
||||
pass
|
||||
|
||||
def ph_get_instruc_start():
|
||||
"""
|
||||
Returns the 'ph.instruc_start'
|
||||
"""
|
||||
pass
|
||||
|
||||
def ph_get_instruc_end():
|
||||
"""
|
||||
Returns the 'ph.instruc_end'
|
||||
"""
|
||||
pass
|
||||
|
||||
def ph_get_tbyte_size():
|
||||
"""
|
||||
Returns the 'ph.tbyte_size' field as defined in he processor module
|
||||
"""
|
||||
pass
|
||||
|
||||
def ph_get_instruc():
|
||||
"""
|
||||
Returns a list of tuples (instruction_name, instruction_feature) containing the
|
||||
instructions list as defined in he processor module
|
||||
"""
|
||||
pass
|
||||
|
||||
def ph_get_regnames():
|
||||
"""
|
||||
Returns the list of register names as defined in the processor module
|
||||
"""
|
||||
pass
|
||||
|
||||
def ph_get_operand_info(ea: ida_idaapi.ea_t, n: int) -> Union[Tuple[int, ida_idaapi.ea_t, int, int, int], None]:
|
||||
"""
|
||||
Returns the operand information given an ea and operand number.
|
||||
|
||||
@param ea: address
|
||||
@param n: operand number
|
||||
|
||||
@return: Returns an idd_opinfo_t as a tuple: (modified, ea, reg_ival, regidx, value_size).
|
||||
Please refer to idd_opinfo_t structure in the SDK.
|
||||
"""
|
||||
pass
|
||||
@@ -0,0 +1,466 @@
|
||||
|
||||
class simplecustviewer_t(object):
|
||||
def OnClick(self, shift):
|
||||
"""
|
||||
User clicked in the view
|
||||
@param shift: Shift flag
|
||||
@return: Boolean. True if you handled the event
|
||||
"""
|
||||
print("OnClick, shift=%d" % shift)
|
||||
return True
|
||||
|
||||
def OnDblClick(self, shift):
|
||||
"""
|
||||
User dbl-clicked in the view
|
||||
@param shift: Shift flag
|
||||
@return: Boolean. True if you handled the event
|
||||
"""
|
||||
print("OnDblClick, shift=%d" % shift)
|
||||
return True
|
||||
|
||||
def OnCursorPosChanged(self):
|
||||
"""
|
||||
Cursor position changed.
|
||||
@return: Nothing
|
||||
"""
|
||||
print("OnCurposChanged")
|
||||
|
||||
def OnClose(self):
|
||||
"""
|
||||
The view is closing. Use this event to cleanup.
|
||||
@return: Nothing
|
||||
"""
|
||||
print("OnClose")
|
||||
|
||||
def OnKeydown(self, vkey, shift):
|
||||
"""
|
||||
User pressed a key
|
||||
@param vkey: Virtual key code
|
||||
@param shift: Shift flag
|
||||
@return: Boolean. True if you handled the event
|
||||
"""
|
||||
print("OnKeydown, vk=%d shift=%d" % (vkey, shift))
|
||||
return False
|
||||
|
||||
def OnHint(self, lineno):
|
||||
"""
|
||||
Hint requested for the given line number.
|
||||
@param lineno: The line number (zero based)
|
||||
@return:
|
||||
- tuple(number of important lines, hint string)
|
||||
- None: if no hint available
|
||||
"""
|
||||
return (1, "OnHint, line=%d" % lineno)
|
||||
|
||||
def OnPopupMenu(self, menu_id):
|
||||
"""
|
||||
A context (or popup) menu item was executed.
|
||||
@param menu_id: ID previously registered with add_popup_menu()
|
||||
@return: Boolean
|
||||
"""
|
||||
print("OnPopupMenu, menu_id=" % menu_id)
|
||||
return True
|
||||
|
||||
def register_timer(interval, callback):
|
||||
"""
|
||||
Register a timer
|
||||
|
||||
@param interval: Interval in milliseconds
|
||||
@param callback: A Python callable that takes no parameters and returns an integer.
|
||||
The callback may return:
|
||||
-1 : to unregister the timer
|
||||
>= 0 : the new or same timer interval
|
||||
@return: None or a timer object
|
||||
"""
|
||||
pass
|
||||
|
||||
def unregister_timer(timer_obj):
|
||||
"""
|
||||
Unregister a timer
|
||||
|
||||
@param timer_obj: a timer object previously returned by a register_timer()
|
||||
@return: Boolean
|
||||
@note: After the timer has been deleted, the timer_obj will become invalid.
|
||||
"""
|
||||
pass
|
||||
|
||||
def choose_idasgn():
|
||||
"""
|
||||
Opens the signature chooser
|
||||
|
||||
@return: None or the selected signature name
|
||||
"""
|
||||
pass
|
||||
|
||||
def get_highlight(v, flags=0):
|
||||
"""
|
||||
Returns the currently highlighted identifier and flags
|
||||
|
||||
@param v: The UI widget to operate on
|
||||
@param flags: Optionally specify a slot (see kernwin.hpp), current otherwise
|
||||
@return: a tuple (text, flags), or None if nothing
|
||||
is highlighted or in case of error.
|
||||
"""
|
||||
pass
|
||||
|
||||
def free_custom_icon(icon_id):
|
||||
"""
|
||||
Frees an icon loaded with load_custom_icon()
|
||||
|
||||
@param icon_id: The ID of the icon to free
|
||||
"""
|
||||
pass
|
||||
|
||||
def read_selection(v, p1, p2):
|
||||
"""
|
||||
Read the user selection, and store its information in p1 (from) and p2 (to).
|
||||
|
||||
This can be used as follows:
|
||||
|
||||
|
||||
>>> p1 = ida_kernwin.twinpos_t()
|
||||
p2 = ida_kernwin.twinpos_t()
|
||||
view = ida_kernwin.get_current_viewer()
|
||||
ida_kernwin.read_selection(view, p1, p2)
|
||||
|
||||
|
||||
At that point, p1 and p2 hold information for the selection.
|
||||
But, the 'at' property of p1 and p2 is not properly typed.
|
||||
To specialize it, call #place() on it, passing it the view
|
||||
they were retrieved from. Like so:
|
||||
|
||||
|
||||
>>> place0 = p1.place(view)
|
||||
place1 = p2.place(view)
|
||||
|
||||
|
||||
This will effectively "cast" the place into a specialized type,
|
||||
holding proper information, depending on the view type (e.g.,
|
||||
disassembly, structures, enums, ...)
|
||||
|
||||
@param v: The view to retrieve the selection for.
|
||||
@param p1: Storage for the "from" part of the selection.
|
||||
@param p2: Storage for the "to" part of the selection.
|
||||
@return: a bool value indicating success.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
def ask_text(max_size: int, defval: str, prompt: str) -> Union[str, None]:
|
||||
"""
|
||||
Asks for a long text
|
||||
|
||||
@param max_size: Maximum text length, 0 for unlimited
|
||||
@param defval: The default value
|
||||
@param prompt: The prompt value
|
||||
@return: None or the entered string
|
||||
"""
|
||||
pass
|
||||
|
||||
def ask_str(defval, hist, prompt):
|
||||
"""
|
||||
Asks for a long text
|
||||
|
||||
@param defval: The default value
|
||||
@param hist: history id
|
||||
@param prompt: The prompt value
|
||||
@return: None or the entered string
|
||||
"""
|
||||
pass
|
||||
|
||||
def process_ui_action(name: str, flags: int=0):
|
||||
"""
|
||||
Invokes an IDA UI action by name
|
||||
|
||||
@param name: action name
|
||||
@param flags: reserved
|
||||
@return: Boolean
|
||||
"""
|
||||
pass
|
||||
|
||||
def del_hotkey(ctx):
|
||||
"""
|
||||
Deletes a previously registered function hotkey
|
||||
|
||||
@param ctx: Hotkey context previously returned by add_hotkey()
|
||||
|
||||
@return: Boolean.
|
||||
"""
|
||||
pass
|
||||
|
||||
def add_hotkey(hotkey, callable):
|
||||
"""
|
||||
Associates a function call with a hotkey.
|
||||
Callable 'callable' will be called each time the hotkey is pressed
|
||||
|
||||
@param hotkey: The hotkey
|
||||
@param callable: Callable
|
||||
|
||||
@return: Context object on success or None on failure.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
MFF_FAST = 0x0000
|
||||
"""execute code as soon as possible
|
||||
this mode is ok call ui related functions
|
||||
that do not query the database."""
|
||||
|
||||
MFF_READ = 0x0001
|
||||
"""execute code only when ida is idle and it is safe to query the database.
|
||||
this mode is recommended only for code that does not modify the database.
|
||||
(nb: ida may be in the middle of executing another user request, for example it may be waiting for him to enter values into a modal dialog box)"""
|
||||
|
||||
MFF_WRITE = 0x0002
|
||||
"""execute code only when ida is idle and it is safe to modify the database. in particular, this flag will suspend execution if there is
|
||||
a modal dialog box on the screen this mode can be used to call any ida api function. MFF_WRITE implies MFF_READ"""
|
||||
|
||||
MFF_NOWAIT = 0x0004
|
||||
"""Do not wait for the request to be executed.
|
||||
he caller should ensure that the request is not
|
||||
destroyed until the execution completes.
|
||||
if not, the request will be ignored.
|
||||
the return code of execute_sync() is meaningless
|
||||
in this case.
|
||||
This flag can be used to delay the code execution
|
||||
until the next UI loop run even from the main thread"""
|
||||
|
||||
def execute_sync(callable, reqf):
|
||||
"""
|
||||
Executes a function in the context of the main thread.
|
||||
If the current thread not the main thread, then the call is queued and
|
||||
executed afterwards.
|
||||
|
||||
@param callable: A python callable object, must return an integer value
|
||||
@param reqf: one of MFF_ flags
|
||||
@return: -1 or the return value of the callable
|
||||
"""
|
||||
pass
|
||||
|
||||
def execute_ui_requests(callable_list):
|
||||
"""
|
||||
Inserts a list of callables into the UI message processing queue.
|
||||
When the UI is ready it will call one callable.
|
||||
A callable can request to be called more than once if it returns True.
|
||||
|
||||
@param callable_list: A list of python callable objects.
|
||||
@note: A callable should return True if it wants to be called more than once.
|
||||
@return: Boolean. False if the list contains a non callable item
|
||||
"""
|
||||
pass
|
||||
|
||||
def set_dock_pos(src_ctrl, dest_ctrl, orient, left = 0, top = 0, right = 0, bottom = 0):
|
||||
"""
|
||||
Sets the dock orientation of a window relatively to another window.
|
||||
|
||||
Use the left, top, right, bottom parameters if DP_FLOATING is used,
|
||||
or if you want to specify the width of docked windows.
|
||||
|
||||
@param src_ctrl: Source docking control
|
||||
@param dest_ctrl: Destination docking control
|
||||
@param orient: One of DP_XXXX constants
|
||||
@return: Boolean
|
||||
|
||||
Example:
|
||||
set_dock_pos('Structures', 'Enums', DP_RIGHT) <- docks the Structures window to the right of Enums window
|
||||
"""
|
||||
pass
|
||||
|
||||
def is_idaq():
|
||||
"""
|
||||
Returns True or False depending if IDAPython is hosted by IDAQ
|
||||
"""
|
||||
pass
|
||||
|
||||
def attach_dynamic_action_to_popup(
|
||||
unused,
|
||||
popup_handle,
|
||||
desc,
|
||||
popuppath = None,
|
||||
flags = 0):
|
||||
"""
|
||||
Create & insert an action into the widget's popup menu
|
||||
(::ui_attach_dynamic_action_to_popup).
|
||||
Note: The action description in the 'desc' parameter is modified by
|
||||
this call so you should prepare a new description for each call.
|
||||
For example:
|
||||
desc = ida_kernwin.action_desc_t(None, 'Dynamic popup action', Handler())
|
||||
ida_kernwin.attach_dynamic_action_to_popup(form, popup, desc)
|
||||
|
||||
@param unused: deprecated; should be None
|
||||
@param popup_handle: target popup
|
||||
@param desc: action description of type action_desc_t
|
||||
@param popuppath: can be None
|
||||
@param flags: a combination of SETMENU_ constants
|
||||
@return: success
|
||||
"""
|
||||
pass
|
||||
|
||||
def set_nav_colorizer(callback):
|
||||
"""
|
||||
Set a new colorizer for the navigation band.
|
||||
|
||||
The 'callback' is a function of 2 arguments:
|
||||
- ea (the EA to colorize for)
|
||||
- nbytes (the number of bytes at that EA)
|
||||
and must return a 'long' value.
|
||||
|
||||
The previous colorizer is returned, allowing
|
||||
the new 'callback' to use 'call_nav_colorizer'
|
||||
with it.
|
||||
|
||||
Note that the previous colorizer is returned
|
||||
only the first time set_nav_colorizer() is called:
|
||||
due to the way the colorizers API is defined in C,
|
||||
it is impossible to chain more than 2 colorizers
|
||||
in IDAPython: the original, IDA-provided colorizer,
|
||||
and a user-provided one.
|
||||
|
||||
Example: colorizer inverting the color provided by the IDA colorizer:
|
||||
def my_colorizer(ea, nbytes):
|
||||
global ida_colorizer
|
||||
orig = ida_kernwin.call_nav_colorizer(ida_colorizer, ea, nbytes)
|
||||
return long(~orig)
|
||||
|
||||
ida_colorizer = ida_kernwin.set_nav_colorizer(my_colorizer)
|
||||
|
||||
@param callback: the new colorizer
|
||||
"""
|
||||
pass
|
||||
|
||||
def call_nav_colorizer(colorizer, ea: ida_idaapi.ea_t, nbytes: int):
|
||||
"""
|
||||
To be used with the IDA-provided colorizer, that is
|
||||
returned as result of the first call to set_nav_colorizer().
|
||||
|
||||
@param colorizer: the Python colorizer to call
|
||||
@param ea: the address to colorize
|
||||
@param nbytes: the size of the range to colorize
|
||||
"""
|
||||
pass
|
||||
|
||||
def msg(message):
|
||||
"""
|
||||
Display a message in the message window
|
||||
|
||||
@param message: message to print
|
||||
"""
|
||||
pass
|
||||
|
||||
def warning(message):
|
||||
"""
|
||||
Display a message in a warning message box
|
||||
|
||||
@param message: message to print
|
||||
"""
|
||||
pass
|
||||
|
||||
def error(message):
|
||||
"""
|
||||
Display a fatal message in a message box and quit IDA
|
||||
|
||||
@param format: message to print
|
||||
"""
|
||||
pass
|
||||
|
||||
def get_navband_pixel(ea):
|
||||
"""
|
||||
Maps an address, onto a pixel coordinate within the navigation band
|
||||
|
||||
@param ea: The address to map
|
||||
@return: a list [pixel, is_vertical]
|
||||
"""
|
||||
pass
|
||||
|
||||
def choose_find(title: str) -> Union[object, None]:
|
||||
"""
|
||||
Retrieve the chooser object by title
|
||||
|
||||
@param title the chooser title
|
||||
@return the chooser, or None
|
||||
"""
|
||||
pass
|
||||
|
||||
class chooser_base_t(object):
|
||||
def get_row(self, n: int) -> Tuple[List[str], int, chooser_item_attrs_t]:
|
||||
"""
|
||||
Get data & attributes for a row in a chooser.
|
||||
|
||||
@param n The row number
|
||||
@return a tuple (list-of-strings, icon-id, row-attributes)
|
||||
"""
|
||||
pass
|
||||
|
||||
def get_chooser_data(title: str, n: int) -> List[str]:
|
||||
"""
|
||||
Get the text corresponding to the index N in the chooser data.
|
||||
Use -1 to get the header.
|
||||
|
||||
@param title The chooser title
|
||||
@return a list of strings, or None
|
||||
"""
|
||||
pass
|
||||
|
||||
def get_registered_actions() -> List[str]:
|
||||
"""
|
||||
Get a list with the names of all currently-registered actions.
|
||||
|
||||
@return the list of action names
|
||||
"""
|
||||
pass
|
||||
|
||||
class jobj_wrapper_t(object):
|
||||
def get_dict(self) -> dict:
|
||||
"""
|
||||
Retrieve the contents of this object, as a dict
|
||||
|
||||
@return a dict containing all kvp's in this object
|
||||
"""
|
||||
pass
|
||||
|
||||
class place_t(object):
|
||||
def generate(self, ud, maxsize: int) -> Tuple[List[str], int, int, int]:
|
||||
"""
|
||||
Generate text lines for the current location.
|
||||
|
||||
@param ud The user data object
|
||||
@param maxsize The maximum number of lines to generate
|
||||
@return a tuple (lines-of-text, default-line-number, prefix-color, background-color)
|
||||
"""
|
||||
pass
|
||||
|
||||
def restore_database_snapshot(snapshot, callback, userdata) -> bool:
|
||||
"""
|
||||
Restore a database snapshot.
|
||||
|
||||
Note: This call is asynchronous. When it is completed, the callback will be triggered.
|
||||
|
||||
@param snapshot the snapshot object
|
||||
@param callback a callback function
|
||||
@param userdata payload to pass to the callback
|
||||
@return success
|
||||
"""
|
||||
pass
|
||||
|
||||
def take_database_snapshot(snapshot) -> Tuple[bool, str]:
|
||||
"""
|
||||
Take a database snapshot.
|
||||
|
||||
@param snapshot the snapshot object
|
||||
@return a tuple (success, error-message)
|
||||
"""
|
||||
pass
|
||||
|
||||
def get_custom_viewer_location(*args) -> bool:
|
||||
"""
|
||||
Get information about the current location in a listing
|
||||
|
||||
This function has the following signatures:
|
||||
|
||||
1. get_custom_viewer_location(out_entry: ida_moves.lochist_entry_t, widget: TWidget, mouse: bool=False) -> bool
|
||||
2. get_custom_viewer_location(out_entry: ida_kernwin.listing_location_t, widget: TWidget, flags: int=0) -> bool
|
||||
|
||||
The 2nd form is a superset of the 1st, and retrieves
|
||||
the text (and tags) of the text.
|
||||
"""
|
||||
pass
|
||||
@@ -0,0 +1,15 @@
|
||||
|
||||
def generate_disassembly(ea, max_lines, as_stack, notags):
|
||||
"""
|
||||
Generate disassembly lines (many lines) and put them into a buffer
|
||||
|
||||
@param ea: address to generate disassembly for
|
||||
@param max_lines: how many lines max to generate
|
||||
@param as_stack: Display undefined items as 2/4/8 bytes
|
||||
@return:
|
||||
- None on failure
|
||||
- tuple(most_important_line_number, list(lines)) : Returns a tuple containing
|
||||
the most important line number and a list of generated lines
|
||||
"""
|
||||
pass
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
|
||||
def mem2base(mem, ea, fpos):
|
||||
"""
|
||||
Load database from the memory.
|
||||
|
||||
@param mem: the buffer
|
||||
@param ea: start linear addresses
|
||||
@param fpos: position in the input file the data is taken from.
|
||||
if == -1, then no file position correspond to the data.
|
||||
@return:
|
||||
- Returns zero if the passed buffer was not a string
|
||||
- Otherwise 1 is returned
|
||||
"""
|
||||
pass
|
||||
|
||||
def load_plugin(name):
|
||||
"""
|
||||
Loads a plugin
|
||||
|
||||
@param name: short plugin name without path and extension,
|
||||
or absolute path to the file name
|
||||
@return:
|
||||
- None if plugin could not be loaded
|
||||
- An opaque object representing the loaded plugin
|
||||
"""
|
||||
pass
|
||||
|
||||
def run_plugin(plg, arg):
|
||||
"""
|
||||
Runs a plugin
|
||||
|
||||
@param plg: A plugin object (returned by load_plugin())
|
||||
@param arg: the code to pass to the plugin's "run()" function
|
||||
@return: Boolean
|
||||
"""
|
||||
pass
|
||||
@@ -0,0 +1,9 @@
|
||||
|
||||
def split_metadata(metadata: bytes) -> dict:
|
||||
"""
|
||||
Split the metadata blob into a set of KVP's
|
||||
|
||||
@param metadata a metadata blob
|
||||
@return a set of KVP's
|
||||
"""
|
||||
pass
|
||||
@@ -0,0 +1,21 @@
|
||||
|
||||
def get_import_module_name(mod_index):
|
||||
"""
|
||||
Returns the name of an imported module given its index
|
||||
|
||||
@param mod_index: the module index
|
||||
@return: None or the module name
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
def enum_import_names(mod_index, callback):
|
||||
"""
|
||||
Enumerate imports from a specific module.
|
||||
Please refer to list_imports.py example.
|
||||
|
||||
@param mod_index: The module index
|
||||
@param callback: A callable object that will be invoked with an ea, name (could be None) and ordinal.
|
||||
@return: 1-finished ok, -1 on error, otherwise callback return value (<=0)
|
||||
"""
|
||||
pass
|
||||
@@ -0,0 +1,22 @@
|
||||
|
||||
class netnode(object):
|
||||
def getblob(self, start, tag) -> Union[bytes, None]:
|
||||
"""
|
||||
Get a blob from a netnode.
|
||||
|
||||
@param start the index where the blob starts (it may span on multiple indexes)
|
||||
@param tag the netnode tag
|
||||
@return a blob, or None
|
||||
"""
|
||||
pass
|
||||
|
||||
def getclob(self, start, tag) -> Union[str, None]:
|
||||
"""
|
||||
Get a large amount of text from a netnode.
|
||||
|
||||
@param start the index where the clob starts (it may span on multiple indexes)
|
||||
@param tag the netnode tag
|
||||
@return a clob, or None
|
||||
"""
|
||||
pass
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
|
||||
def str2user(str):
|
||||
"""
|
||||
Insert C-style escape characters to string
|
||||
|
||||
@param str: the input string
|
||||
@return: new string with escape characters inserted, or None
|
||||
"""
|
||||
pass
|
||||
@@ -0,0 +1,15 @@
|
||||
|
||||
def get_defsr(s, reg):
|
||||
"""
|
||||
Deprecated, use instead:
|
||||
value = s.defsr[reg]
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
def set_defsr(s, reg, value):
|
||||
"""
|
||||
Deprecated, use instead:
|
||||
s.defsr[reg] = value
|
||||
"""
|
||||
pass
|
||||
@@ -0,0 +1,559 @@
|
||||
|
||||
def calc_type_size(til: til_t, type: bytes):
|
||||
"""
|
||||
Returns the size of a type
|
||||
@param til: Type info library. 'None' can be passed.
|
||||
@param type: serialized type byte string
|
||||
@return:
|
||||
- None on failure
|
||||
- The size of the type
|
||||
"""
|
||||
pass
|
||||
|
||||
def apply_type(til: til_t, type: bytes, fields: bytes, ea: ida_idaapi.ea_t, flags: int) -> bool:
|
||||
"""
|
||||
Apply the specified type to the address
|
||||
|
||||
@param til: Type info library. 'None' can be used.
|
||||
@param type: type string
|
||||
@param fields: fields string (may be empty or None)
|
||||
@param ea: the address of the object
|
||||
@param flags: combination of TINFO_... constants or 0
|
||||
@return: Boolean
|
||||
"""
|
||||
pass
|
||||
|
||||
def get_arg_addrs(caller: ida_idaapi.ea_t):
|
||||
"""
|
||||
Retrieve addresses of argument initialization instructions
|
||||
|
||||
@param caller: the address of the call instruction
|
||||
@return: list of instruction addresses
|
||||
"""
|
||||
pass
|
||||
|
||||
def unpack_object_from_idb(til: til_t, type: bytes, fields: bytes, ea: ida_idaapi.ea_t, pio_flags: int = 0):
|
||||
"""
|
||||
Unpacks from the database at 'ea' to an object.
|
||||
Please refer to unpack_object_from_bv()
|
||||
"""
|
||||
pass
|
||||
|
||||
def unpack_object_from_bv(til: til_t, type: bytes, fields: bytes, bytes, pio_flags: int = 0):
|
||||
"""
|
||||
Unpacks a buffer into an object.
|
||||
Returns the error_t returned by idaapi.pack_object_to_idb
|
||||
|
||||
@param til: Type library. 'None' can be passed.
|
||||
@param type: type string
|
||||
@param fields: fields string (may be empty or None)
|
||||
@param bytes: the bytes to unpack
|
||||
@param pio_flags: flags used while unpacking
|
||||
@return:
|
||||
- tuple(0, err) on failure
|
||||
- tuple(1, obj) on success
|
||||
"""
|
||||
pass
|
||||
|
||||
def pack_object_to_idb(obj, til: til_t, type: bytes, fields: bytes, ea: ida_idaapi.ea_t, pio_flags: int = 0):
|
||||
"""
|
||||
Write a typed object to the database.
|
||||
Raises an exception if wrong parameters were passed or conversion fails
|
||||
Returns the error_t returned by idaapi.pack_object_to_idb
|
||||
|
||||
@param til: Type library. 'None' can be passed.
|
||||
@param type: type string
|
||||
@param fields: fields string (may be empty or None)
|
||||
@param ea: ea to be used while packing
|
||||
@param pio_flags: flags used while unpacking
|
||||
"""
|
||||
pass
|
||||
|
||||
def pack_object_to_bv(obj, til: til_t, type: bytes, fields: bytes, base_ea: ida_idaapi.ea_t, pio_flags: int = 0):
|
||||
"""
|
||||
Packs a typed object to a string
|
||||
|
||||
@param til: Type library. 'None' can be passed.
|
||||
@param type: type string
|
||||
@param fields: fields string (may be empty or None)
|
||||
@param base_ea: base ea used to relocate the pointers in the packed object
|
||||
@param pio_flags: flags used while unpacking
|
||||
@return:
|
||||
tuple(0, err_code) on failure
|
||||
tuple(1, packed_buf) on success
|
||||
"""
|
||||
pass
|
||||
|
||||
def get_named_type(til: til_t, name: str, ntf_flags: int):
|
||||
"""
|
||||
Get a type data by its name.
|
||||
|
||||
@param til: Type library
|
||||
@param name: the type name
|
||||
@param ntf_flags: a combination of NTF_* constants
|
||||
@return:
|
||||
None on failure
|
||||
tuple(code, type_str, fields_str, cmt, field_cmts, sclass, value) on success
|
||||
"""
|
||||
pass
|
||||
|
||||
class tinfo_t(object):
|
||||
def __init__(self, *args, ordinal=None, name=None, tid=None, til=None):
|
||||
"""
|
||||
Create a type object with the provided argumens.
|
||||
|
||||
This constructor has the following signatures:
|
||||
|
||||
1. tinfo_t(decl_type: type_t)
|
||||
2. tinfo_t(decl: str, til: til_t = None, pt_flags: int = 0)
|
||||
|
||||
The latter form will create the type object by parsing the type declaration
|
||||
|
||||
Alternatively, you can use a form accepting the following keyword arguments:
|
||||
|
||||
* ordinal: int
|
||||
* name: str
|
||||
* tid: int
|
||||
* til: til_t=None # `None` means `get_idati()`
|
||||
|
||||
E.g.,
|
||||
|
||||
* tinfo_t(ordinal=3)
|
||||
* tinfo_t(ordinal=10, til=get_idati())
|
||||
* tinfo_t(name="mytype_t")
|
||||
* tinfo_t(name="thattype_t", til=my_other_til)
|
||||
* tinfo_t(tid=ida_nalt.get_strid(some_address))
|
||||
|
||||
The constructor may raise an exception if data was invalid, or if parsing failed.
|
||||
|
||||
@param decl_type A simple type
|
||||
@param decl A valid C declaration
|
||||
@param til A type library, or `None` to use the (`get_idati()`) default
|
||||
@param ordinal An ordinal in the type library
|
||||
@param name A valid type name
|
||||
@param pt_flags Parsing flags
|
||||
"""
|
||||
pass
|
||||
|
||||
def get_udm(self, *args) -> Union[Tuple[int, 'udm_t'], Tuple[None, None]]:
|
||||
"""
|
||||
Retrieve a structure/union member with either the specified name
|
||||
or the specified index, in the specified tinfo_t object.
|
||||
|
||||
This function has the following signatures:
|
||||
|
||||
1. get_udm(index: int)
|
||||
2. get_udm(name: str)
|
||||
|
||||
@param index a member index (1st form)
|
||||
@param name a member name (2nd form)
|
||||
@return a tuple (int, udm_t), or (-1, None) if member not found
|
||||
"""
|
||||
pass
|
||||
|
||||
def get_udm_by_offset(self, offset: int):
|
||||
"""
|
||||
Retrieve a structure/union member with the specified offset,
|
||||
in the specified tinfo_t object.
|
||||
|
||||
@param offset the member offset
|
||||
@return a tuple (int, udm_t), or (-1, None) if member not found
|
||||
"""
|
||||
pass
|
||||
|
||||
def add_udm(self, *args):
|
||||
"""
|
||||
Add a member to the current structure/union.
|
||||
|
||||
When creating a new structure/union from scratch, you might
|
||||
want to first call `create_udt()`
|
||||
|
||||
This method has the following signatures:
|
||||
|
||||
1. add_udm(udm: udm_t, etf_flags: int = 0, times: int = 1, idx: int = -1)
|
||||
2. add_udm(name: str, type: type_t | tinfo_t | str, offset: int = 0, etf_flags: int = 0, times: int = 1, idx: int = -1)
|
||||
|
||||
In the 2nd form, the 'type' descriptor, can be one of:
|
||||
|
||||
* type_t: if the type is simple (integral/floating/bool). E.g., `BTF_INT`
|
||||
* tinfo_t: can handle more complex types (structures, pointers, arrays, ...)
|
||||
* str: a C type declaration
|
||||
|
||||
If an input argument is incorrect, the constructor may raise an exception
|
||||
|
||||
@param udm The member, fully initialized (1st form)
|
||||
@param name Member name - must not be empty
|
||||
@param type Member type
|
||||
@param offset the member offset in bits. It is the caller's responsibility
|
||||
to specify correct offsets.
|
||||
@param etf_flags an OR'ed combination of ETF_ flags
|
||||
@param times how many times to add the new member
|
||||
@param idx the index in the udm array where the new udm should be placed.
|
||||
If the specified index cannot be honored because it would spoil
|
||||
the udm sorting order, it is silently ignored.
|
||||
"""
|
||||
pass
|
||||
|
||||
def get_edm(self, *args) -> Tuple[int, 'edm_t']:
|
||||
"""
|
||||
Retrieve an enumerator with either the specified name
|
||||
or the specified index, in the specified tinfo_t object.
|
||||
|
||||
This function has the following signatures:
|
||||
|
||||
1. get_edm(index: int)
|
||||
2. get_edm(name: str)
|
||||
|
||||
@param index an enumerator index (1st form).
|
||||
@param name an enumerator name (2nd form).
|
||||
@return a tuple (int, edm_t), or (-1, None) if member not found
|
||||
"""
|
||||
pass
|
||||
|
||||
def get_edm_by_value(self, value: int, bmask: int = DEFMASK64, serial: int = 0) -> Tuple[int, 'edm_t']:
|
||||
"""
|
||||
Retrieve an enumerator with the specified value,
|
||||
in the specified tinfo_t object.
|
||||
|
||||
@param value the enumerator value
|
||||
@return a tuple (int, edm_t), or (-1, None) if member not found
|
||||
"""
|
||||
pass
|
||||
|
||||
def add_edm(self, *args):
|
||||
"""
|
||||
Add an enumerator to the current enumeration.
|
||||
|
||||
When creating a new enumeration from scratch, you might
|
||||
want to first call `create_enum()`
|
||||
|
||||
This method has the following signatures:
|
||||
|
||||
1. add_edm(edm: edm_t, bmask: int = -1, etf_flags: int = 0, idx: int = -1)
|
||||
2. add_edm(name: str, value: int, bmask: int = -1, etf_flags: int = 0, idx: int = -1)
|
||||
|
||||
If an input argument is incorrect, the constructor may raise an exception
|
||||
|
||||
@param edm The member, fully initialized (1st form)
|
||||
@param name Enumerator name - must not be empty
|
||||
@param value Enumerator value
|
||||
@param bmask A bitmask to which the enumerator belongs
|
||||
@param etf_flags an OR'ed combination of ETF_ flags
|
||||
@param idx the index in the edm array where the new udm should be placed.
|
||||
If the specified index cannot be honored because it would spoil
|
||||
the edm sorting order, it is silently ignored.
|
||||
"""
|
||||
pass
|
||||
|
||||
def del_edm(self, *args):
|
||||
"""
|
||||
Delete an enumerator with the specified name
|
||||
or the specified index, in the specified tinfo_t object.
|
||||
|
||||
This method has the following signatures:
|
||||
|
||||
1. del_edm(name: str) -> int
|
||||
2. del_edm(index: int) -> int
|
||||
|
||||
@param name an enumerator name (1st form)
|
||||
@param index an enumerator index (2nd form)
|
||||
@return TERR_OK in case of success, or another TERR_* value in case of error
|
||||
"""
|
||||
pass
|
||||
|
||||
def del_edm_by_value(self, value: int, etf_flags: int=0, bmask: int = DEFMASK64, serial: int = 0):
|
||||
"""
|
||||
Delete an enumerator with the specified value,
|
||||
in the specified tinfo_t object.
|
||||
|
||||
@param value the enumerator value
|
||||
@return TERR_OK in case of success, or another TERR_* value in case of error
|
||||
"""
|
||||
pass
|
||||
|
||||
def iter_struct(self):
|
||||
"""
|
||||
Iterate on the members composing this structure.
|
||||
|
||||
Example:
|
||||
|
||||
til = ida_typeinf.get_idati()
|
||||
tif = til.get_named_type("my_struc")
|
||||
for udm in tif.iter_struct():
|
||||
print(f"{udm.name} at bit offset {udm.offset}")
|
||||
|
||||
Will raise an exception if this type is not a structure.
|
||||
|
||||
@return a udm_t-producing generator
|
||||
"""
|
||||
pass
|
||||
|
||||
def iter_union(self):
|
||||
"""
|
||||
Iterate on the members composing this union.
|
||||
|
||||
Example:
|
||||
|
||||
til = ida_typeinf.get_idati()
|
||||
tif = til.get_named_type("my_union")
|
||||
for udm in tif.iter_union():
|
||||
print(f"{udm.name}, with type {udm.type}")
|
||||
|
||||
Will raise an exception if this type is not a union.
|
||||
|
||||
@return a udm_t-producing generator
|
||||
"""
|
||||
pass
|
||||
|
||||
def iter_udt(self):
|
||||
"""
|
||||
Iterate on the members composing this structure, or union.
|
||||
|
||||
Example:
|
||||
|
||||
til = ida_typeinf.get_idati()
|
||||
tif = til.get_named_type("my_type")
|
||||
for udm in tif.iter_udt():
|
||||
print(f"{udm.name} at bit offset {udm.offset} with type {udm.type}")
|
||||
|
||||
Will raise an exception if this type is not a structure, or union
|
||||
|
||||
@return a udm_t-producing generator
|
||||
"""
|
||||
pass
|
||||
|
||||
def iter_enum(self):
|
||||
"""
|
||||
Iterate on the members composing this enumeration.
|
||||
|
||||
Example:
|
||||
|
||||
til = ida_typeinf.get_idati()
|
||||
tif = til.get_named_type("my_enum")
|
||||
for edm in tif.iter_enum():
|
||||
print(f"{edm.name} = {edm.value}")
|
||||
|
||||
Will raise an exception if this type is not an enumeration
|
||||
|
||||
@return a edm_t-producing generator
|
||||
"""
|
||||
pass
|
||||
|
||||
def iter_func(self):
|
||||
"""
|
||||
Iterate on the arguments contained in this function prototype
|
||||
|
||||
Example:
|
||||
|
||||
address = ...
|
||||
func = ida_funcs.get_func(address)
|
||||
func_type = func.prototype
|
||||
for arg in func_type.iter_func():
|
||||
print(f"{arg.name}, of type {arg.type}")
|
||||
|
||||
Will raise an exception if this type is not a function
|
||||
|
||||
@return a funcarg_t-producing generator
|
||||
"""
|
||||
pass
|
||||
|
||||
class edm_t(object):
|
||||
def __init__(self, *args):
|
||||
"""
|
||||
Create an enumerator, with the specified name and value
|
||||
|
||||
This constructor has the following signatures:
|
||||
|
||||
1. edm_t(edm: edm_t)
|
||||
2. edm_t(name: str, value: int, cmt: str=None)
|
||||
|
||||
@param name Enumerator name. Must not be empty (1st form)
|
||||
@param value Enumerator value (1st form)
|
||||
@param cmt Enumerator repeatable comment. May be empty (1st form)
|
||||
@param edm An enum member to copy
|
||||
"""
|
||||
pass
|
||||
|
||||
class udm_t(object):
|
||||
def __init__(self, *args):
|
||||
"""
|
||||
Create a structure/union member, with the specified name and type.
|
||||
|
||||
This constructor has the following signatures:
|
||||
|
||||
1. udm_t(udm: udm_t)
|
||||
2. udm_t(name: str, type, offset: int)
|
||||
|
||||
The 'type' descriptor, can be one of:
|
||||
|
||||
* type_t: if the type is simple (integral/floating/bool). E.g., `BTF_INT`
|
||||
* tinfo_t: can handle more complex types (structures, pointers, arrays, ...)
|
||||
* str: a C type declaration
|
||||
|
||||
If an input argument is incorrect, the constructor may raise an exception
|
||||
The size will be computed automatically.
|
||||
|
||||
@param udm a source udm_t
|
||||
@param name a valid member name. Must not be empty.
|
||||
@param type the member type
|
||||
@param offset the member offset in bits. It is the caller's responsibility
|
||||
to specify correct offsets.
|
||||
"""
|
||||
pass
|
||||
|
||||
def copy(self, src):
|
||||
"""
|
||||
Copy the src, into this instance
|
||||
|
||||
@param src The source udm_t
|
||||
"""
|
||||
pass
|
||||
|
||||
class udt_type_data_t(object):
|
||||
def get_best_fit_member(self, disp):
|
||||
"""
|
||||
Get the member that is most likely referenced by the specified offset.
|
||||
|
||||
@param disp the byte offset
|
||||
@return a tuple (int, udm_t), or (-1, None) if member not found
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class funcarg_t(object):
|
||||
def __init__(self, *args):
|
||||
"""
|
||||
Create a function argument, with the specified name and type.
|
||||
|
||||
This constructor has the following signatures:
|
||||
|
||||
1. funcarg_t(name: str, type, argloc: argloc_t)
|
||||
2. funcarg_t(funcarg: funcarg_t)
|
||||
|
||||
In the 1st form, the 'type' descriptor, can be one of:
|
||||
|
||||
* type_t: if the type is simple (integral/floating/bool). E.g., `BTF_INT`
|
||||
* tinfo_t: can handle more complex types (structures, pointers, arrays, ...)
|
||||
* str: a C type declaration
|
||||
|
||||
If an input argument is incorrect, the constructor may raise an exception
|
||||
|
||||
@param name a valid argument name. May not be empty (1st form).
|
||||
@param type the member type (1st form).
|
||||
@param argloc the argument location. Can be empty (1st form).
|
||||
@param funcarg a funcarg_t to copy
|
||||
"""
|
||||
pass
|
||||
|
||||
class til_t(object):
|
||||
def import_type(self, src):
|
||||
"""
|
||||
Import a type (and all its dependencies) into this type info library.
|
||||
|
||||
@param src The type to import
|
||||
@return the imported copy, or None
|
||||
"""
|
||||
|
||||
def numbered_types(self):
|
||||
"""
|
||||
Returns a generator over the numbered types contained in this
|
||||
type library.
|
||||
|
||||
Every iteration returns a fresh new tinfo_t object
|
||||
|
||||
@return a tinfo_t-producing generator
|
||||
"""
|
||||
pass
|
||||
|
||||
def named_types(self):
|
||||
"""
|
||||
Returns a generator over the named types contained in this
|
||||
type library.
|
||||
|
||||
Every iteration returns a fresh new tinfo_t object
|
||||
|
||||
@return a tinfo_t-producing generator
|
||||
"""
|
||||
pass
|
||||
|
||||
def get_named_type(self, name):
|
||||
"""
|
||||
Retrieves a tinfo_t representing the named type in this type library.
|
||||
|
||||
@param name a type name
|
||||
@return a new tinfo_t object, or None if not found
|
||||
"""
|
||||
pass
|
||||
|
||||
def get_numbered_type(self, ordinal):
|
||||
"""
|
||||
Retrieves a tinfo_t representing the numbered type in this type library.
|
||||
|
||||
@param ordinal a type ordinal
|
||||
@return a new tinfo_t object, or None if not found
|
||||
"""
|
||||
pass
|
||||
|
||||
def get_named_type64(til: til_t, name: str, ntf_flags: int=0) -> Union[Tuple[int, bytes, bytes, str, str, int, int], None]:
|
||||
"""
|
||||
Get a named type from a type library.
|
||||
|
||||
Please use til_t.get_named_type instead.
|
||||
"""
|
||||
pass
|
||||
|
||||
def get_numbered_type(til: til_t, ordinal: int) -> Union[Tuple[bytes, bytes, str, str, int], None]:
|
||||
"""
|
||||
Get a type from a type library, by its ordinal
|
||||
|
||||
Please use til_t.get_numbered_type instead.
|
||||
"""
|
||||
pass
|
||||
|
||||
def idc_get_local_type_raw(ordinal) -> Tuple[bytes, bytes]:
|
||||
"""
|
||||
"""
|
||||
pass
|
||||
|
||||
def idc_parse_decl(til: til_t, decl: str, flags: int) -> Tuple[str, bytes, bytes]:
|
||||
"""
|
||||
"""
|
||||
pass
|
||||
|
||||
def idc_print_type(type: bytes, fields: bytes, name: str, flags: int) -> str:
|
||||
"""
|
||||
"""
|
||||
pass
|
||||
|
||||
def print_decls(printer: text_sink_t, til: til_t, ordinals: List[int], flags: int) -> int:
|
||||
"""
|
||||
Print types (and possibly their dependencies) in a format suitable for using in
|
||||
a header file. This is the reverse parse_decls().
|
||||
|
||||
@param printer a handler for printing text
|
||||
@param til the type library holding the ordinals
|
||||
@param ordinals a list of ordinals corresponding to the types to print
|
||||
@param flags a combination of PDF_ constants
|
||||
@return
|
||||
>0: the number of types exported
|
||||
0: an error occurred
|
||||
<0: the negated number of types exported. There were minor errors and
|
||||
the resulting output might not be compilable.
|
||||
"""
|
||||
pass
|
||||
|
||||
def remove_tinfo_pointer(tif: tinfo_t, name: str, til: til_t) -> Tuple[bool, str]:
|
||||
"""
|
||||
Remove pointer of a type. (i.e. convert "char *" into "char"). Optionally remove
|
||||
the "lp" (or similar) prefix of the input name. If the input type is not a
|
||||
pointer, then fail.
|
||||
|
||||
@param tif the type info
|
||||
@param name the name of the type to "unpointerify"
|
||||
@param til the type library
|
||||
@return a tuple (success, new-name)
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
|
||||
def decode_preceding_insn(out: insn_t, ea: ida_idaapi.ea_t) -> Tuple[ida_idaapi.ea_t, bool]:
|
||||
"""
|
||||
Decodes the preceding instruction.
|
||||
|
||||
@param out: instruction storage
|
||||
@param ea: current ea
|
||||
@return: tuple(preceeding_ea or BADADDR, farref = Boolean)
|
||||
"""
|
||||
pass
|
||||
|
||||
def construct_macro(*args):
|
||||
"""
|
||||
See ua.hpp's construct_macro().
|
||||
|
||||
This function has the following signatures
|
||||
|
||||
1. construct_macro(insn: insn_t, enable: bool, build_macro: callable) -> bool
|
||||
2. construct_macro(constuctor: macro_constructor_t, insn: insn_t, enable: bool) -> bool
|
||||
|
||||
@param insn: the instruction to build the macro for
|
||||
@param enable: enable macro generation
|
||||
@param build_macro: a callable with 2 arguments: an insn_t, and
|
||||
whether it is ok to consider the next instruction
|
||||
for the macro
|
||||
@param constructor: a macro_constructor_t implementation
|
||||
@return: success
|
||||
"""
|
||||
pass
|
||||
@@ -0,0 +1,47 @@
|
||||
|
||||
def create_switch_xrefs(ea, si):
|
||||
"""
|
||||
This function creates xrefs from the indirect jump.
|
||||
|
||||
Usually there is no need to call this function directly because the kernel
|
||||
will call it for switch tables
|
||||
|
||||
Note: Custom switch information are not supported yet.
|
||||
|
||||
@param ea: address of the 'indirect jump' instruction
|
||||
@param si: switch information
|
||||
|
||||
@return: Boolean
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
def calc_switch_cases(ea, si):
|
||||
"""
|
||||
Get information about a switch's cases.
|
||||
|
||||
The returned information can be used as follows:
|
||||
|
||||
for idx in range(len(results.cases)):
|
||||
cur_case = results.cases[idx]
|
||||
for cidx in range(len(cur_case)):
|
||||
print("case: %d" % cur_case[cidx])
|
||||
print(" goto 0x%x" % results.targets[idx])
|
||||
|
||||
@param ea: address of the 'indirect jump' instruction
|
||||
@param si: switch information
|
||||
|
||||
@return: a structure with 2 members: 'cases', and 'targets'.
|
||||
"""
|
||||
pass
|
||||
|
||||
def create_switch_table(ea, si):
|
||||
"""
|
||||
Create switch table from the switch information
|
||||
|
||||
@param ea: address of the 'indirect jump' instruction
|
||||
@param si: switch information
|
||||
|
||||
@return: Boolean
|
||||
"""
|
||||
pass
|
||||
Executable
+27
@@ -0,0 +1,27 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
#ensure out folder exists
|
||||
mkdir -p $3
|
||||
|
||||
IN_FOLDER=$(realpath $2)
|
||||
OUT_FOLDER=$(realpath $3)
|
||||
|
||||
ARTIFACTS=$1
|
||||
|
||||
echo "[${ARTIFACTS}] GOING to COPY FILES from ${IN_FOLDER} to ${OUT_FOLDER}"
|
||||
|
||||
cd ${OUT_FOLDER}
|
||||
|
||||
echo "[${ARTIFACTS}] make the out folder p4 edit"
|
||||
p4 edit ...
|
||||
|
||||
echo "[${ARTIFACTS}] copy new files"
|
||||
rm -rf *
|
||||
cp -R ${IN_FOLDER}/* .
|
||||
|
||||
echo "[${ARTIFACTS}] adding files to p4"
|
||||
p4 add ...
|
||||
p4 revert -a ...
|
||||
|
||||
Executable
+138
@@ -0,0 +1,138 @@
|
||||
"""
|
||||
summary: Add missing inodes in dirtree structure in "/lost+found" directory
|
||||
|
||||
description:
|
||||
How to collects inodes for various dirtrees ('Local Types', 'Names',
|
||||
'Functions', 'Imports', 'Address bookmark' and 'Breakpoints') in both
|
||||
the dirtree structure and the database.
|
||||
Create a directory an links inodes to them in the dirtree structure
|
||||
You cannot add all inodes to the "/lost+found" directory because inodes
|
||||
can be at various places in a dirtree structure.
|
||||
The early dirtree implementations were not perfect and may have missed to
|
||||
add some inodes in the tree structure, this script corrects this issue.
|
||||
|
||||
keywords: dirtree, recovery
|
||||
"""
|
||||
|
||||
import ida_dirtree
|
||||
from ida_dirtree import dirtree_t
|
||||
import ida_typeinf
|
||||
import ida_funcs
|
||||
import ida_name
|
||||
import ida_dbg
|
||||
import ida_nalt
|
||||
import ida_kernwin
|
||||
import ida_moves
|
||||
|
||||
|
||||
def get_ltypes_inode(n):
|
||||
inode = n + 1
|
||||
name = ida_typeinf.get_numbered_type_name(None, inode)
|
||||
if name is None:
|
||||
# if the name is None, we have a #deleted type,
|
||||
# present in flat mode but not in fulltree mode
|
||||
return True, None
|
||||
else:
|
||||
return False, inode
|
||||
|
||||
|
||||
def get_func_inode(n):
|
||||
inode = ida_funcs.getn_func(n).start_ea
|
||||
return False, inode
|
||||
|
||||
|
||||
def get_name_inode(n):
|
||||
inode = ida_name.get_nlist_ea(n)
|
||||
if inode is None:
|
||||
print(hex(inode))
|
||||
return False, inode
|
||||
|
||||
|
||||
list_inodes_in_idb = []
|
||||
def get_import_list():
|
||||
def imp_cb(ea, name, ordinal):
|
||||
list_inodes_in_idb.append(ea)
|
||||
return True
|
||||
nimps = ida_nalt.get_import_module_qty()
|
||||
for i in range(nimps):
|
||||
ida_nalt.enum_import_names(i, imp_cb)
|
||||
list_inodes_in_idb.sort()
|
||||
return len(list_inodes_in_idb)
|
||||
|
||||
|
||||
def get_nth_inode_in_idb(n):
|
||||
return False, list_inodes_in_idb[n]
|
||||
|
||||
|
||||
def get_idaplace_list_inodes_in_idb():
|
||||
id = ida_kernwin.get_place_class_id("idaplace_t")
|
||||
p = ida_kernwin.get_place_class_template(id)
|
||||
r = ida_moves.renderer_info_t()
|
||||
l = ida_moves.lochist_entry_t(p, r)
|
||||
for idx in range(ida_moves.bookmarks_t.size(l, None)):
|
||||
ida_moves.bookmarks_t.get(l, idx, None)
|
||||
idaloc = ida_kernwin.place_t.as_idaplace_t(l.place())
|
||||
list_inodes_in_idb.append(idaloc.ea)
|
||||
list_inodes_in_idb.sort()
|
||||
return len(list_inodes_in_idb)
|
||||
|
||||
|
||||
def get_bpt_inode(n):
|
||||
bpt = ida_dbg.bpt_t()
|
||||
if not ida_dbg.getn_bpt(n, bpt):
|
||||
return True, None
|
||||
return False, bpt.bptid
|
||||
|
||||
|
||||
class dt_collect_inode_t(ida_dirtree.dirtree_visitor_t):
|
||||
def __init__(self):
|
||||
ida_dirtree.dirtree_visitor_t.__init__(self)
|
||||
self.list_inodes_in_dirtree = []
|
||||
def visit(self, c, de):
|
||||
if dirtree_t.isfile(de):
|
||||
self.list_inodes_in_dirtree.append(de.idx)
|
||||
return 0
|
||||
|
||||
|
||||
std_recovery_data = [
|
||||
( ida_dirtree.DIRTREE_LOCAL_TYPES, ida_typeinf.get_ordinal_count, get_ltypes_inode, "Local Types" ),
|
||||
( ida_dirtree.DIRTREE_FUNCS, ida_funcs.get_func_qty, get_func_inode, "Local Types" ),
|
||||
( ida_dirtree.DIRTREE_NAMES, ida_name.get_nlist_size, get_name_inode, "Names" ),
|
||||
( ida_dirtree.DIRTREE_IMPORTS, get_import_list, get_nth_inode_in_idb, "Imports" ),
|
||||
( ida_dirtree.DIRTREE_IDAPLACE_BOOKMARKS, get_idaplace_list_inodes_in_idb, get_nth_inode_in_idb, "Address bookmarks" ),
|
||||
( ida_dirtree.DIRTREE_BPTS, ida_dbg.get_bpt_qty, get_bpt_inode, "Breakpoints" ),
|
||||
]
|
||||
|
||||
|
||||
for dt_id, get_count_and_maybe_list_inodes_in_idb, get_inode, title in std_recovery_data:
|
||||
dt = ida_dirtree.get_std_dirtree(dt_id)
|
||||
print("### Dirtree ", title)
|
||||
list_inodes_in_idb = []
|
||||
collector = dt_collect_inode_t()
|
||||
dt.traverse(collector)
|
||||
set_inodes_in_dirtree = set(collector.list_inodes_in_dirtree)
|
||||
nb_inodes = get_count_and_maybe_list_inodes_in_idb()
|
||||
nb_not_list = 0
|
||||
nb_list = len(set_inodes_in_dirtree)
|
||||
print("Number of unique inodes in the idb: %d\nNumber of unique inodes in fulltree mode: %d"%(nb_inodes, nb_list))
|
||||
|
||||
if nb_list < nb_inodes:
|
||||
err = dt.mkdir("/lost+found")
|
||||
if err != ida_dirtree.DTE_OK:
|
||||
print(dt.errstr(err))
|
||||
err = dt.chdir("/lost+found")
|
||||
if err != ida_dirtree.DTE_OK:
|
||||
print(dt.errstr(err))
|
||||
for n in range(nb_inodes):
|
||||
inc, inode = get_inode(n)
|
||||
if inode is not None:
|
||||
if inode not in set_inodes_in_dirtree:
|
||||
err = dt.link(inode)
|
||||
if err != ida_dirtree.DTE_OK:
|
||||
print("Failed to link inode ", hex(inode), " ", dt.errstr(err) )
|
||||
inc = True
|
||||
if inc:
|
||||
nb_not_list += 1
|
||||
if nb_inodes == nb_list + nb_not_list:
|
||||
break
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
"""This internal test is used to verify that pc_api tests won't swallow
|
||||
exceptions while using IDAPYTHON_EXAMPLE <path_to_script>"""
|
||||
|
||||
raise ImportError("Nasty exception at the script")
|
||||
@@ -18,6 +18,29 @@ with one or many examples, and those should be also put under test
|
||||
rather than if it consists of a bunch of IDAPython code our
|
||||
users will never see, and cannot be inspired from.)
|
||||
|
||||
### Best practices
|
||||
|
||||
* don't use `idc.py`: some of its operations are a bit too elusive
|
||||
* don't use `idaapi`: that "hides" the provenance of the
|
||||
function/type/item being used, and makes it that much harder to
|
||||
group ideas by module
|
||||
* don't `from <something> import <whatever>`: for the same reason
|
||||
* use double-quotes for all string literals, unless there's a good
|
||||
reason not to do so (e.g., the string literal contains some `"`
|
||||
characters, and `\`-escaping them would be inconvenient & make the
|
||||
code awkward to read).
|
||||
Double-quoted string literals let us grep more predictably & reliably.
|
||||
|
||||
## Example header
|
||||
|
||||
Every example must have a valid header, holding a one-liner `summary:`,
|
||||
as well as a description further explaining what the example is about.
|
||||
|
||||
Some notes:
|
||||
|
||||
* `summary:`: the one-liner must not end with a `.`
|
||||
* `summary:`: prefer the `list something...` form over the `listing something...`
|
||||
|
||||
## Helping our customers, teaching IDAPython in the process
|
||||
|
||||
In addition, when a customer asks for help on support@ (or the forums)
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
"""
|
||||
summary: triggering bits of code by pressing a shortcut (older version)
|
||||
|
||||
description:
|
||||
This is a somewhat ancient way of registering actions & binding
|
||||
shortcuts. It's still here for reference, but "fresher" alternatives
|
||||
should be preferred.
|
||||
|
||||
keywords: actions
|
||||
|
||||
see_also: actions, add_hotkey
|
||||
"""
|
||||
|
||||
import ida_expr
|
||||
import ida_kernwin
|
||||
|
||||
def say_hi():
|
||||
print("Hotkey activated!")
|
||||
|
||||
# IDA binds hotkeys to IDC functions so a trampoline IDC function must be created
|
||||
ida_expr.compile_idc_text('static key_2() { RunPythonStatement("say_hi()"); }')
|
||||
|
||||
# Add the hotkey
|
||||
ida_kernwin.add_idc_hotkey("2", 'key_2')
|
||||
|
||||
# Press 2 to activate foo()
|
||||
|
||||
# The hotkey can be removed with
|
||||
# ida_kernwin.del_idc_hotkey('2')
|
||||
|
||||
@@ -1,94 +0,0 @@
|
||||
"""
|
||||
summary: showcasing `ida_bytes.bin_search`
|
||||
|
||||
description:
|
||||
IDAPython's ida_bytes.bin_search function is pretty powerful,
|
||||
but can be tough to figure out at first. This example introduces
|
||||
|
||||
* `ida_bytes.bin_search`, and
|
||||
* `ida_bytes.parse_binpat_str`
|
||||
|
||||
in order to implement a simple replacement for the
|
||||
'Search > Sequence of bytes...' dialog, that lets users
|
||||
search for sequences of bytes that compose string literals
|
||||
in the binary file (either in the default 1-byte-per-char
|
||||
encoding, or as UTF-16.)
|
||||
"""
|
||||
|
||||
import ida_kernwin
|
||||
import ida_bytes
|
||||
import ida_ida
|
||||
import ida_idaapi
|
||||
import ida_nalt
|
||||
|
||||
class search_strlit_form_t(ida_kernwin.Form):
|
||||
def __init__(self):
|
||||
ida_kernwin.Form.__init__(
|
||||
self,
|
||||
r"""Please enter string literal
|
||||
|
||||
<Text: {Text}>
|
||||
<#UTF16-BE if file is big-endian, UTF16-LE otherwise#As UTF-16: {UTF16}>{Encoding}>
|
||||
""",
|
||||
{
|
||||
"Text" : ida_kernwin.Form.StringInput(),
|
||||
"Encoding" : ida_kernwin.Form.ChkGroupControl(("UTF16",)),
|
||||
})
|
||||
|
||||
class search_strlit_ah_t(ida_kernwin.action_handler_t):
|
||||
def __init__(self):
|
||||
ida_kernwin.action_handler_t.__init__(self)
|
||||
|
||||
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
|
||||
|
||||
def update(self, ctx):
|
||||
return ida_kernwin.AST_ENABLE_FOR_WIDGET \
|
||||
if ctx.widget_type == ida_kernwin.BWN_DISASM \
|
||||
else ida_kernwin.AST_DISABLE_FOR_WIDGET
|
||||
|
||||
|
||||
ACTION_NAME = "bin_search:search"
|
||||
ACTION_SHORTCUT = "Ctrl+Shift+S"
|
||||
|
||||
if ida_kernwin.register_action(
|
||||
ida_kernwin.action_desc_t(
|
||||
ACTION_NAME,
|
||||
"Search for string literal",
|
||||
search_strlit_ah_t(),
|
||||
ACTION_SHORTCUT)):
|
||||
print("Please use \"%s\" to search for string literals" % ACTION_SHORTCUT)
|
||||
+3
-1
@@ -1,5 +1,5 @@
|
||||
"""
|
||||
summary: executing code into the application being debugged (on Linux)
|
||||
summary: execute code into the application being debugged (on Linux)
|
||||
|
||||
description:
|
||||
Using the `ida_idd.Appcall` utility to execute code in
|
||||
@@ -18,6 +18,8 @@ description:
|
||||
* run this script
|
||||
|
||||
Note: the real body of code is in `simple_appcall_common.py`.
|
||||
|
||||
level: advanced
|
||||
"""
|
||||
|
||||
import os
|
||||
+4
-2
@@ -1,5 +1,5 @@
|
||||
"""
|
||||
summary: executing code into the application being debugged (on Windows)
|
||||
summary: execute code into the application being debugged (on Windows)
|
||||
|
||||
description:
|
||||
Using the `ida_idd.Appcall` utility to execute code in
|
||||
@@ -11,13 +11,15 @@ description:
|
||||
|
||||
To use this example:
|
||||
|
||||
* run `ida64` on test program `simple_appcall_win64.exe`, or
|
||||
* run `ida` on test program `simple_appcall_win64.exe`, or
|
||||
`ida` on test program `simple_appcall_win32.exe`, and wait for
|
||||
auto-analysis to finish
|
||||
* select the 'windows debugger' (either local, or remote)
|
||||
* run this script
|
||||
|
||||
Note: the real body of code is in `simple_appcall_common.py`.
|
||||
|
||||
level: advanced
|
||||
"""
|
||||
|
||||
import os
|
||||
+2
@@ -5,6 +5,8 @@ description:
|
||||
Start a debugging session, step through the first five
|
||||
instructions. Each instruction is disassembled after
|
||||
execution.
|
||||
|
||||
level: advanced
|
||||
"""
|
||||
|
||||
import ida_dbg
|
||||
@@ -1,11 +1,13 @@
|
||||
"""
|
||||
summary: using the low-level tracing hook
|
||||
summary: react to trace notifications
|
||||
|
||||
description:
|
||||
This script demonstrates using the low-level tracing hook
|
||||
(ida_dbg.DBG_Hooks.dbg_trace). It can be run like so:
|
||||
|
||||
ida[t].exe -B -Sdbg_trace.py -Ltrace.log file.exe
|
||||
ida.exe -B -Sdbg_trace.py -Ltrace.log file.exe
|
||||
|
||||
level: advanced
|
||||
"""
|
||||
|
||||
import time
|
||||
+11
-6
@@ -1,18 +1,23 @@
|
||||
"""
|
||||
summary: print call stack (on Linux)
|
||||
summary: print call stack
|
||||
|
||||
description: print the return addresses from the call stack at a breakpoint.
|
||||
(and print also the module and the debug name from debugger)
|
||||
description:
|
||||
|
||||
Print the return addresses from the call stack at a breakpoint,
|
||||
when debugging a Linux binary.
|
||||
(and also print the module and the debug name from debugger)
|
||||
|
||||
To use this example:
|
||||
|
||||
* run `ida64` on test program `simple_appcall_linux64`, or
|
||||
* run `ida` on test program `simple_appcall_linux64`, or
|
||||
`ida` on test program `simple_appcall_linux32`, and wait for
|
||||
auto-analysis to finish
|
||||
* put a breakpoint where you want to see the call stack
|
||||
* select the 'linux debugger' (either local, or remote)
|
||||
* start debugging
|
||||
* Press Shift+C at the breakpoint
|
||||
|
||||
level: intermediate
|
||||
"""
|
||||
import os
|
||||
import ida_idaapi
|
||||
@@ -35,8 +40,8 @@ class print_call_stack_ah_t():
|
||||
if ida_dbg.get_module_info(frame.callea, mi):
|
||||
module = os.path.basename(mi.name)
|
||||
name = ida_name.get_nice_colored_name(
|
||||
frame.callea,
|
||||
ida_name.GNCN_NOCOLOR|ida_name.GNCN_NOLABEL|ida_name.GNCN_NOSEG|ida_name.GNCN_PREFDBG)
|
||||
frame.callea,
|
||||
ida_name.GNCN_NOCOLOR|ida_name.GNCN_NOLABEL|ida_name.GNCN_NOSEG|ida_name.GNCN_PREFDBG)
|
||||
log("Return address: " + hex(frame.callea) + " from: " + module + " with debug name: " + name)
|
||||
else:
|
||||
log("Return address: " + hex(frame.callea))
|
||||
+6
-3
@@ -1,8 +1,9 @@
|
||||
"""
|
||||
summary: print all registers, for all threads
|
||||
summary: print all registers, for all threads in the debugged process
|
||||
|
||||
description: iterate over the list of threads in the program being
|
||||
debugged, and dump all registers contents
|
||||
description:
|
||||
Iterate over the list of threads in the program being
|
||||
debugged, and dump all registers contents
|
||||
|
||||
To use this example:
|
||||
|
||||
@@ -13,6 +14,8 @@ description: iterate over the list of threads in the program being
|
||||
* select the 'linux debugger' (either local, or remote)
|
||||
* start debugging
|
||||
* Press Alt+Shift+C at the breakpoint
|
||||
|
||||
level: beginner
|
||||
"""
|
||||
import ida_idd
|
||||
import ida_dbg
|
||||
+3
-1
@@ -1,5 +1,5 @@
|
||||
"""
|
||||
summary: adding actions to the "registers" widget(s)
|
||||
summary: add a custom action to the "registers" widget
|
||||
|
||||
description:
|
||||
It's possible to add actions to the context menu of
|
||||
@@ -7,6 +7,8 @@ description:
|
||||
|
||||
This example shows how to do just that for
|
||||
registers-displaying widgets (e.g., "General registers")
|
||||
|
||||
level: intermediate
|
||||
"""
|
||||
|
||||
import ida_dbg
|
||||
@@ -1,9 +1,11 @@
|
||||
"""
|
||||
summary: retrieving & dumping debuggee symbols
|
||||
summary: dump symbols from a process being debugged
|
||||
|
||||
description:
|
||||
Queries the debugger (possibly remotely) for the list of
|
||||
symbols that the process being debugged, provides.
|
||||
|
||||
level: beginner
|
||||
"""
|
||||
|
||||
import ida_dbg
|
||||
+3
-1
@@ -1,5 +1,5 @@
|
||||
"""
|
||||
summary: interactively color certain pseudocode lines
|
||||
summary: interactively color decompilation lines
|
||||
|
||||
description:
|
||||
Provides an action that can be used to dynamically alter the
|
||||
@@ -11,6 +11,8 @@ description:
|
||||
with a special background color.
|
||||
|
||||
keywords: colors
|
||||
|
||||
level: intermediate
|
||||
"""
|
||||
|
||||
import ida_kernwin
|
||||
@@ -1,11 +1,13 @@
|
||||
"""
|
||||
summary: a focus on the 'curpos' hook, printing additional details about user input
|
||||
summary: print information about the current position in decompilation
|
||||
|
||||
description:
|
||||
Shows how user input information can be retrieved during
|
||||
processing of a notification triggered by that input
|
||||
|
||||
see_also: vds_hooks
|
||||
|
||||
level: advanced
|
||||
"""
|
||||
|
||||
import ida_hexrays
|
||||
+6
-8
@@ -1,13 +1,15 @@
|
||||
"""
|
||||
summary: automatic decompilation of functions
|
||||
summary: decompile entrypoint automatically
|
||||
|
||||
description:
|
||||
Attempts to load a decompiler plugin corresponding to the current
|
||||
architecture (and address size) right after auto-analysis is performed,
|
||||
architecture right after auto-analysis is performed,
|
||||
and then tries to decompile the function at the first entrypoint.
|
||||
|
||||
It is particularly suited for use with the '-S' flag, for example:
|
||||
idat -Ldecompile.log -Sdecompile_entry_points.py -c file
|
||||
|
||||
level: intermediate
|
||||
"""
|
||||
|
||||
import ida_ida
|
||||
@@ -22,21 +24,17 @@ import ida_kernwin
|
||||
# manually if we want to use it
|
||||
def init_hexrays():
|
||||
ALL_DECOMPILERS = {
|
||||
ida_idp.PLFM_386: "hexrays",
|
||||
ida_idp.PLFM_386: "hexx64",
|
||||
ida_idp.PLFM_ARM: "hexarm",
|
||||
ida_idp.PLFM_PPC: "hexppc",
|
||||
ida_idp.PLFM_MIPS: "hexmips",
|
||||
ida_idp.PLFM_RISCV: "hexrv",
|
||||
}
|
||||
cpu = ida_idp.ph.id
|
||||
decompiler = ALL_DECOMPILERS.get(cpu, None)
|
||||
if not decompiler:
|
||||
print("No known decompilers for architecture with ID: %d" % ida_idp.ph.id)
|
||||
return False
|
||||
if ida_ida.inf_is_64bit():
|
||||
if cpu == ida_idp.PLFM_386:
|
||||
decompiler = "hexx64"
|
||||
else:
|
||||
decompiler += "64"
|
||||
if ida_loader.load_plugin(decompiler) and ida_hexrays.init_hexrays_plugin():
|
||||
return True
|
||||
else:
|
||||
@@ -1,5 +1,5 @@
|
||||
"""
|
||||
summary: decompile entire file
|
||||
summary: produce C listing for the entire file
|
||||
|
||||
description:
|
||||
automate IDA to perform auto-analysis on a file and,
|
||||
@@ -15,6 +15,8 @@ description:
|
||||
* -A instructs IDA to run in non-interactive mode
|
||||
* -S holds a path to the script to run (note this is a single token;
|
||||
there is no space between '-S' and its path.)
|
||||
|
||||
level: beginner
|
||||
"""
|
||||
|
||||
import ida_pro
|
||||
@@ -1,5 +1,10 @@
|
||||
"""
|
||||
summary: decompile & print current function.
|
||||
summary: decompile & print current function
|
||||
|
||||
description:
|
||||
Decompile the function under the cursor
|
||||
|
||||
level: beginner
|
||||
"""
|
||||
|
||||
import ida_hexrays
|
||||
@@ -1,5 +1,5 @@
|
||||
"""
|
||||
summary: a custom microcode instruction optimization rule
|
||||
summary: add custom microcode instruction optimization rule
|
||||
|
||||
description:
|
||||
Installs a custom microcode instruction optimization rule,
|
||||
@@ -12,6 +12,8 @@ description:
|
||||
call !DbgRaiseAssertionFailure <fast:"char *" "assertion text">.0
|
||||
|
||||
To see this plugin in action please use arm64_brk.i64
|
||||
|
||||
level: intermediate
|
||||
"""
|
||||
|
||||
import ida_bytes
|
||||
@@ -1,5 +1,5 @@
|
||||
"""
|
||||
summary: a custom microcode block optimization rule (resolve `goto` chains)
|
||||
summary: add a custom microcode block optimization rule
|
||||
|
||||
description:
|
||||
Installs a custom microcode block optimization rule,
|
||||
@@ -16,6 +16,8 @@ description:
|
||||
|
||||
In other words we fix a goto target if it points to a chain of gotos.
|
||||
This improves the decompiler output in some cases.
|
||||
|
||||
level: advanced
|
||||
"""
|
||||
|
||||
import ida_bytes
|
||||
@@ -4,6 +4,8 @@ summary: list instruction registers
|
||||
description:
|
||||
Shows a list of direct references to a register from the
|
||||
current instruction.
|
||||
|
||||
level: advanced
|
||||
"""
|
||||
|
||||
import ida_pro
|
||||
@@ -1,8 +1,10 @@
|
||||
"""
|
||||
summary: generates microcode for selection
|
||||
summary: generate microcode for the selected range of instructions
|
||||
|
||||
description:
|
||||
Generates microcode for selection and dumps it to the output window.
|
||||
|
||||
level: beginner
|
||||
"""
|
||||
|
||||
import ida_bytes
|
||||
@@ -1,5 +1,5 @@
|
||||
"""
|
||||
summary: using the "Select offsets" widget
|
||||
summary: invoke the structure offset-choosing dialog from decompilation
|
||||
|
||||
description:
|
||||
Registers an action opens the "Select offsets" widget
|
||||
@@ -9,6 +9,8 @@ description:
|
||||
through Alt+Y.
|
||||
|
||||
Place cursor on the union field and press Shift+T
|
||||
|
||||
level: advanced
|
||||
"""
|
||||
|
||||
import ida_idaapi
|
||||
@@ -1,5 +1,5 @@
|
||||
"""
|
||||
summary: a custom microcode instruction optimization rule (`x | ~x => -1`)
|
||||
summary: add a custom microcode instruction optimization rule
|
||||
|
||||
description:
|
||||
Installs a custom microcode instruction optimization rule,
|
||||
@@ -12,6 +12,8 @@ description:
|
||||
-1
|
||||
|
||||
To see this plugin in action please use be_ornot_be.idb
|
||||
|
||||
level: advanced
|
||||
"""
|
||||
|
||||
import ida_hexrays
|
||||
@@ -22,6 +22,8 @@ description:
|
||||
This plugin illustrates another approach to the problem:
|
||||
if you happen to be able to calculate the call prototypes dynamically,
|
||||
this is how to inform the decompiler about them.
|
||||
|
||||
level: intermediate
|
||||
"""
|
||||
|
||||
import ida_idaapi
|
||||
@@ -1,5 +1,5 @@
|
||||
"""
|
||||
summary: invert if/else blocks
|
||||
summary: invert if/else blocks in decompilation
|
||||
|
||||
description:
|
||||
Registers an action that can be used to invert the `if`
|
||||
@@ -31,6 +31,8 @@ description:
|
||||
IDA, and the changes will be present.
|
||||
|
||||
author: EiNSTeiN_ (einstein@g3nius.org)
|
||||
|
||||
level: advanced
|
||||
"""
|
||||
|
||||
import idautils
|
||||
@@ -1,5 +1,5 @@
|
||||
"""
|
||||
summary: dump user-defined information
|
||||
summary: dump user-defined information for a function
|
||||
|
||||
description:
|
||||
Prints user-defined information to the "Output" window.
|
||||
@@ -13,6 +13,8 @@ description:
|
||||
This script loads information from the database without decompiling anything.
|
||||
|
||||
author: EiNSTeiN_ (einstein@g3nius.org)
|
||||
|
||||
level: intermediate
|
||||
"""
|
||||
|
||||
import ida_kernwin
|
||||
@@ -1,5 +1,5 @@
|
||||
"""
|
||||
summary: show ctree graph
|
||||
summary: dump C-tree graph
|
||||
|
||||
description:
|
||||
Registers an action that can be used to show the graph of the ctree.
|
||||
@@ -10,6 +10,8 @@ description:
|
||||
|
||||
To display the graph, we produce a .gdl file, and
|
||||
request that ida displays that using `ida_gdl.display_gdl`.
|
||||
|
||||
level: advanced
|
||||
"""
|
||||
|
||||
import ida_pro
|
||||
@@ -6,6 +6,8 @@ description:
|
||||
by removing some white spaces
|
||||
|
||||
Note: this is rather crude, not quite "pythonic" code.
|
||||
|
||||
level: intermediate
|
||||
"""
|
||||
|
||||
import idautils
|
||||
@@ -1,11 +1,13 @@
|
||||
"""
|
||||
summary: iterate a cblock_t object
|
||||
summary: dump statement blocks
|
||||
|
||||
description:
|
||||
Using a `ida_hexrays.ctree_visitor_t`, search for
|
||||
`ida_hexrays.cit_block` instances and dump them.
|
||||
|
||||
author: EiNSTeiN_ (einstein@g3nius.org)
|
||||
|
||||
level: beginner
|
||||
"""
|
||||
|
||||
import ida_hexrays
|
||||
@@ -1,5 +1,5 @@
|
||||
"""
|
||||
summary: using `ida_hexrays.udc_filter_t`
|
||||
summary: improve decompilation by turning specific patterns into custom function calls
|
||||
|
||||
description:
|
||||
Registers an action that uses a `ida_hexrays.udc_filter_t` to decompile
|
||||
@@ -10,6 +10,8 @@ description:
|
||||
|
||||
In addition to having a shortcut, the action will be present
|
||||
in the context menu.
|
||||
|
||||
level: intermediate
|
||||
"""
|
||||
|
||||
import ida_idaapi
|
||||
@@ -1,5 +1,5 @@
|
||||
"""
|
||||
summary: decompiler hints
|
||||
summary: provide custom decompiler hints
|
||||
|
||||
description:
|
||||
Handle `ida_hexrays.hxe_create_hint` notification using hooks,
|
||||
@@ -12,6 +12,8 @@ description:
|
||||
the form of `!{varname}` (where `{varname}` is replaced with the
|
||||
variable name)
|
||||
* an `if` statement, replace the hint with our own, saying "condition"
|
||||
|
||||
level: beginner
|
||||
"""
|
||||
|
||||
import ida_idaapi
|
||||
@@ -1,5 +1,5 @@
|
||||
"""
|
||||
summary: various decompiler hooks
|
||||
summary: react to decompiler events/notifications
|
||||
|
||||
description:
|
||||
Shows how to hook to many notifications sent by the decompiler.
|
||||
@@ -12,6 +12,8 @@ description:
|
||||
subclassing `ida_hexrays.Hexrays_Hooks`
|
||||
|
||||
see_also: curpos_details
|
||||
|
||||
level: intermediate
|
||||
"""
|
||||
|
||||
import inspect
|
||||
@@ -70,7 +72,7 @@ class vds_hooks_t(ida_hexrays.Hexrays_Hooks):
|
||||
print("### %s: %s" % (method_name, ", ".join(argstrs)))
|
||||
return 0
|
||||
|
||||
def flowchart(self, fc):
|
||||
def flowchart(self, fc, mba, reachable_blocks, decomp_flags):
|
||||
return self._log()
|
||||
|
||||
def stkpnts(self, mba, stkpnts):
|
||||
@@ -94,6 +96,9 @@ class vds_hooks_t(ida_hexrays.Hexrays_Hooks):
|
||||
def glbopt(self, mba):
|
||||
return self._log()
|
||||
|
||||
def begin_structural(self, out, cfunc, ctrl_graph):
|
||||
return self._log()
|
||||
|
||||
def structural(self, ctrl_graph):
|
||||
return self._log()
|
||||
|
||||
@@ -172,5 +177,20 @@ class vds_hooks_t(ida_hexrays.Hexrays_Hooks):
|
||||
def calls_done(self, mba):
|
||||
return self._log()
|
||||
|
||||
def begin_inlining(self, cdg, flags):
|
||||
return self._log()
|
||||
|
||||
def inlining_func(self, cdg, blk, mbr):
|
||||
return self._log()
|
||||
|
||||
def inlined_func(self, cdg, blk, mbr, i1, i2):
|
||||
return self._log()
|
||||
|
||||
def pre_structural(self, ctrl_graph, cfunc, cfg):
|
||||
return self._log()
|
||||
|
||||
def collect_warnings(self, cfunc):
|
||||
return self._log()
|
||||
|
||||
vds_hooks = vds_hooks_t()
|
||||
vds_hooks.hook()
|
||||
+3
-1
@@ -1,9 +1,11 @@
|
||||
"""
|
||||
summary: modifying local variables
|
||||
summary: modifying function local variables
|
||||
|
||||
description:
|
||||
Use a `ida_hexrays.user_lvar_modifier_t` to modify names,
|
||||
comments and/or types of local variables.
|
||||
|
||||
level: intermediate
|
||||
"""
|
||||
|
||||
import ida_hexrays
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user