MainMenuWindow::MainMenuWindow(MainMenuEngineWindow* enginewindow) : AbstractWindow("mainmenuwindow.xml", WIT_MOUSE_INPUT, false, false), mActiveModule(NULL), mEngineWindow(enginewindow) { getWindow("MainMenu/Game/Start")->subscribeEvent( MenuItem::EventClicked, boost::bind(&MainMenuWindow::handleStart, this)); getWindow("MainMenu/Game/Load")->subscribeEvent( MenuItem::EventClicked, boost::bind(&MainMenuWindow::handleLoad, this)); getWindow("MainMenu/Game/Quit")->subscribeEvent( MenuItem::EventClicked, boost::bind(&MainMenuWindow::handleQuit, this)); getWindow("MainMenu/Options")->subscribeEvent( MenuItem::EventClicked, boost::bind(&MainMenuWindow::handleSettings, this)); fillModules(); mWindow->moveToBack(); }
/** * Attaches to the target process. * * @param tids The thread IDs of the threads that belong to the target process. * * @return A NaviError code that describes whether the operation was successful or not. */ NaviError LinuxSystem::attachToProcess() { msglog->log(LOG_VERBOSE, "Trying to attach to process %d", getPID()); int result = ptrace(PTRACE_ATTACH, getPID(), 0, 0); if (result) { msglog->log(LOG_ALWAYS, "Error: Couldn't attach to process"); return errno; } // TODO: Right now multi-threading is not supported Thread ts(getPID(), SUSPENDED); tids.push_back(ts); setActiveThread (getPID()); std ::string path; NaviError pathError = getExecutablePath(getPID(), path); if (pathError) { msglog->log( LOG_ALWAYS, "Error: Unable to determine the executable path of the debuggee."); return pathError; } // Generate processStart message and send it to BinNavi. fillModules(getPID(), this->modules); std::map<std::string, Module>::const_iterator cit = this->modules.find(path); if (cit != this->modules.end()) { Module processModule = cit->second; processStart(processModule, ts); } else { msglog->log(LOG_ALWAYS, "Error: Unable to determine main process module for '%s'", path.c_str()); exit(0); } return NaviErrors::SUCCESS; }
/** * Starts a new process for debugging. * * @param path The path to the executable of the process. * @param tids The thread IDs of the threads that belong to the target process. * * @return A NaviError code that describes whether the operation was successful or not. */ NaviError LinuxSystem::startProcess( const NATIVE_STRING path, const std::vector<const NATIVE_STRING>& commands) { pid_t pid = fork(); if (pid == -1) { msglog->log(LOG_ALWAYS, "Error: Couldn't fork process"); return NaviErrors::COULDNT_OPEN_TARGET_PROCESS; } else if (pid == 0) { ptrace(PTRACE_TRACEME, 0, 0, 0); char** child_arguments = new char*[1 + commands.size() + 1]; child_arguments[0] = new char[strlen(path) + 1]; strcpy(child_arguments[0], path); for (unsigned int i = 0; i < commands.size(); i++) { child_arguments[i + 1] = new char[strlen(commands[i]) + 1]; strcpy(child_arguments[i + 1], commands[i]); } child_arguments[1 + commands.size()] = 0; // Child process if (execvp(path, child_arguments) == -1) { msglog->log(LOG_ALWAYS, "Error: Could not start the child process '%s'", path); exit(0); } return NaviErrors::SUCCESS; } else { int status; if (waitpid(pid, &status, __WALL) == -1) { msglog->log(LOG_ALWAYS, "Error: Wait for target process failed '%s'", path); exit(0); } if (WIFSTOPPED(status)) { if (WSTOPSIG(status) == SIGTRAP) { msglog->log(LOG_VERBOSE, "Initial STOP signal received"); } else { msglog->log(LOG_ALWAYS, "Error: Received unexpected STOP signal"); exit(0); } } else { msglog->log(LOG_ALWAYS, "Error: Did not receive initial STOP signal"); exit(0); } if (ptrace( PTRACE_SETOPTIONS, pid, 0, PTRACE_O_TRACECLONE | PTRACE_O_TRACEFORK | PTRACE_O_TRACEVFORK | PTRACE_O_TRACEVFORKDONE) == -1) { msglog->log(LOG_ALWAYS, "Error: Could not set ptrace options"); exit(0); } msglog->log(LOG_VERBOSE, "PID of the child process is %d", pid); setPID(pid); Thread ts(pid, SUSPENDED); tids.push_back(ts); setActiveThread(pid); lastMapFileSize = getFileSize( "/proc/" + zylib::zycon::toString(pid) + "/maps"); fillModules(pid, modules); this->modules = modules; std::map<std::string, Module>::const_iterator cit = this->modules.find( getTargetApplicationPath().string()); if (cit != this->modules.end()) { Module processModule = cit->second; processStart(processModule, ts); } else { msglog->log(LOG_ALWAYS, "Error: Unable to determine main process module for '%s'", getTargetApplicationPath().string().c_str()); exit(0); } return NaviErrors::SUCCESS; } }