Пример #1
0
    def SvcDoRun(self):
        if hasattr(sys, "frozen"):
            this_dir = os.path.dirname(win32api.GetModuleFileName(None))
        else:
            this_dir = os.path.dirname(os.path.abspath(__file__))
        # TODO: maybe it is better to run this in a job object too
        with open(os.path.join(this_dir, 'npm.log'), 'w') as npm_log:
            subprocess.check_call('npm install',
                                  cwd=this_dir,
                                  shell=True,
                                  stdin=None,
                                  stdout=npm_log,
                                  stderr=subprocess.STDOUT)

        security_attributes = win32security.SECURITY_ATTRIBUTES()
        security_attributes.bInheritHandle = True
        startup = win32process.STARTUPINFO()
        startup.dwFlags |= win32process.STARTF_USESTDHANDLES
        startup.hStdInput = None
        startup.hStdOutput = win32file.CreateFile(
            os.path.join(this_dir, "service_stderr.log"),
            win32file.GENERIC_WRITE, win32file.FILE_SHARE_READ,
            security_attributes, win32file.CREATE_ALWAYS, 0, None)
        startup.hStdError = win32file.CreateFile(
            os.path.join(this_dir, "service_stdout.log"),
            win32file.GENERIC_WRITE, win32file.FILE_SHARE_READ,
            security_attributes, win32file.CREATE_ALWAYS, 0, None)
        (hProcess, hThread, processId, threadId) = win32process.CreateProcess(
            None, r'"C:\Program Files\nodejs\node.exe" node_worker.js', None,
            None, True, win32process.CREATE_SUSPENDED
            | win32process.CREATE_BREAKAWAY_FROM_JOB, None, this_dir, startup)

        assert not win32job.IsProcessInJob(hProcess, None)

        self.hJob = win32job.CreateJobObject(None, "")
        extended_info = win32job.QueryInformationJobObject(
            self.hJob, win32job.JobObjectExtendedLimitInformation)
        extended_info['BasicLimitInformation'][
            'LimitFlags'] = win32job.JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE | win32job.JOB_OBJECT_LIMIT_BREAKAWAY_OK
        win32job.SetInformationJobObject(
            self.hJob, win32job.JobObjectExtendedLimitInformation,
            extended_info)
        win32job.AssignProcessToJobObject(self.hJob, hProcess)

        win32process.ResumeThread(hThread)
        win32api.CloseHandle(hThread)

        signalled = win32event.WaitForMultipleObjects(
            [self.hWaitStop, hProcess], False, win32event.INFINITE)
        if signalled == win32event.WAIT_OBJECT_0 + 1 and win32process.GetExitCodeProcess(
                hProcess) != 0:
            servicemanager.LogErrorMsg(
                self._svc_name_ + " process exited with non-zero status " +
                str(win32process.GetExitCodeProcess(hProcess)))
        win32api.CloseHandle(hProcess)
        win32api.CloseHandle(self.hJob)
        win32api.CloseHandle(self.hWaitStop)
        win32api.CloseHandle(startup.hStdOutput)
        win32api.CloseHandle(startup.hStdError)
Пример #2
0
 def resume_thread(hThread):
     """
 @param   hThread  HANDLE
 @return  bool
 """
     try:
         return win32process.ResumeThread(hThread) >= 0
         #except pywintypes.error, e:
     except Exception, e:
         dwarn(e)
         return False
Пример #3
0
 def onKeyboardEvent(self, event):
     if event.Key == 'F9':
         thread.start_new_thread(self.change_argv, ())
     if event.Key == 'F10':
         if self.suspended:
             print "Press F10 to pause."
             win32process.ResumeThread(self.handle)
             self.suspended = False
         else:
             print "Press F10 to continue."
             win32process.SuspendThread(self.handle)
             self.suspended = True
     if event.Key == 'F8':
         win32api.PostThreadMessage(win32api.GetCurrentThreadId(),
                                    win32con.WM_QUIT, 0, 0)
     if event.Key == 'F12':
         print 'killed thread'
         self.suspended = False
         terminate_thread(int(self.tid))
         self.handle, self.tid = win32process.beginthreadex(
             None, 0, self.main, (), 0)
     return True
