@@ -125,6 +125,7 @@ static int script_timeout = 2;
125125static bool g_ui_ready = false ;
126126static bool g_alert_auto_scripts = true ;
127127static bool g_remove_cwd_sys_path = false ;
128+ static bool g_use_local_python = false ;
128129
129130static void end_execution ();
130131static void begin_execution ();
@@ -369,6 +370,11 @@ const char *idaapi set_python_options(
369370 g_remove_cwd_sys_path = *(uval_t *)value != 0 ;
370371 break ;
371372 }
373+ else if ( qstrcmp (keyword, " USE_LOCAL_PYTHON" ) == 0 )
374+ {
375+ g_use_local_python = *(uval_t *)value != 0 ;
376+ break ;
377+ }
372378 }
373379 return IDPOPT_BADKEY;
374380 } while (false );
@@ -466,7 +472,10 @@ static bool IDAPython_ExecFile(const char *FileName, char *errbuf, size_t errbuf
466472{
467473 PyObject *py_execscript = get_idaapi_attr (S_IDAAPI_EXECSCRIPT);
468474 if ( py_execscript == NULL )
475+ {
476+ qstrncpy (errbuf, " Could not find idaapi." S_IDAAPI_EXECSCRIPT " ?!" , errbufsz);
469477 return false ;
478+ }
470479
471480 char script[MAXSTR];
472481 qstrncpy (script, FileName, sizeof (script));
@@ -1288,6 +1297,25 @@ static void sanitize_path()
12881297 PySys_SetPath (newpath.begin ());
12891298}
12901299
1300+
1301+ // -------------------------------------------------------------------------
1302+ // we have to do it ourselves because Python 2.7 calls exit() if importing site fails
1303+ static bool initsite (void )
1304+ {
1305+ PyObject *m;
1306+ m = PyImport_ImportModule (" site" );
1307+ if (m == NULL )
1308+ {
1309+ PyErr_Print ();
1310+ Py_Finalize ();
1311+ return false ;
1312+ }
1313+ else {
1314+ Py_DECREF (m);
1315+ }
1316+ return true ;
1317+ }
1318+
12911319// -------------------------------------------------------------------------
12921320// Initialize the Python environment
12931321bool IDAPython_Init (void )
@@ -1306,12 +1334,11 @@ bool IDAPython_Init(void)
13061334 char tmp[QMAXPATH];
13071335#ifdef __LINUX__
13081336 // Export symbols from libpython to resolve imported module deps
1309- qsnprintf (tmp, sizeof (tmp), " libpython%d.%d.so.1" ,
1310- PY_MAJOR_VERSION,
1311- PY_MINOR_VERSION);
1312- if ( !dlopen (tmp, RTLD_NOLOAD | RTLD_GLOBAL | RTLD_LAZY) )
1337+ // use the standard soname: libpython2.7.so.1.0
1338+ #define PYLIB " libpython" QSTRINGIZE(PY_MAJOR_VERSION) " ." QSTRINGIZE(PY_MINOR_VERSION) " .so.1.0"
1339+ if ( !dlopen (PYLIB, RTLD_NOLOAD | RTLD_GLOBAL | RTLD_LAZY) )
13131340 {
1314- warning (" IDAPython: %s" , dlerror ());
1341+ warning (" IDAPython dlopen( " PYLIB " ) error : %s" , dlerror ());
13151342 return false ;
13161343 }
13171344#endif
@@ -1350,16 +1377,31 @@ bool IDAPython_Init(void)
13501377 }
13511378 }
13521379
1380+ if ( g_use_local_python )
1381+ Py_SetPythonHome (g_idapython_dir);
1382+
1383+ // don't import "site" right now
1384+ Py_NoSiteFlag = 1 ;
1385+
13531386 // Start the interpreter
13541387 Py_Initialize ();
1388+
13551389 if ( !Py_IsInitialized () )
13561390 {
13571391 warning (" IDAPython: Py_Initialize() failed" );
13581392 return false ;
13591393 }
13601394
1395+ // remove current directory
13611396 sanitize_path ();
13621397
1398+ // import "site"
1399+ if ( !g_use_local_python && !initsite () )
1400+ {
1401+ warning (" IDAPython: importing \" site\" failed" );
1402+ return false ;
1403+ }
1404+
13631405 // Enable multi-threading support
13641406 if ( !PyEval_ThreadsInitialized () )
13651407 PyEval_InitThreads ();
@@ -1416,7 +1458,7 @@ bool IDAPython_Init(void)
14161458 parse_plugin_options ();
14171459
14181460 // Register a RunPythonStatement() function for IDC
1419- set_idc_func (S_IDC_RUNPYTHON_STATEMENT, idc_runpythonstatement, idc_runpythonstatement_args);
1461+ set_idc_func_ex (S_IDC_RUNPYTHON_STATEMENT, idc_runpythonstatement, idc_runpythonstatement_args, 0 );
14201462
14211463 // A script specified on the command line is run
14221464 if ( g_run_when == run_on_init )
@@ -1463,7 +1505,7 @@ void IDAPython_Term(void)
14631505 deinit_pywraps ();
14641506
14651507 // Uninstall IDC function
1466- set_idc_func (S_IDC_RUNPYTHON_STATEMENT, NULL , NULL );
1508+ set_idc_func_ex (S_IDC_RUNPYTHON_STATEMENT, NULL , NULL , 0 );
14671509
14681510 // Shut the interpreter down
14691511 Py_Finalize ();
0 commit comments