mirror of
https://github.com/idapython/src
synced 2026-06-08 14:47:00 +00:00
IDAPython for IDA 7.5
This commit is contained in:
+65
-22
@@ -20,7 +20,6 @@ parser.add_argument("-b", "--batch-patches", required=True)
|
||||
parser.add_argument("-v", "--verbose", default=False, action="store_true")
|
||||
parser.add_argument("-x", "--xml-doc-directory", required=True)
|
||||
parser.add_argument("-m", "--module", required=True)
|
||||
parser.add_argument("-V", "--apply-valist-patches", default=False, action="store_true")
|
||||
args = parser.parse_args()
|
||||
|
||||
this_dir, _ = os.path.split(__file__)
|
||||
@@ -117,9 +116,11 @@ if add_ridb is not None:
|
||||
|
||||
# Patch the code
|
||||
wrap_regex = re.compile(r"SWIGINTERN PyObject \*_wrap_([a-zA-Z0-9_]*)\(.*")
|
||||
director_method_regex = re.compile(r".*((SwigDirector_([a-zA-Z0-9_]*))::([a-zA-Z0-9_]*))\(.*")
|
||||
director_method_regex = re.compile(r".*((SwigDirector_([a-zA-Z0-9_]*))::~?([a-zA-Z0-9_]*))\(.*")
|
||||
swig_clink_var_get_regex = re.compile(r"SWIGINTERN PyObject \*(Swig_var_[a-zA-Z0-9_]*_get).*")
|
||||
swig_clink_var_set_regex = re.compile(r"SWIGINTERN int (Swig_var_[a-zA-Z0-9_]*_set).*")
|
||||
SWIG_Python_TypeError_regex = re.compile(".*(SWIG_Python_TypeError)\(const char \*type, PyObject \*obj\).*")
|
||||
SwigPyObject_dealloc_regex = re.compile(r"^(SwigPyObject_dealloc)\(PyObject \*v\)$")
|
||||
|
||||
all_lines = [
|
||||
"#ifdef __NT__\n",
|
||||
@@ -176,6 +177,10 @@ with open(args.input) as f:
|
||||
m = swig_clink_var_get_regex.match(line)
|
||||
if not m:
|
||||
m = swig_clink_var_set_regex.match(line)
|
||||
if not m:
|
||||
m = SWIG_Python_TypeError_regex.match(line)
|
||||
if not m:
|
||||
m = SwigPyObject_dealloc_regex.match(line)
|
||||
if m:
|
||||
stat = STAT_IN_FUNCTION
|
||||
entered_function = True
|
||||
@@ -184,6 +189,31 @@ with open(args.input) as f:
|
||||
current_function_uses_args = False
|
||||
current_function_uses_varargs = False
|
||||
func_patches = patches.get(current_function, [])[:]
|
||||
if current_function == "SWIG_Python_TypeError":
|
||||
func_patches.append(
|
||||
(
|
||||
"repl_text",
|
||||
(
|
||||
"#ifndef Py_LIMITED_API // tp_name is not accessible",
|
||||
(
|
||||
" (void) obj;",
|
||||
"#ifndef Py_LIMITED_API // tp_name is not accessible",
|
||||
),
|
||||
)))
|
||||
elif current_function == "SwigPyObject_dealloc":
|
||||
func_patches.append(
|
||||
(
|
||||
"insert_before_text",
|
||||
(
|
||||
"printf(\"swig/python detected a memory leak",
|
||||
(
|
||||
"#ifdef TESTABLE_BUILD",
|
||||
" if ( name == NULL || strcmp(name, \"std::out_of_range *\") != 0 )",
|
||||
" abort();",
|
||||
"#endif",
|
||||
),
|
||||
),
|
||||
))
|
||||
line = line.replace(", ...arg0)", ", ...)")
|
||||
else:
|
||||
if line.find("PyArg_UnpackTuple(args") > -1:
|
||||
@@ -193,14 +223,13 @@ with open(args.input) as f:
|
||||
elif line.find("varargs") > -1:
|
||||
current_function_uses_varargs = True
|
||||
for patch_kind, patch_data in func_patches:
|
||||
if patch_kind == "va_copy":
|
||||
if args.apply_valist_patches:
|
||||
dst_va, src_va = patch_data
|
||||
target = "%s = *%s;" % (dst_va, src_va)
|
||||
if line.strip() == target:
|
||||
subst = "set_vva(%s, *%s); %s" % (dst_va, src_va, patched_cmt)
|
||||
elif patch_kind == "spontaneous_callback_call":
|
||||
if line.lstrip().startswith("return "):
|
||||
if patch_kind == "spontaneous_callback_call":
|
||||
if patch_data is not None:
|
||||
add_gil_lock, try_anchor, catch_anchor = patch_data
|
||||
else:
|
||||
add_gil_lock, try_anchor, catch_anchor = True, None, None
|
||||
if line.lstrip().startswith("return ") \
|
||||
or catch_anchor and line.rstrip() == catch_anchor:
|
||||
subst = prepend_subst(
|
||||
subst,
|
||||
" }\n" +
|
||||
@@ -211,13 +240,23 @@ with open(args.input) as f:
|
||||
" PyErr_Print();\n"
|
||||
" }\n",
|
||||
line)
|
||||
elif line.rstrip().find("c_result = SwigValueInit") > -1:
|
||||
# vtype = line.strip().split()[0]
|
||||
# init_line = " %s c_result = %s(0);" % (vtype, vtype)
|
||||
elif line.rstrip().find("c_result = SwigValueInit") > -1 \
|
||||
or line.rstrip().find("qstring c_result;") > -1 \
|
||||
or try_anchor and line.rstrip() == try_anchor:
|
||||
|
||||
lines = []
|
||||
if add_gil_lock:
|
||||
subst_lines = [
|
||||
" PYW_GIL_GET; %s" % patched_cmt,
|
||||
" try {"
|
||||
]
|
||||
else:
|
||||
subst_lines = [
|
||||
" try { %s" % patched_cmt
|
||||
]
|
||||
subst = append_subst(
|
||||
subst,
|
||||
" PYW_GIL_GET; %s\n" % patched_cmt +
|
||||
" try {",
|
||||
"\n".join(subst_lines),
|
||||
line)
|
||||
|
||||
elif patch_kind == "repl_text":
|
||||
@@ -231,7 +270,10 @@ with open(args.input) as f:
|
||||
elif patch_kind == "insert_before_text":
|
||||
idx = line.find(patch_data[0])
|
||||
if idx > -1:
|
||||
subst = ["%s %s" % (patch_data[1], patched_cmt), line]
|
||||
repl = patch_data[1]
|
||||
if not isinstance(repl, str):
|
||||
repl = "\n".join(repl)
|
||||
subst = ["%s %s" % (repl, patched_cmt), line]
|
||||
elif patch_kind == "maybe_collect_director_fixed_method_set":
|
||||
if entered_function:
|
||||
subst = [
|
||||
@@ -251,18 +293,19 @@ with open(args.input) as f:
|
||||
if entered_function:
|
||||
subst = prepend_subst(subst, " if ( !__chkreqidb() ) return NULL; %s" % patched_cmt, line)
|
||||
elif patch_kind == "director_method_call_arity_cap":
|
||||
method_name, args_cfoa, args_cmoa = patch_data
|
||||
add_gil_lock, method_name, args_cfoa, args_cmoa = patch_data
|
||||
if entered_function:
|
||||
subst = prepend_subst(
|
||||
subst,
|
||||
subst_lines = [" %s" % patched_cmt]
|
||||
if add_gil_lock:
|
||||
subst_lines.append(" PYW_GIL_GET;")
|
||||
subst_lines.extend(
|
||||
[
|
||||
" %s" % patched_cmt,
|
||||
" newref_t __method(PyObject_GetAttrString(swig_get_self(), \"%s\"));" % method_name,
|
||||
" ssize_t __argcnt = get_callable_arg_count(__method);",
|
||||
" if ( __argcnt < 0 )",
|
||||
" Swig::DirectorMethodException::raise(\"Error detected when calling '%s.%s'\");" % (hooks_class_name, method_name),
|
||||
],
|
||||
line)
|
||||
])
|
||||
subst = prepend_subst(subst, subst_lines, line)
|
||||
else:
|
||||
add_error = False
|
||||
call_args = None
|
||||
|
||||
Reference in New Issue
Block a user