Пример #4
0
def main():
    # escape list of arguments
    command = _win32_arglist_to_string(sys.argv[1:])

    # create job
    hJob = win32job.CreateJobObject(None, '')
    extended_info = win32job.QueryInformationJobObject(
        hJob, win32job.JobObjectExtendedLimitInformation)
    extended_info['BasicLimitInformation'][
        'LimitFlags'] = win32job.JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE
    win32job.SetInformationJobObject(
        hJob, win32job.JobObjectExtendedLimitInformation, extended_info)

    # associate job with completion port
    hIoPort = win32file.CreateIoCompletionPort(win32file.INVALID_HANDLE_VALUE,
                                               None, 0, 1)
    # pywin32 is missing support for JOBOBJECT_ASSOCIATE_COMPLETION_PORT, therefore
    #   we call it through ctypes
    port = JOBOBJECT_ASSOCIATE_COMPLETION_PORT()
    port.CompletionKey = hJob.handle
    port.CompletionPort = hIoPort.handle
    assert bool(
        ctypes.windll.kernel32.SetInformationJobObject(
            ctypes.wintypes.HANDLE(hJob.handle),
            ctypes.c_int(JobObjectAssociateCompletionPortInformation),
            ctypes.byref(port),
            ctypes.sizeof(JOBOBJECT_ASSOCIATE_COMPLETION_PORT)))

    # create process suspended
    si = win32process.STARTUPINFO()
    hProcess, hThread, processId, threadId = win32process.CreateProcess(
        None, command, None, None, True,
        win32process.CREATE_BREAKAWAY_FROM_JOB | win32process.CREATE_SUSPENDED,
        None, None, si)

    # add process to job
    win32job.AssignProcessToJobObject(hJob, hProcess)

    # resume process
    win32process.ResumeThread(hThread)
    win32api.CloseHandle(hThread)
    win32api.CloseHandle(hProcess)

    # wait for job termination
    numberOfBytes = ctypes.wintypes.DWORD(0)
    completionKey = ctypes.wintypes.HANDLE(0)
    overlapped = OVERLAPPED()
    while True:
        # calling this through pywin32 crashes the program, therefore we call it through ctypes
        res = bool(
            ctypes.windll.kernel32.GetQueuedCompletionStatus(
                ctypes.wintypes.HANDLE(hIoPort.handle),
                ctypes.byref(numberOfBytes), ctypes.byref(completionKey),
                ctypes.byref(overlapped),
                ctypes.wintypes.DWORD(win32event.INFINITE)))
        if not res or (bytes(completionKey) == bytes(
                ctypes.c_void_p(hJob.handle))
                       and bytes(numberOfBytes) == bytes(
                           ctypes.c_ulong(
                               win32job.JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO))):
            break
