/** * Should be called before executing a script */ void XBPython::Initialize() { CLog::Log(LOGINFO, "initializing python engine. "); EnterCriticalSection(&m_critSection); m_iDllScriptCounter++; if (!m_bInitialized) { if (dThreadId == GetCurrentThreadId()) { #ifndef _LINUX //DllLoader* pDll = g_sectionLoader.LoadDLL(PYTHON_DLL); m_hModule = dllLoadLibraryA(PYTHON_DLL); m_pDll = DllLoaderContainer::GetModule(m_hModule); #else m_pDll = DllLoaderContainer::LoadModule(PYTHON_DLL, NULL, true); #endif if (!m_pDll || !python_load_dll(*m_pDll)) { CLog::Log(LOGFATAL, "Python: error loading python24.dll"); Finalize(); LeaveCriticalSection(&m_critSection); return; } // first we check if all necessary files are installed #ifndef _LINUX if (!FileExist("Q:\\system\\python\\python24.zlib") || !FileExist("Q:\\system\\python\\DLLs\\_socket.pyd") || !FileExist("Q:\\system\\python\\DLLs\\_ssl.pyd") || !FileExist("Q:\\system\\python\\DLLs\\bz2.pyd") || !FileExist("Q:\\system\\python\\DLLs\\pyexpat.pyd") || !FileExist("Q:\\system\\python\\DLLs\\select.pyd") || !FileExist("Q:\\system\\python\\DLLs\\unicodedata.pyd") || !FileExist("Q:\\system\\python\\DLLs\\zlib.pyd")) { CLog::Log(LOGERROR, "Python: Missing files, unable to execute script"); Finalize(); LeaveCriticalSection(&m_critSection); return; } #endif #ifdef _LINUX // Required for python to find optimized code (pyo) files setenv("PYTHONOPTIMIZE", "1", 1); setenv("PYTHONHOME", _P("Q:/system/python"), 1); setenv("PYTHONPATH", _P("Q:/system/python/python24.zip"), 1); //setenv("PYTHONDEBUG", "1", 1); //setenv("PYTHONINSPECT", "1", 1); //setenv("PYTHONVERBOSE", "1", 1); setenv("PYTHONCASEOK", "1", 1); #endif #ifdef __APPLE__ setenv("PYTHONHOME", _P("Q:\\system\\python"), 1); #endif Py_Initialize(); PyEval_InitThreads(); char* python_argv[1] = { (char*)"" } ; PySys_SetArgv(1, python_argv); InitXBMCTypes(); InitGUITypes(); InitPluginTypes(); mainThreadState = PyThreadState_Get(); // release the lock PyEval_ReleaseLock(); m_bInitialized = true; PulseEvent(m_hEvent); } else { // only the main thread should initialize python. m_iDllScriptCounter--; LeaveCriticalSection(&m_critSection); WaitForSingleObject(m_hEvent, INFINITE); EnterCriticalSection(&m_critSection); } } LeaveCriticalSection(&m_critSection); }
void Win32DllLoader::OverrideImports(const std::string &dll) { std::wstring strdllW; g_charsetConverter.utf8ToW(CSpecialProtocol::TranslatePath(dll), strdllW, false); BYTE* image_base = (BYTE*)GetModuleHandleW(strdllW.c_str()); if (!image_base) { CLog::Log(LOGERROR, "%s - unable to GetModuleHandle for dll %s", __FUNCTION__, dll.c_str()); return; } PIMAGE_DOS_HEADER dos_header = (PIMAGE_DOS_HEADER)image_base; PIMAGE_NT_HEADERS nt_header = (PIMAGE_NT_HEADERS)(image_base + dos_header->e_lfanew); // e_lfanew = value at 0x3c PIMAGE_IMPORT_DESCRIPTOR imp_desc = (PIMAGE_IMPORT_DESCRIPTOR)( image_base + nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress); if (!imp_desc) { CLog::Log(LOGERROR, "%s - unable to get import directory for dll %s", __FUNCTION__, dll.c_str()); return; } // loop over all imported dlls for (int i = 0; imp_desc[i].Characteristics != 0; i++) { char *dllName = (char*)(image_base + imp_desc[i].Name); // check whether this is one of our dll's. if (NeedsHooking(dllName)) { // this will do a loadlibrary on it, which should effectively make sure that it's hooked // Note that the library has obviously already been loaded by the OS (as it's implicitly linked) // so all this will do is insert our hook and make sure our DllLoaderContainer knows about it HMODULE hModule = dllLoadLibraryA(dllName); if (hModule) m_referencedDlls.push_back(hModule); } PIMAGE_THUNK_DATA orig_first_thunk = (PIMAGE_THUNK_DATA)(image_base + imp_desc[i].OriginalFirstThunk); PIMAGE_THUNK_DATA first_thunk = (PIMAGE_THUNK_DATA)(image_base + imp_desc[i].FirstThunk); // and then loop over all imported functions for (int j = 0; orig_first_thunk[j].u1.Function != 0; j++) { void *fixup = NULL; if (orig_first_thunk[j].u1.Function & 0x80000000) ResolveOrdinal(dllName, (orig_first_thunk[j].u1.Ordinal & 0x7fffffff), &fixup); else { // resolve by name PIMAGE_IMPORT_BY_NAME orig_imports_by_name = (PIMAGE_IMPORT_BY_NAME)( image_base + orig_first_thunk[j].u1.AddressOfData); ResolveImport(dllName, (char*)orig_imports_by_name->Name, &fixup); }/* if (!fixup) { // create a dummy function for tracking purposes PIMAGE_IMPORT_BY_NAME orig_imports_by_name = (PIMAGE_IMPORT_BY_NAME)( image_base + orig_first_thunk[j].u1.AddressOfData); fixup = CreateDummyFunction(dllName, (char*)orig_imports_by_name->Name); }*/ if (fixup) { // save the old function Import import; import.table = &first_thunk[j].u1.Function; import.function = first_thunk[j].u1.Function; m_overriddenImports.push_back(import); DWORD old_prot = 0; // change to protection settings so we can write to memory area VirtualProtect((PVOID)&first_thunk[j].u1.Function, 4, PAGE_EXECUTE_READWRITE, &old_prot); // patch the address of function to point to our overridden version first_thunk[j].u1.Function = (DWORD)fixup; // reset to old settings VirtualProtect((PVOID)&first_thunk[j].u1.Function, 4, old_prot, &old_prot); } } } }
/** * Should be called before executing a script */ void XBPython::Initialize() { CLog::Log(LOGINFO, "initializing python engine. "); CSingleLock lock(m_critSection); m_iDllScriptCounter++; if (!m_bInitialized) { if (dThreadId == GetCurrentThreadId()) { m_hModule = dllLoadLibraryA(PYTHON_DLL); LibraryLoader* pDll = DllLoaderContainer::GetModule(m_hModule); if (!pDll || !python_load_dll(*pDll)) { CLog::Log(LOGFATAL, "Python: error loading python27.dll"); Finalize(); return; } // first we check if all necessary files are installed if (!FileExist("Q:\\system\\python\\python27.zlib") || !FileExist("Q:\\system\\python\\DLLs\\_socket.pyd") || !FileExist("Q:\\system\\python\\DLLs\\_sqlite3.pyd") || !FileExist("Q:\\system\\python\\DLLs\\_ssl.pyd") || !FileExist("Q:\\system\\python\\DLLs\\bz2.pyd") || !FileExist("Q:\\system\\python\\DLLs\\pyexpat.pyd") || !FileExist("Q:\\system\\python\\DLLs\\select.pyd") || !FileExist("Q:\\system\\python\\DLLs\\unicodedata.pyd")) { CLog::Log(LOGERROR, "Python: Missing files, unable to execute script"); Finalize(); return; } Py_Initialize(); PyEval_InitThreads(); if (g_advancedSettings.m_bPythonVerbose) { CLog::Log(LOGDEBUG, "%s - Running Python in verbose(--verbose) mode", __FUNCTION__); char* python_argv[1] = { (char*)"--verbose" }; PySys_SetArgv(1, python_argv); } else { char* python_argv[1] = { (char*)"" }; PySys_SetArgv(1, python_argv); } initxbmc(); // init xbmc modules initxbmcplugin(); // init plugin modules initxbmcgui(); // init xbmcgui modules // redirecting default output to debug console if (PyRun_SimpleString("" "import xbmc\n" "class xbmcout:\n" "\tdef write(self, data):\n" "\t\txbmc.log(data)\n" "\tdef close(self):\n" "\t\txbmc.log('.')\n" "\tdef flush(self):\n" "\t\txbmc.log('.')\n" "\n" "import sys\n" "sys.stdout = xbmcout()\n" "sys.stderr = xbmcout()\n" "print '-->Python Initialized<--'\n" "") == -1) { CLog::Log(LOGFATAL, "Python Initialize Error"); } if (!(mainThreadState = PyThreadState_Get())) CLog::Log(LOGERROR, "Python threadstate is NULL."); PyEval_ReleaseLock(); m_bInitialized = true; bThreadInitialize = false; PulseEvent(m_hEvent); } else { // only the main thread should initialize python. m_iDllScriptCounter--; bThreadInitialize = true; lock.Leave(); WaitForSingleObject(m_hEvent, INFINITE); lock.Enter(); } } }