void ScriptController::clearWindowShell(bool goingIntoPageCache) { if (m_windowShells.isEmpty()) return; JSLock lock(SilenceAssertionsOnly); for (ShellMap::iterator iter = m_windowShells.begin(); iter != m_windowShells.end(); ++iter) { JSDOMWindowShell* windowShell = iter->second.get(); // Clear the debugger from the current window before setting the new window. attachDebugger(windowShell, 0); windowShell->window()->willRemoveFromWindowShell(); windowShell->setWindow(m_frame->domWindow()); // An m_cacheableBindingRootObject persists between page navigations // so needs to know about the new JSDOMWindow. if (m_cacheableBindingRootObject) m_cacheableBindingRootObject->updateGlobalObject(windowShell->window()); if (Page* page = m_frame->page()) { attachDebugger(windowShell, page->debugger()); windowShell->window()->setProfileGroup(page->group().identifier()); } } // It's likely that resetting our windows created a lot of garbage, unless // it went in a back/forward cache. if (!goingIntoPageCache) gcController().garbageCollectSoon(); }
JSDOMWindowShell* ScriptController::initScript(DOMWrapperWorld& world) { ASSERT(!m_windowShells.contains(&world)); JSLockHolder lock(world.vm()); JSDOMWindowShell* windowShell = createWindowShell(world); windowShell->window()->updateDocument(); if (m_frame.document()) { bool shouldBypassMainWorldContentSecurityPolicy = !world.isNormal(); if (shouldBypassMainWorldContentSecurityPolicy) windowShell->window()->setEvalEnabled(true); else windowShell->window()->setEvalEnabled(m_frame.document()->contentSecurityPolicy()->allowEval(0, shouldBypassMainWorldContentSecurityPolicy, ContentSecurityPolicy::ReportingStatus::SuppressReport), m_frame.document()->contentSecurityPolicy()->evalDisabledErrorMessage()); } if (Page* page = m_frame.page()) { attachDebugger(windowShell, page->debugger()); windowShell->window()->setProfileGroup(page->group().identifier()); windowShell->window()->setConsoleClient(&page->console()); } m_frame.loader().dispatchDidClearWindowObjectInWorld(world); return windowShell; }
void ScriptController::clearWindowShell(DOMWindow* newDOMWindow, bool goingIntoPageCache) { if (m_windowShells.isEmpty()) return; JSLockHolder lock(JSDOMWindowBase::commonVM()); Vector<JSC::Strong<JSDOMWindowShell>> windowShells = this->windowShells(); for (size_t i = 0; i < windowShells.size(); ++i) { JSDOMWindowShell* windowShell = windowShells[i].get(); if (&windowShell->window()->wrapped() == newDOMWindow) continue; // Clear the debugger and console from the current window before setting the new window. attachDebugger(windowShell, nullptr); windowShell->window()->setConsoleClient(nullptr); // FIXME: We should clear console profiles for each frame as soon as the frame is destroyed. // Instead of clearing all of them when the main frame is destroyed. if (m_frame.isMainFrame()) { if (Page* page = m_frame.page()) page->console().clearProfiles(); } windowShell->window()->willRemoveFromWindowShell(); windowShell->setWindow(newDOMWindow); // An m_cacheableBindingRootObject persists between page navigations // so needs to know about the new JSDOMWindow. if (m_cacheableBindingRootObject) m_cacheableBindingRootObject->updateGlobalObject(windowShell->window()); if (Page* page = m_frame.page()) { attachDebugger(windowShell, page->debugger()); windowShell->window()->setProfileGroup(page->group().identifier()); windowShell->window()->setConsoleClient(&page->console()); } } // It's likely that resetting our windows created a lot of garbage, unless // it went in a back/forward cache. if (!goingIntoPageCache) collectGarbageAfterWindowShellDestruction(); }
void ScriptController::initScript() { if (m_windowShell) return; JSLock lock; m_windowShell = new JSDOMWindowShell(m_frame->domWindow()); updateDocument(); if (Page* page = m_frame->page()) { attachDebugger(page->debugger()); m_windowShell->window()->setPageGroupIdentifier(page->group().identifier()); } m_frame->loader()->dispatchWindowObjectAvailable(); }
void ScriptController::clear() { if (!m_windowShell) return; JSLock lock; m_windowShell->window()->clear(); m_liveFormerWindows.add(m_windowShell->window()); m_windowShell->setWindow(new JSDOMWindow(m_frame->domWindow(), m_windowShell)); if (Page* page = m_frame->page()) { attachDebugger(page->debugger()); m_windowShell->window()->setPageGroupIdentifier(page->group().identifier()); } // There is likely to be a lot of garbage now. gcController().garbageCollectSoon(); }
QSEngineImp::~QSEngineImp() { #if defined (QT_THREAD_SUPPORT) && QT_VERSION >= 0x030300 QMutexLocker locker(qt_global_mutexpool ? qt_global_mutexpool->get(qApp) : 0); #endif #ifdef QSDEBUGGER attachDebugger(0L); #endif clear(); // are we the last of our kind ? Free global stuff. if (instances == 1) globalClear(); instances--; }
JSDOMWindowShell* ScriptController::initScript(DOMWrapperWorld* world) { ASSERT(!m_windowShells.contains(world)); JSLock lock(SilenceAssertionsOnly); JSDOMWindowShell* windowShell = createWindowShell(world); windowShell->window()->updateDocument(); if (Page* page = m_frame->page()) { attachDebugger(windowShell, page->debugger()); windowShell->window()->setProfileGroup(page->group().identifier()); } m_frame->loader()->dispatchDidClearWindowObjectInWorld(world); return windowShell; }
CCompilerSet::CCompilerSet(QObject *parent) : QObject(parent) , m_countOfSuccessful(0) , m_countOfFailure(0) { QUuid uuid = QUuid::createUuid(); m_server = new QLocalServer(this); if( !m_server->listen("hspide." + uuid.toString()) ) { } connect(m_server, SIGNAL(newConnection()), this, SLOT(attachDebugger())); setCompilerSlotNum(1); // 設定の変更通史の登録と設定からの初期化処理 connect(theConf, SIGNAL(updateConfiguration(const Configuration*)), this, SLOT(updateConfiguration(const Configuration*))); updateConfiguration(theConf); }
JSDOMWindowShell* ScriptController::initScript(DOMWrapperWorld* world) { ASSERT(!m_windowShells.contains(world)); JSLockHolder lock(world->globalData()); JSDOMWindowShell* windowShell = createWindowShell(world); windowShell->window()->updateDocument(); if (m_frame->document()) windowShell->window()->setEvalEnabled(m_frame->document()->contentSecurityPolicy()->allowEval(0, ContentSecurityPolicy::SuppressReport)); if (Page* page = m_frame->page()) { attachDebugger(windowShell, page->debugger()); windowShell->window()->setProfileGroup(page->group().identifier()); } m_frame->loader()->dispatchDidClearWindowObjectInWorld(world); return windowShell; }
JSDOMWindowShell* ScriptController::initScript(DOMWrapperWorld& world) { ASSERT(!m_windowShells.contains(&world)); JSLockHolder lock(world.vm()); JSDOMWindowShell& windowShell = createWindowShell(world); windowShell.window()->updateDocument(); if (Document* document = m_frame.document()) document->contentSecurityPolicy()->didCreateWindowShell(windowShell); if (Page* page = m_frame.page()) { attachDebugger(&windowShell, page->debugger()); windowShell.window()->setProfileGroup(page->group().identifier()); windowShell.window()->setConsoleClient(&page->console()); } m_frame.loader().dispatchDidClearWindowObjectInWorld(world); return &windowShell; }
void ScriptController::attachDebugger(JSC::Debugger* debugger) { for (ShellMap::iterator iter = m_windowShells.begin(); iter != m_windowShells.end(); ++iter) attachDebugger(iter->second.get(), debugger); }
void ScriptController::attachDebugger(JSC::Debugger* debugger) { Vector<JSC::Strong<JSDOMWindowShell>> windowShells = this->windowShells(); for (size_t i = 0; i < windowShells.size(); ++i) attachDebugger(windowShells[i].get(), debugger); }
int main(int argc, char *argv[]) { BOOL bDebug = FALSE; BOOL bAttach = FALSE; DWORD dwProcessId = 0; DWORD dwThreadId = 0; char cVerbosity = 0; const char *szDll = NULL; int option_index = 0; while (true) { int opt = getopt_long_only(argc, argv, short_options, long_options, &option_index); if (opt == -1) { break; } switch (opt) { case 'h': help(); return 0; case 'd': bDebug = TRUE; break; case 'D': szDll = optarg; break; case 'p': dwProcessId = strtoul(optarg, NULL, 0); bAttach = TRUE; break; case 't': dwThreadId = strtoul(optarg, NULL, 0); bAttach = TRUE; break; case 'v': ++cVerbosity; break; default: debugPrintf("inject: invalid option '%c'\n", optopt); help(); return 1; } } if (!bAttach) { if (argc - optind < 1) { debugPrintf("inject: error: insufficient number of arguments\n"); help(); return 1; } if (isNumber(argv[optind])) { dwProcessId = atol(argv[optind]); bAttach = TRUE; } else if (argv[optind][0] == '!') { const char *szProcessName = &argv[optind][1]; dwProcessId = getProcessIdByName(szProcessName); if (!dwProcessId) { debugPrintf("error: failed to find process %s\n", szProcessName); return 1; } bAttach = TRUE; } } if (!szDll) { debugPrintf("inject: error: DLL not specificed\n"); help(); return 1; } HANDLE hSemaphore = NULL; if (!USE_SHARED_MEM) { SetEnvironmentVariableA("INJECT_DLL", szDll); } else { hSemaphore = CreateSemaphore(NULL, 1, 1, "inject_semaphore"); if (hSemaphore == NULL) { debugPrintf("error: failed to create semaphore\n"); return 1; } DWORD dwWait = WaitForSingleObject(hSemaphore, 0); if (dwWait == WAIT_TIMEOUT) { debugPrintf("info: waiting for another inject instance to finish\n"); dwWait = WaitForSingleObject(hSemaphore, INFINITE); } if (dwWait != WAIT_OBJECT_0) { debugPrintf("error: failed to enter semaphore gate\n"); return 1; } SharedMem *pSharedMem = OpenSharedMemory(); if (!pSharedMem) { debugPrintf("error: failed to open shared memory\n"); return 1; } pSharedMem->cVerbosity = cVerbosity; strncpy(pSharedMem->szDllName, szDll, _countof(pSharedMem->szDllName) - 1); pSharedMem->szDllName[_countof(pSharedMem->szDllName) - 1] = '\0'; } BOOL bAttachDwm = FALSE; PROCESS_INFORMATION processInfo; HANDLE hProcess; if (bAttach) { BOOL bRet; HANDLE hToken = NULL; bRet = OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &hToken); if (!bRet) { debugPrintf("error: OpenProcessToken returned %u\n", (unsigned)bRet); return 1; } LUID Luid; bRet = LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &Luid); if (!bRet) { debugPrintf("error: LookupPrivilegeValue returned %u\n", (unsigned)bRet); return 1; } TOKEN_PRIVILEGES tp; tp.PrivilegeCount = 1; tp.Privileges[0].Luid = Luid; tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; bRet = AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof tp, NULL, NULL); if (!bRet) { debugPrintf("error: AdjustTokenPrivileges returned %u\n", (unsigned)bRet); return 1; } DWORD dwDesiredAccess = PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_QUERY_LIMITED_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ | PROCESS_TERMINATE; hProcess = OpenProcess( dwDesiredAccess, FALSE /* bInheritHandle */, dwProcessId); if (!hProcess) { logLastError("failed to open process"); return 1; } char szProcess[MAX_PATH]; DWORD dwRet = GetModuleFileNameEx(hProcess, 0, szProcess, sizeof szProcess); assert(dwRet); if (dwRet && stricmp(getBaseName(szProcess), "dwm.exe") == 0) { bAttachDwm = TRUE; } } else { std::string commandLine; char sep = 0; for (int i = optind; i < argc; ++i) { const char *arg = argv[i]; if (sep) { commandLine.push_back(sep); } if (needsQuote(arg)) { quoteArg(commandLine, arg); } else { commandLine.append(arg); } sep = ' '; } STARTUPINFO startupInfo; memset(&startupInfo, 0, sizeof startupInfo); startupInfo.cb = sizeof startupInfo; // Create the process in suspended state if (!CreateProcessA( NULL, const_cast<char *>(commandLine.c_str()), // only modified by CreateProcessW 0, // process attributes 0, // thread attributes TRUE, // inherit handles CREATE_SUSPENDED, NULL, // environment NULL, // current directory &startupInfo, &processInfo)) { DWORD dwLastError = GetLastError(); fprintf(stderr, "inject: error: failed to execute %s (%lu)\n", commandLine.c_str(), dwLastError); if (dwLastError == ERROR_ELEVATION_REQUIRED) { fprintf(stderr, "error: target program requires elevated priviledges and must be started from an Administrator Command Prompt, or UAC must be disabled\n"); } return 1; } hProcess = processInfo.hProcess; } /* * XXX: Mixed architecture don't quite work. See also * http://www.corsix.org/content/dll-injection-and-wow64 */ { typedef BOOL (WINAPI *PFNISWOW64PROCESS)(HANDLE, PBOOL); PFNISWOW64PROCESS pfnIsWow64Process; pfnIsWow64Process = (PFNISWOW64PROCESS) GetProcAddress(GetModuleHandleA("kernel32"), "IsWow64Process"); if (pfnIsWow64Process) { BOOL isParentWow64 = FALSE; BOOL isChildWow64 = FALSE; if (pfnIsWow64Process(GetCurrentProcess(), &isParentWow64) && pfnIsWow64Process(hProcess, &isChildWow64) && isParentWow64 != isChildWow64) { debugPrintf("error: binaries mismatch: you need to use the " #ifdef _WIN64 "32-bits" #else "64-bits" #endif " apitrace binaries to trace this application\n"); TerminateProcess(hProcess, 1); return 1; } } } if (bAttachDwm && IsWindows8OrGreater()) { // Switch to Microsoft Basic Display Driver before injecting, so that // we don't trace with it. devconDisable(DEVCON_CLASS_DISPLAY); Sleep(1000); } const char *szDllName; szDllName = "injectee.dll"; char szDllPath[MAX_PATH]; GetModuleFileNameA(NULL, szDllPath, sizeof szDllPath); getDirName(szDllPath); strncat(szDllPath, szDllName, sizeof szDllPath - strlen(szDllPath) - 1); if (bDebug) { if (!attachDebugger(GetProcessId(hProcess))) { if (!bAttach) { TerminateProcess(hProcess, 1); } return 1; } } #if 1 if (!injectDll(hProcess, szDllPath)) { if (!bAttach) { TerminateProcess(hProcess, 1); } return 1; } #endif DWORD exitCode; if (bAttach) { if (bAttachDwm) { restartDwmComposition(hProcess); } else { fprintf(stderr, "Press any key when finished tracing\n"); getchar(); ejectDll(hProcess, szDllPath); } if (dwThreadId) { HANDLE hThread = OpenThread(THREAD_SUSPEND_RESUME, TRUE, dwThreadId); if (hThread) { ResumeThread(hThread); WaitForSingleObject(hThread, INFINITE); CloseHandle(hThread); } else { debugPrintf("inject: failed to open thread %lu\n", dwThreadId); } return 0; } exitCode = 0; } else { // Start main process thread ResumeThread(processInfo.hThread); // Wait for it to finish WaitForSingleObject(hProcess, INFINITE); if (pSharedMem && !pSharedMem->bReplaced) { debugPrintf("warning: %s was never used: application probably does not use this API\n", szDll); } exitCode = ~0; GetExitCodeProcess(hProcess, &exitCode); CloseHandle(processInfo.hThread); } CloseHandle(hProcess); if (hSemaphore) { ReleaseSemaphore(hSemaphore, 1, NULL); CloseHandle(hSemaphore); } return (int)exitCode; }