Пример #5
0
    def startBackgroundProcess(self):
        """Method to start a process running in the background.
		
		"""
        with process_lock:
            # security attributes for pipes
            sAttrs = win32security.SECURITY_ATTRIBUTES()
            sAttrs.bInheritHandle = 1

            # create pipes for the process to write to
            hStdin_r, hStdin = win32pipe.CreatePipe(sAttrs, 0)
            hStdout = win32file.CreateFile(
                self.stdout, win32file.GENERIC_WRITE | win32file.GENERIC_READ,
                win32file.FILE_SHARE_DELETE | win32file.FILE_SHARE_READ
                | win32file.FILE_SHARE_WRITE, sAttrs, win32file.CREATE_ALWAYS,
                win32file.FILE_ATTRIBUTE_NORMAL, None)
            hStderr = win32file.CreateFile(
                self.stderr, win32file.GENERIC_WRITE | win32file.GENERIC_READ,
                win32file.FILE_SHARE_DELETE | win32file.FILE_SHARE_READ
                | win32file.FILE_SHARE_WRITE, sAttrs, win32file.CREATE_ALWAYS,
                win32file.FILE_ATTRIBUTE_NORMAL, None)

            try:

                # set the info structure for the new process.
                StartupInfo = win32process.STARTUPINFO()
                StartupInfo.hStdInput = hStdin_r
                StartupInfo.hStdOutput = hStdout
                StartupInfo.hStdError = hStderr
                StartupInfo.dwFlags = win32process.STARTF_USESTDHANDLES

                # Create new handles for the thread ends of the pipes. The duplicated handles will
                # have their inheritence properties set to false so that any children inheriting these
                # handles will not have non-closeable handles to the pipes
                pid = win32api.GetCurrentProcess()
                tmp = win32api.DuplicateHandle(pid, hStdin, pid, 0, 0,
                                               win32con.DUPLICATE_SAME_ACCESS)
                win32file.CloseHandle(hStdin)
                hStdin = tmp

                # start the process, and close down the copies of the process handles
                # we have open after the process creation (no longer needed here)
                old_command = command = self.__quotePath(self.command)
                for arg in self.arguments:
                    command = '%s %s' % (command, self.__quotePath(arg))

                # Windows CreateProcess maximum lpCommandLine length is 32,768
                # http://msdn.microsoft.com/en-us/library/ms682425%28VS.85%29.aspx
                if len(command) >= 32768:  # pragma: no cover
                    raise ValueError(
                        "Command line length exceeded 32768 characters: %s..."
                        % command[:1000])

                dwCreationFlags = 0
                if IS_PRE_WINDOWS_8:  # pragma: no cover
                    # In case PySys is itself running in a job, might need to explicitly breakaway from it so we can give
                    # it its own, but only for old pre-windows 8/2012, which support nested jobs
                    dwCreationFlags = dwCreationFlags | win32process.CREATE_BREAKAWAY_FROM_JOB

                if self.command.lower().endswith(('.bat', '.cmd')):
                    # If we don't start suspended there's a slight race condition but due to some issues with
                    # initially-suspended processes hanging (seen many years ago), to be safe, only bother to close the
                    # race condition for shell scripts (which is the main use case for this anyway)
                    dwCreationFlags = dwCreationFlags | win32con.CREATE_SUSPENDED

                self.__job = self._createParentJob()

                try:
                    self.__hProcess, self.__hThread, self.pid, self.__tid = win32process.CreateProcess(
                        None, command, None, None, 1,
                        dwCreationFlags, self.environs,
                        os.path.normpath(self.workingDir), StartupInfo)
                except pywintypes.error as e:
                    raise ProcessError("Error creating process %s: %s" %
                                       (old_command, e))

                try:
                    if not self.disableKillingChildProcesses:
                        win32job.AssignProcessToJobObject(
                            self.__job, self.__hProcess)
                    else:
                        self.__job = None  # pragma: no cover
                except Exception as e:  # pragma: no cover
                    # Shouldn't fail unless process already terminated (which can happen since
                    # if we didn't use SUSPENDED there's an inherent race here)
                    if win32process.GetExitCodeProcess(
                            self.__hProcess) == win32con.STILL_ACTIVE:
                        log.warning(
                            'Failed to associate process %s with new job: %s (this may prevent automatic cleanup of child processes)'
                            % (self, e))

                    # force use of TerminateProcess not TerminateJobObject if this failed
                    self.__job = None

                if (dwCreationFlags & win32con.CREATE_SUSPENDED) != 0:
                    win32process.ResumeThread(self.__hThread)
            finally:
                win32file.CloseHandle(hStdin_r)
                win32file.CloseHandle(hStdout)
                win32file.CloseHandle(hStderr)

            # set the handle to the stdin of the process
            self.__stdin = hStdin
Пример #6
0
 def resume_child(self):
     """Un-pauses the main thread of the child process."""
     handle = windll.kernel32.OpenThread(win32con.THREAD_SUSPEND_RESUME, 0,
                                         self.child_tid)
     win32process.ResumeThread(handle)
Пример #7
0
 def CreateProcess(self, *args, **kwargs):
     hp, ht, pid, tid = self._oldapi.CreateProcess(*args, **kwargs)
     win32job.AssignProcessToJobObject(self._job, hp)
     win32process.ResumeThread(ht)
     return hp, ht, pid, tid
Пример #8
0
 def change_argv(self):
     win32process.SuspendThread(self.handle)
     self.new_argv = raw_input("\r\nInput argument:")
     win32process.ResumeThread(self.handle)
Пример #9
0
    sys.exit(30)

hProcess = processInfo[0]

#### Associate the process with the job

try:
    win32job.AssignProcessToJobObject(hJob, hProcess)
except pywintypes.error, e:
    print 'AssignProcessToJobObject failed, err=%s' % e[0]
    sys.exit(33)

#### Resume the process

hThread = processInfo[1]
if not win32process.ResumeThread(hThread):
    print 'ResumeThread failed, err=%s' % e[0]
    sys.exit(36)

win32api.CloseHandle(hThread)

#### Wait on the process and get the exit code

try:
    win32event.WaitForSingleObject(hProcess, win32event.INFINITE)
except pywintypes.error, e:
    print 'WaitForSingleObject failed, err=%s' % e[0]
    sys.exit(40)

