From a12974b66c5b000b4634a84392cd2c972f2e2f58 Mon Sep 17 00:00:00 2001 From: "elias.bachaalany" Date: Thu, 19 May 2011 15:06:31 +0000 Subject: [PATCH] - bugfix: idc.GetString()/idaapi.get_ascii_contents()/idautils.Strings() were limited to MAXSTR string length - minor mods --- python.cpp | 20 +++++++++++++++----- python/idc.py | 4 ++-- swig/bytes.i | 40 +++++++++++++++++++++++++++++++++++++++- swig/idaapi.i | 30 +++++++++++++++++------------- 4 files changed, 73 insertions(+), 21 deletions(-) diff --git a/python.cpp b/python.cpp index ebc0dd3..b908054 100644 --- a/python.cpp +++ b/python.cpp @@ -144,6 +144,7 @@ static int break_check(PyObject *obj, _frame *frame, int what, PyObject *arg) { // We check the timer once every 10 calls ninsns = 0; + // Timeout disabled or elapsed? if ( script_timeout != 0 && (time(NULL) - start_time > script_timeout) ) { @@ -164,6 +165,8 @@ static void reset_execution_time() start_time = time(NULL); ninsns = 0; } + +//------------------------------------------------------------------------ // Prepare for Python execution static void begin_execution() { @@ -175,8 +178,7 @@ static void begin_execution() PyEval_SetTrace(break_check, NULL); } -//------------------------------------------------------------------------ -// Called after Python execution finishes +//--------------------------------------------------------------------------- static void hide_script_waitbox() { if ( box_displayed ) @@ -186,6 +188,8 @@ static void hide_script_waitbox() } } +//------------------------------------------------------------------------ +// Called after Python execution finishes static void end_execution() { hide_script_waitbox(); @@ -197,19 +201,25 @@ static void end_execution() } //------------------------------------------------------------------------- -// Exported to the Python environment void disable_script_timeout() { + // Clear timeout script_timeout = 0; - end_execution(); + + // Uninstall the trace function and hide the waitbox (if it was shown) + end_execution(); } +//------------------------------------------------------------------------- int set_script_timeout(int timeout) { + // Update the timeout qswap(timeout, script_timeout); - + + // Reset the execution time and hide the waitbox (so it is shown again after timeout elapses) reset_execution_time(); hide_script_waitbox(); + return timeout; } diff --git a/python/idc.py b/python/idc.py index 6df1f1a..7bcfc64 100644 --- a/python/idc.py +++ b/python/idc.py @@ -2327,7 +2327,7 @@ def GetString(ea, length = -1, strtype = ASCSTR_C): if length == -1: length = idaapi.get_max_ascii_length(ea, strtype) - return idaapi.get_ascii_contents(ea, length, strtype) + return idaapi.get_ascii_contents(ea, length, strtype, length + 1) def GetStringType(ea): @@ -2911,7 +2911,7 @@ def AskAddr(defval, prompt): """ Ask the user to enter an address - @param defval: a string designating the default address value. This value + @param defval: an ea_t designating the default address value. This value will appear in the dialog box. @param prompt: the prompt to display in the dialog box diff --git a/swig/bytes.i b/swig/bytes.i index 75efcc7..3e71db8 100644 --- a/swig/bytes.i +++ b/swig/bytes.i @@ -73,6 +73,7 @@ %ignore unregister_custom_data_type; %ignore register_custom_data_type; %ignore get_many_bytes; +%ignore get_ascii_contents; // TODO: This could be fixed (if needed) %ignore set_dbgmem_source; @@ -94,7 +95,7 @@ %rename (unregister_custom_data_type) py_unregister_custom_data_type; %rename (register_custom_data_type) py_register_custom_data_type; %rename (get_many_bytes) py_get_many_bytes; - +%rename (get_ascii_contents) py_get_ascii_contents; %{ // //------------------------------------------------------------------------ @@ -690,6 +691,43 @@ static PyObject *py_get_many_bytes(ea_t ea, unsigned int size) Py_RETURN_NONE; } +//--------------------------------------------------------------------------- +/* +# +def get_ascii_contents(ea, len, type, bufsize): + """ + Get contents of ascii string + This function returns the displayed part of the string + It works even if the string has not been created in the database yet. + + @param ea: linear address of the string + @param len: length of the string in bytes + @param type: type of the string + @param bufsize: size of output buffer + @return: 1-ok, 0-ascii string is too long and was truncated + """ + pass +# +*/ +static PyObject *py_get_ascii_contents( + ea_t ea, + size_t len, + int32 type, + size_t bufsize = MAXSTR) +{ + char *buf = (char *)qalloc(bufsize); + if ( buf == NULL ) + return NULL; + + if ( !get_ascii_contents(ea, len, type, buf, bufsize) ) + { + qfree(buf); + Py_RETURN_NONE; + } + PyObject *py_buf = PyString_FromStringAndSize((const char *)buf, bufsize); + qfree(buf); + return py_buf; +} diff --git a/swig/idaapi.i b/swig/idaapi.i index d73936c..e4e92e7 100644 --- a/swig/idaapi.i +++ b/swig/idaapi.i @@ -606,7 +606,7 @@ const char *pywraps_check_autoscripts() #define STRING2(x) STRING1(x) static const char *exts[] = {"py", "pyw", "pyc", "pyo"}; - static const char *fns[] = + static const char *fns[] = { "swig_runtime_data" STRING2(SWIG_RUNTIME_VERSION), "sitecustomize", @@ -662,7 +662,7 @@ static error_t idaapi py_idc_opaque_dtor( // Extract the Python object reference PyObject *py_obj = (PyObject *)idc_val.pvoid; - + // Decrease its reference (and eventually destroy it) Py_DECREF(py_obj); @@ -745,7 +745,7 @@ PyObject *create_idaapi_class_instance0(const char *clsname) //------------------------------------------------------------------------ // Utility function to create linked class instances PyObject *create_idaapi_linked_class_instance( - const char *clsname, + const char *clsname, void *lnk) { PyObject *py_cls = get_idaapi_attr(clsname); @@ -796,8 +796,8 @@ PyObject *get_idaapi_attr(const char *attrname) //------------------------------------------------------------------------ // Returns a qstring from an object attribute bool PyW_GetStringAttr( - PyObject *py_obj, - const char *attr_name, + PyObject *py_obj, + const char *attr_name, qstring *str) { PyObject *py_attr = PyW_TryGetAttrString(py_obj, attr_name); @@ -1034,7 +1034,7 @@ static int get_pyidc_cvt_type(PyObject *py_var) PyObject *attr = PyW_TryGetAttrString(py_var, S_PY_IDCCVT_ID_ATTR); if ( attr == NULL ) return -1; - + if ( !(PyInt_Check(attr) || PyLong_Check(attr)) ) { Py_DECREF(attr); @@ -1267,7 +1267,7 @@ int pyvar_to_idcvar( continue; size_t len = strlen(field_name); - + // Skip private attributes if ( (len > 2 ) && (strncmp(field_name, "__", 2) == 0 ) @@ -1376,7 +1376,7 @@ int idcvar_to_pyvar( } else return CIP_IMMUTABLE; - + case VT_REF: { if ( *py_var == NULL ) @@ -1384,7 +1384,7 @@ int idcvar_to_pyvar( PyObject *py_cls = get_idaapi_attr(PY_CLSID_CVT_BYREF); if ( py_cls == NULL ) return CIP_FAILED; - + // Create a byref object with None value. We populate it later *py_var = PyObject_CallFunctionObjArgs(py_cls, Py_None, NULL); Py_DECREF(py_cls); @@ -1441,7 +1441,7 @@ int idcvar_to_pyvar( } PyObject *obj; bool is_dict = false; - + // Need to create a new object? if ( *py_var == NULL ) { @@ -1472,7 +1472,7 @@ int idcvar_to_pyvar( // Get the attribute idc_value_t v; VarGetAttr(&idc_var, attr_name, &v, true); - + // Convert attribute to a python value (recursively) PyObject *py_attr(NULL); int cvt = idcvar_to_pyvar(v, &py_attr); @@ -1488,7 +1488,7 @@ int idcvar_to_pyvar( PyDict_SetItemString(obj, attr_name, py_attr); else PyObject_SetAttrString(obj, attr_name, py_attr); - + if ( cvt == CIP_OK ) Py_XDECREF(py_attr); } @@ -2322,26 +2322,30 @@ 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 + @return: Returns the old timeout value """ pass # */ int set_script_timeout(int timeout); + /* # 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 # */ void disable_script_timeout(); + /* # def enable_extlang_python(enable):