From 0706ff10187cccea4709f3c85631fef78ecc288d Mon Sep 17 00:00:00 2001 From: Arnaud Diederen Date: Mon, 14 Sep 2020 17:25:37 +0200 Subject: [PATCH] Backported fixes --- api_contents2.txt | 3 ++ api_contents3.txt | 3 ++ idapython.cpp | 76 +++++++++++++++++++++++++-- out_of_tree/parsed_notifications.zip | Bin 4300293 -> 4300293 bytes pydoc_injections2.txt | 29 ++++++++-- pydoc_injections3.txt | 21 ++++++++ pywraps/py_bytes.hpp | 20 +++++++ pywraps/py_search.py | 4 ++ release_api_contents2.txt | 2 + release_api_contents3.txt | 2 + release_pydoc_injections2.txt | 33 +++++++++--- release_pydoc_injections3.txt | 33 +++++++++--- swig/bytes.i | 2 - swig/search.i | 5 ++ 14 files changed, 210 insertions(+), 23 deletions(-) diff --git a/api_contents2.txt b/api_contents2.txt index 2f62f11..d37f388 100644 --- a/api_contents2.txt +++ b/api_contents2.txt @@ -8144,6 +8144,7 @@ 'next_not_tail', 'next_that', 'next_unknown', + 'next_visea', 'node2ea', 'node_info_t_bg_color_get', 'node_info_t_bg_color_set', @@ -8688,6 +8689,7 @@ 'prev_not_tail', 'prev_that', 'prev_unknown', + 'prev_visea', 'print_argloc', 'print_decls', 'print_idcv', @@ -11109,6 +11111,7 @@ 'udt_type_data_t_pack_set', 'udt_type_data_t_sda_get', 'udt_type_data_t_sda_set', + 'udt_type_data_t_set_vftable', 'udt_type_data_t_swap', 'udt_type_data_t_taudt_bits_get', 'udt_type_data_t_taudt_bits_set', diff --git a/api_contents3.txt b/api_contents3.txt index c6a1dda..7000b6a 100644 --- a/api_contents3.txt +++ b/api_contents3.txt @@ -8148,6 +8148,7 @@ 'next_not_tail', 'next_that', 'next_unknown', + 'next_visea', 'node2ea', 'node_info_t_bg_color_get', 'node_info_t_bg_color_set', @@ -8692,6 +8693,7 @@ 'prev_not_tail', 'prev_that', 'prev_unknown', + 'prev_visea', 'print_argloc', 'print_decls', 'print_idcv', @@ -11113,6 +11115,7 @@ 'udt_type_data_t_pack_set', 'udt_type_data_t_sda_get', 'udt_type_data_t_sda_set', + 'udt_type_data_t_set_vftable', 'udt_type_data_t_swap', 'udt_type_data_t_taudt_bits_get', 'udt_type_data_t_taudt_bits_set', diff --git a/idapython.cpp b/idapython.cpp index 2612554..f98439d 100644 --- a/idapython.cpp +++ b/idapython.cpp @@ -27,7 +27,7 @@ #include #include #include - +#include #if defined (PY_MAJOR_VERSION) && (PY_MAJOR_VERSION < 3) // in Python 2.x many APIs accept char * instead of const char * GCC_DIAG_OFF(write-strings) @@ -783,11 +783,11 @@ idapython_plugin_t::idapython_plugin_t() // Cleaning up Python idapython_plugin_t::~idapython_plugin_t() { - if ( !initialized || Py_IsInitialized() == 0 ) - return; - QASSERT(30616, instance == this); + if ( !initialized || Py_IsInitialized() == 0 ) + goto SKIP_CLEANUP; + if ( PyGILState_GetThisThreadState() ) { // Note: No 'PYW_GIL_GET' here, as it would try to release @@ -829,10 +829,66 @@ idapython_plugin_t::~idapython_plugin_t() const hook_data_t &hd = hook_data_vec[i-1]; idapython_unhook_from_notification_point(hd.type, hd.cb, hd.ud); } - +SKIP_CLEANUP: instance = nullptr; } +#ifdef __NT__ +// for MessageBox() +#pragma comment(lib, "user32") +#endif +//-------------------------------------------------------------------------- +// show an error message, possibly during teardown of the process +AS_PRINTF(1, 2) static void lerror(const char *format, ...) +{ + va_list va; + va_start(va, format); +#ifdef __NT__ + char buf[MAXSTR]; + qvsnprintf(buf, sizeof(buf), format, va); + // use MB_SERVICE_NOTIFICATION to prevent UI message loop from running since ida.exe is mostly shut down at this point + // and can crash if messages get processed + MessageBox(NULL, buf, "IDA", MB_ICONERROR|MB_SERVICE_NOTIFICATION); +#else + qveprintf(format, va); + //qgetchar(); +#endif +} + +#define ERRMSG "Unexpected fatal error while intitailizing Python runtime. Please run idapyswitch to confirm or change the used Python runtime" + +volatile sig_atomic_t initdone = 0; +//------------------------------------------------------------------------- +// some Python runtimes may call abort() or exit() if they don't like something +// catch this to avoid silent IDA exit +static void exithandler(void) +{ + if ( !initdone ) + { + initdone = 1; + lerror(ERRMSG); + // return to caller to continue exiting normally + } +} + +//lint -e2761 call to non-async-signal-safe function '' within signal handler '' +//lint -e2762 call to signal registration function 'signal' within signal handler 'aborthandler' +//------------------------------------------------------------------------- +// catch unexpected abort() call +static void aborthandler(int sig) +{ + lerror(ERRMSG); + initdone = 1; // avoid duplicate message on exit + // from https://www.gnu.org/software/libc/manual/html_node/Termination-in-Handler.html + /* Now reraise the signal. We reactivate the signal's + default handling, which is to terminate the process. + We could just call exit or abort, + but reraising the signal sets the return status + from the process correctly. */ + signal(sig, SIG_DFL); + raise(sig); +} + //------------------------------------------------------------------------- // Initialize the Python environment bool idapython_plugin_t::init() @@ -913,8 +969,18 @@ bool idapython_plugin_t::init() } } + + typedef void(*SignalHandlerPointer)(int); + // catch unexpected abort() + SignalHandlerPointer previousHandler = signal(SIGABRT, aborthandler); + // ... and exit() + atexit(exithandler); + // Start the interpreter Py_InitializeEx(0 /* Don't catch SIGPIPE, SIGXFZ, SIGXFSZ & SIGINT signals */); + // disable handlers + initdone = 1; + signal(SIGABRT, previousHandler); if ( !Py_IsInitialized() ) { diff --git a/out_of_tree/parsed_notifications.zip b/out_of_tree/parsed_notifications.zip index c9d75226fc6bb3fab3abb6c8d9e04cfd927aa9fe..edb3b1c9bce87f36c07106c03d8b02c3a1cf531d 100644 GIT binary patch delta 43071 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 delta 43176 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 Dsys#C diff --git a/pydoc_injections2.txt b/pydoc_injections2.txt index a6d8123..87d8095 100644 --- a/pydoc_injections2.txt +++ b/pydoc_injections2.txt @@ -2942,6 +2942,15 @@ next_unknown(*args) @param ea (C++: ea_t) @param maxea (C++: ea_t) +Help on function next_visea in module ida_bytes: + +next_visea(*args) + Get next visible address. + + next_visea(ea) -> ea_t + @param ea (C++: ea_t) + @return: BADADDR if none exists. + Help on function num_flag in module ida_bytes: num_flag(*args) @@ -3266,6 +3275,15 @@ prev_unknown(*args) @param ea (C++: ea_t) @param minea (C++: ea_t) +Help on function prev_visea in module ida_bytes: + +prev_visea(*args) + Get previous visible address. + + prev_visea(ea) -> ea_t + @param ea (C++: ea_t) + @return: BADADDR if none exists. + Help on function print_strlit_type in module ida_bytes: print_strlit_type(*args) @@ -70612,10 +70630,10 @@ Help on function op_offset in module ida_offset: op_offset(*args) See 'op_offset_ex()' - op_offset(ea, n, type, target=BADADDR, base=0, tdelta=0) -> bool + op_offset(ea, n, type_and_flags, target=BADADDR, base=0, tdelta=0) -> bool @param ea (C++: ea_t) @param n (C++: int) - @param type (C++: reftype_t) + @param type_and_flags (C++: uint32) @param target (C++: ea_t) @param base (C++: ea_t) @param tdelta (C++: adiff_t) @@ -84282,6 +84300,9 @@ class udt_type_data_t(udtmembervec_t) | is_vftable(self, *args) | is_vftable(self) -> bool | + | set_vftable(self, *args) + | set_vftable(self) + | | swap(self, *args) | swap(self, r) | @param r (C++: udt_type_data_t &) @@ -92178,10 +92199,10 @@ Help on function op_offset in module ida_offset: op_offset(*args) See 'op_offset_ex()' - op_offset(ea, n, type, target=BADADDR, base=0, tdelta=0) -> bool + op_offset(ea, n, type_and_flags, target=BADADDR, base=0, tdelta=0) -> bool @param ea (C++: ea_t) @param n (C++: int) - @param type (C++: reftype_t) + @param type_and_flags (C++: uint32) @param target (C++: ea_t) @param base (C++: ea_t) @param tdelta (C++: adiff_t) diff --git a/pydoc_injections3.txt b/pydoc_injections3.txt index 23bc0ad..fcb193b 100644 --- a/pydoc_injections3.txt +++ b/pydoc_injections3.txt @@ -2939,6 +2939,15 @@ next_unknown(*args) -> 'ea_t' @param ea (C++: ea_t) @param maxea (C++: ea_t) +Help on function next_visea in module ida_bytes: + +next_visea(*args) -> 'ea_t' + Get next visible address. + + next_visea(ea) -> ea_t + @param ea (C++: ea_t) + @return: BADADDR if none exists. + Help on function num_flag in module ida_bytes: num_flag(*args) -> 'flags_t' @@ -3263,6 +3272,15 @@ prev_unknown(*args) -> 'ea_t' @param ea (C++: ea_t) @param minea (C++: ea_t) +Help on function prev_visea in module ida_bytes: + +prev_visea(*args) -> 'ea_t' + Get previous visible address. + + prev_visea(ea) -> ea_t + @param ea (C++: ea_t) + @return: BADADDR if none exists. + Help on function print_strlit_type in module ida_bytes: print_strlit_type(*args) -> 'PyObject *' @@ -84757,6 +84775,9 @@ class udt_type_data_t(udtmembervec_t) | is_vftable(self, *args) -> 'bool' | is_vftable(self) -> bool | + | set_vftable(self, *args) -> 'void' + | set_vftable(self) + | | swap(self, *args) -> 'void' | swap(self, r) | @param r (C++: udt_type_data_t &) diff --git a/pywraps/py_bytes.hpp b/pywraps/py_bytes.hpp index 103c095..fac9aa2 100644 --- a/pywraps/py_bytes.hpp +++ b/pywraps/py_bytes.hpp @@ -328,6 +328,26 @@ static PyObject *py_get_8bit(ea_t ea, uint32 v, int nbit) uchar octet = get_8bit(&ea, &v, &nbit); return Py_BuildValue("(i" PY_BV_EA "ki)", int(uint32(octet)), bvea_t(ea), v, nbit); } + +//------------------------------------------------------------------------- +/* +# +def bin_search(start_ea, end_ea, image, imask, step, flags): + """ + Search for a set of bytes in the program + + @param start_ea: linear address, start of range to search + @param end_ea: linear address, end of range to search (exclusive) + @param image: the set of bytes to search for + @param imask: a bitfield representing the mask in 'image' (can be None) + @param step: either BIN_SEARCH_FORWARD, or BIN_SEARCH_BACKWARD + @param flags: combination of BIN_SEARCH_* flags + @return: the address of a match, or ida_idaapi.BADADDR if not found + """ + pass +# +*/ + // #endif diff --git a/pywraps/py_search.py b/pywraps/py_search.py index b63322a..8624977 100644 --- a/pywraps/py_search.py +++ b/pywraps/py_search.py @@ -1,4 +1,8 @@ +# +SEARCH_UNICODE = 0x40 # Deprecated. For find_binary() +# + # find_void=find_suspop # diff --git a/release_api_contents2.txt b/release_api_contents2.txt index 53cc7f4..116b046 100644 --- a/release_api_contents2.txt +++ b/release_api_contents2.txt @@ -7441,6 +7441,7 @@ 'next_not_tail', 'next_that', 'next_unknown', + 'next_visea', 'node2ea', 'node_info_t_bg_color_get', 'node_info_t_bg_color_set', @@ -7921,6 +7922,7 @@ 'prev_not_tail', 'prev_that', 'prev_unknown', + 'prev_visea', 'print_argloc', 'print_decls', 'print_idcv', diff --git a/release_api_contents3.txt b/release_api_contents3.txt index b107954..c6c27e2 100644 --- a/release_api_contents3.txt +++ b/release_api_contents3.txt @@ -7445,6 +7445,7 @@ 'next_not_tail', 'next_that', 'next_unknown', + 'next_visea', 'node2ea', 'node_info_t_bg_color_get', 'node_info_t_bg_color_set', @@ -7925,6 +7926,7 @@ 'prev_not_tail', 'prev_that', 'prev_unknown', + 'prev_visea', 'print_argloc', 'print_decls', 'print_idcv', diff --git a/release_pydoc_injections2.txt b/release_pydoc_injections2.txt index 421da17..52acfc4 100644 --- a/release_pydoc_injections2.txt +++ b/release_pydoc_injections2.txt @@ -585,12 +585,15 @@ Help on function bin_search in module ida_bytes: bin_search(*args) bin_search(start_ea, end_ea, image, imask, step, flags) -> ea_t - start_ea: ea_t - end_ea: ea_t - image: bytevec_t const & - imask: bytevec_t const & - step: int - flags: int + Search for a set of bytes in the program + + @param start_ea: linear address, start of range to search + @param end_ea: linear address, end of range to search (exclusive) + @param image: the set of bytes to search for + @param imask: a bitfield representing the mask in 'image' (can be None) + @param step: either BIN_SEARCH_FORWARD, or BIN_SEARCH_BACKWARD + @param flags: combination of BIN_SEARCH_* flags + @return: the address of a match, or ida_idaapi.BADADDR if not found Help on function byte_flag in module ida_bytes: @@ -2942,6 +2945,15 @@ next_unknown(*args) @param ea (C++: ea_t) @param maxea (C++: ea_t) +Help on function next_visea in module ida_bytes: + +next_visea(*args) + Get next visible address. + + next_visea(ea) -> ea_t + @param ea (C++: ea_t) + @return: BADADDR if none exists. + Help on function num_flag in module ida_bytes: num_flag(*args) @@ -3266,6 +3278,15 @@ prev_unknown(*args) @param ea (C++: ea_t) @param minea (C++: ea_t) +Help on function prev_visea in module ida_bytes: + +prev_visea(*args) + Get previous visible address. + + prev_visea(ea) -> ea_t + @param ea (C++: ea_t) + @return: BADADDR if none exists. + Help on function print_strlit_type in module ida_bytes: print_strlit_type(*args) diff --git a/release_pydoc_injections3.txt b/release_pydoc_injections3.txt index 9cc67f6..0719188 100644 --- a/release_pydoc_injections3.txt +++ b/release_pydoc_injections3.txt @@ -584,12 +584,15 @@ Help on function bin_search in module ida_bytes: bin_search(*args) -> 'ea_t' bin_search(start_ea, end_ea, image, imask, step, flags) -> ea_t - start_ea: ea_t - end_ea: ea_t - image: bytevec_t const & - imask: bytevec_t const & - step: int - flags: int + Search for a set of bytes in the program + + @param start_ea: linear address, start of range to search + @param end_ea: linear address, end of range to search (exclusive) + @param image: the set of bytes to search for + @param imask: a bitfield representing the mask in 'image' (can be None) + @param step: either BIN_SEARCH_FORWARD, or BIN_SEARCH_BACKWARD + @param flags: combination of BIN_SEARCH_* flags + @return: the address of a match, or ida_idaapi.BADADDR if not found Help on function byte_flag in module ida_bytes: @@ -2939,6 +2942,15 @@ next_unknown(*args) -> 'ea_t' @param ea (C++: ea_t) @param maxea (C++: ea_t) +Help on function next_visea in module ida_bytes: + +next_visea(*args) -> 'ea_t' + Get next visible address. + + next_visea(ea) -> ea_t + @param ea (C++: ea_t) + @return: BADADDR if none exists. + Help on function num_flag in module ida_bytes: num_flag(*args) -> 'flags_t' @@ -3263,6 +3275,15 @@ prev_unknown(*args) -> 'ea_t' @param ea (C++: ea_t) @param minea (C++: ea_t) +Help on function prev_visea in module ida_bytes: + +prev_visea(*args) -> 'ea_t' + Get previous visible address. + + prev_visea(ea) -> ea_t + @param ea (C++: ea_t) + @return: BADADDR if none exists. + Help on function print_strlit_type in module ida_bytes: print_strlit_type(*args) -> 'PyObject *' diff --git a/swig/bytes.i b/swig/bytes.i index a88f59f..b948cff 100644 --- a/swig/bytes.i +++ b/swig/bytes.i @@ -7,8 +7,6 @@ %ignore next_that; %ignore prev_that; %ignore adjust_visea; -%ignore prev_visea; -%ignore next_visea; %ignore visit_patched_bytes; %ignore is_first_visea; %ignore is_last_visea; diff --git a/swig/search.i b/swig/search.i index 356b51f..21d1e92 100644 --- a/swig/search.i +++ b/swig/search.i @@ -6,6 +6,11 @@ %ignore search; %ignore user2bin; +%pythoncode %{ +# +# +%} + %inline %{ // //