exitCode = win32process.GetExitCodeProcess(hProcess)
Пример #10
0
        si.hStdInput=pp[0]
        si.hStdOutput=pp[1]
        si.hStdError=pp[2]

    si.wShowWindow=win32con.SW_HIDE
    si.dwFlags = win32process.STARTF_USESHOWWINDOW | win32con.STARTF_USESTDHANDLES
    cmd=" ".join(argv)
    win32api.SetLastError(0)
    #PyHANDLE, PyHANDLE, int, int = CreateProcess(appName, commandLine , processAttributes , threadAttributes , bInheritHandles , dwCreationFlags , newEnvironment , currentDirectory , startupinfo )
    try:
        pi= win32process.CreateProcess(None,cmd,None,None,True,win32con.CREATE_SUSPENDED,None,RootDir,si)
    except pywintypes.error , e:
        ret[1]=e[2]
        return ret
    #pi  (hProcess, hThread, dwProcessId, dwThreadId)
    win32process.ResumeThread(pi[1]) #hThread
    win32api.CloseHandle(pi[1])

    while True:
        exitCode=win32process.GetExitCodeProcess(pi[0])
        pmc=win32process.GetProcessMemoryInfo(pi[0])
        ft=win32process.GetProcessTimes(pi[0])
        ret[3]=mem = round(float(pmc["PeakPagefileUsage"]) / 1024 / 1024,2)
        ret[2]=time= round(float(ft["UserTime"]) / WIN32_PROCESS_TIMES_TICKS_PER_SECOND,2)
        print exitCode,ret
        if limit is not None and time>limit[0]:
            ret[1]=u"超过时间限制"
            CloseProcess(pi)
            return ret
        if limit is not None and mem>limit[1]:
            ret[1]=u"超过内存限制"
Пример #11
0
    def each_with_type(self, target, file_type):
        self.process_created = threading.Event()

        self.paths = {
            "word": "{}\\{}".format(self.office_path, "WINWORD.EXE"),
            "rtf": "{}\\{}".format(self.office_path, "WINWORD.EXE"),
            "html": "{}\\{}".format(self.office_path, "WINWORD.EXE"),
            "excel": "{}\\{}".format(self.office_path, "EXCEL.EXE"),
            "powerpoint": "{}\\{}".format(self.office_path, "POWERPOINT.EXE"),
            "javascript": "C:\\Windows\\system32\\wscript.exe",
            "vbscript": "C:\\Windows\\system32\\wscript.exe",
        }

        self.files = set()
        self.results = {"actions": []}

        monkey = ClickThread()
        monkey.click_on(
            "Microsoft Excel",
            "Yes",
            "is in a different format than specified by the file extension",
        )
        monkey.click_on(
            "Microsoft Word", "OK",
            "command cannot be performed because a dialog box is open")
        monkey.click_on("Microsoft Word", "No", "start Word in safe mode")
        monkey.click_on("Microsoft Word", "Yes", "caused a serious error")
        monkey.click_on("File In Use", "OK", "locked for editing")
        monkey.click_on("Microsoft Word", "Yes",
                        "that may refer to other files")
        monkey.click_on("Microsoft Excel", "Yes",
                        "that may refer to other files")
        monkey.click_on("Microsoft Word", "Yes", "Do you want to start")
        monkey.click_on("Microsoft Excel", "Yes", "Do you want to start")
        monkey.close("Activation Wizard")
        monkey.start()

        try:
            target = self.set_extension(target, file_type)
            executable = self.paths[file_type]
            cmdline = "\"{}\" \"{}\"".format(executable, target)

            # Start the process in a paused state
            process = win32process.CreateProcess(
                executable,
                cmdline,
                None,
                None,
                False,
                win32process.CREATE_SUSPENDED,
                None,
                None,
                win32process.STARTUPINFO(),
            )

            # Add hooks with Frida to trace interesting API calls
            session = frida.attach(process[2])
            script = session.create_script(FRIDA_SCRIPT)
            script.on('message', self.callback)
            script.load()

            # Resume the process so that it executes
            win32process.ResumeThread(process[1])

            # Let the process execute for a while
            if self.stop_on_process_creation:
                self.process_created.wait(self.timeout)
            else:
                sleep(self.timeout)

            # Stop Frida session and kill process
            session.detach()
            win32api.TerminateProcess(process[0], -1)
        finally:
            monkey.stop()
            monkey.join()

        for i, dropped_file in enumerate(self.files):
            if self.add_to_support_files:
                basename = dropped_file.split("\\")[-1].split("/")[-1]
                self.add_support_file("{}_{}".format(i, basename),
                                      dropped_file)
            if self.add_to_extracted_files:
                self.add_extracted_file(dropped_file)
        del self.files

        # Restore the VM if we did not catch a process creation
        if not self.process_created.is_set():
            self.should_restore = True

        return len(self.results["actions"]) > 0