debugpy 1.8.3__zip → 1.8.6__zip
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {debugpy-1.8.3/src/debugpy.egg-info → debugpy-1.8.6}/PKG-INFO +1 -1
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydev_bundle/_pydev_calltip_util.py +19 -21
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydev_bundle/_pydev_completer.py +30 -30
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydev_bundle/_pydev_execfile.py +3 -1
- debugpy-1.8.6/src/debugpy/_vendored/pydevd/_pydev_bundle/_pydev_filesystem_encoding.py +43 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydev_bundle/_pydev_getopt.py +35 -32
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydev_bundle/_pydev_imports_tipper.py +83 -84
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydev_bundle/_pydev_jy_imports_tipper.py +92 -99
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydev_bundle/_pydev_log.py +2 -3
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydev_bundle/_pydev_saved_modules.py +51 -27
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydev_bundle/_pydev_sys_patch.py +11 -7
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydev_bundle/_pydev_tipper_common.py +6 -5
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydev_bundle/fsnotify/__init__.py +34 -38
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydev_bundle/pydev_console_utils.py +71 -69
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydev_bundle/pydev_import_hook.py +1 -3
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydev_bundle/pydev_imports.py +0 -1
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydev_bundle/pydev_ipython_console.py +14 -16
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydev_bundle/pydev_ipython_console_011.py +81 -93
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydev_bundle/pydev_is_thread_alive.py +3 -3
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydev_bundle/pydev_localhost.py +9 -8
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydev_bundle/pydev_log.py +33 -25
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydev_bundle/pydev_monkey.py +183 -170
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydev_bundle/pydev_monkey_qt.py +33 -29
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydev_bundle/pydev_override.py +6 -4
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydev_bundle/pydev_umd.py +19 -18
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydev_bundle/pydev_versioncheck.py +3 -3
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydev_runfiles/pydev_runfiles.py +165 -138
- debugpy-1.8.6/src/debugpy/_vendored/pydevd/_pydev_runfiles/pydev_runfiles_coverage.py +77 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydev_runfiles/pydev_runfiles_nose.py +35 -36
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydev_runfiles/pydev_runfiles_parallel.py +22 -23
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydev_runfiles/pydev_runfiles_parallel_client.py +37 -57
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydev_runfiles/pydev_runfiles_pytest2.py +54 -52
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydev_runfiles/pydev_runfiles_unittest.py +28 -37
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydev_runfiles/pydev_runfiles_xml_rpc.py +56 -53
- debugpy-1.8.6/src/debugpy/_vendored/pydevd/_pydevd_bundle/_debug_adapter/__main__pydevd_gen_debug_adapter_protocol.py +604 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_bundle/_debug_adapter/debugProtocol.json +551 -445
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_bundle/_debug_adapter/pydevd_base_schema.py +25 -29
- debugpy-1.8.6/src/debugpy/_vendored/pydevd/_pydevd_bundle/_debug_adapter/pydevd_schema.py +17458 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_bundle/_debug_adapter/pydevd_schema_log.py +11 -12
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevconsole_code.py +18 -19
- debugpy-1.8.6/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_additional_thread_info.py +41 -0
- debugpy-1.8.6/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_additional_thread_info_regular.py +327 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_api.py +263 -214
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_breakpoints.py +7 -10
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_bytecode_utils.py +187 -92
- debugpy-1.8.6/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_bytecode_utils_py311.py +105 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_code_to_source.py +46 -51
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_collect_bytecode_info.py +239 -176
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_comm.py +370 -297
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_comm_constants.py +78 -86
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_command_line_handling.py +55 -59
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_concurrency_analyser/pydevd_concurrency_logger.py +194 -58
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_concurrency_analyser/pydevd_thread_wrappers.py +2 -3
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_console.py +18 -23
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_constants.py +157 -127
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_custom_frames.py +10 -12
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_cython.c +35217 -23106
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_cython.pxd +15 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_cython.pyx +802 -511
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_cython_wrapper.py +18 -7
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_daemon_thread.py +32 -24
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_defaults.py +11 -13
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_dont_trace.py +16 -16
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_dont_trace_files.py +27 -2
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_exec2.py +1 -1
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_extension_api.py +4 -5
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_extension_utils.py +8 -10
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_filtering.py +50 -45
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_frame.py +462 -407
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_frame_utils.py +63 -61
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_gevent_integration.py +14 -16
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_import_class.py +27 -25
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_io.py +40 -42
- debugpy-1.8.6/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_json_debug_options.py +200 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_net_command.py +20 -19
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_net_command_factory_json.py +199 -108
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_net_command_factory_xml.py +121 -73
- debugpy-1.8.6/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_plugin_utils.py +208 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_process_net_command.py +206 -159
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_process_net_command_json.py +346 -334
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_referrers.py +75 -80
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_reload.py +35 -35
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_resolver.py +116 -124
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_runpy.py +44 -58
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_safe_repr.py +51 -55
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_save_locals.py +4 -2
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_signature.py +24 -24
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_source_mapping.py +19 -20
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_stackless.py +45 -49
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_suspended_frames.py +61 -58
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_thread_lifecycle.py +23 -13
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_timeout.py +29 -31
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_trace_dispatch.py +41 -11
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_trace_dispatch_regular.py +117 -55
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_traceproperty.py +11 -14
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_utils.py +90 -89
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_vars.py +106 -97
- debugpy-1.8.6/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_vm_type.py +40 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_xml.py +56 -46
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_frame_eval/pydevd_frame_eval_cython_wrapper.py +5 -5
- debugpy-1.8.6/src/debugpy/_vendored/pydevd/_pydevd_frame_eval/pydevd_frame_eval_main.py +71 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_frame_eval/pydevd_frame_evaluator.c +11165 -5326
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_frame_eval/pydevd_frame_tracing.py +5 -6
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_frame_eval/pydevd_modify_bytecode.py +53 -56
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_frame_eval/vendored/bytecode/__init__.py +1 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_frame_eval/vendored/bytecode/bytecode.py +4 -6
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_frame_eval/vendored/bytecode/cfg.py +6 -26
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_frame_eval/vendored/bytecode/concrete.py +7 -21
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_frame_eval/vendored/bytecode/flags.py +5 -24
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_frame_eval/vendored/bytecode/instr.py +10 -34
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_frame_eval/vendored/bytecode/peephole_opt.py +1 -4
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_frame_eval/vendored/bytecode/tests/__init__.py +2 -6
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_frame_eval/vendored/bytecode/tests/test_bytecode.py +3 -5
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_frame_eval/vendored/bytecode/tests/test_cfg.py +11 -31
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_frame_eval/vendored/bytecode/tests/test_code.py +2 -2
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_frame_eval/vendored/bytecode/tests/test_concrete.py +14 -41
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_frame_eval/vendored/bytecode/tests/test_flags.py +2 -4
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_frame_eval/vendored/bytecode/tests/test_instr.py +7 -18
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_frame_eval/vendored/bytecode/tests/test_misc.py +6 -18
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_frame_eval/vendored/bytecode/tests/test_peephole_opt.py +7 -18
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_frame_eval/vendored/bytecode/tests/util_annotation.py +1 -3
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_frame_eval/vendored/pydevd_fix_code.py +14 -19
- debugpy-1.8.6/src/debugpy/_vendored/pydevd/_pydevd_sys_monitoring/_pydevd_sys_monitoring.py +1927 -0
- debugpy-1.8.6/src/debugpy/_vendored/pydevd/_pydevd_sys_monitoring/_pydevd_sys_monitoring_cython.c +43058 -0
- debugpy-1.8.6/src/debugpy/_vendored/pydevd/_pydevd_sys_monitoring/_pydevd_sys_monitoring_cython.pxd +46 -0
- debugpy-1.8.6/src/debugpy/_vendored/pydevd/_pydevd_sys_monitoring/_pydevd_sys_monitoring_cython.pyx +1934 -0
- debugpy-1.8.6/src/debugpy/_vendored/pydevd/_pydevd_sys_monitoring/pydevd_sys_monitoring.py +16 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydev_app_engine_debug_startup.py +12 -11
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydev_coverage.py +30 -32
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydev_ipython/inputhook.py +58 -54
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydev_ipython/inputhookglut.py +20 -24
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydev_ipython/inputhookgtk.py +8 -7
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydev_ipython/inputhookgtk3.py +8 -6
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydev_ipython/inputhookpyglet.py +11 -8
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydev_ipython/inputhookqt4.py +21 -18
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydev_ipython/inputhookqt5.py +17 -15
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydev_ipython/inputhookqt6.py +17 -15
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydev_ipython/inputhooktk.py +6 -4
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydev_ipython/inputhookwx.py +14 -10
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydev_ipython/matplotlibtools.py +30 -26
- debugpy-1.8.6/src/debugpy/_vendored/pydevd/pydev_ipython/qt.py +24 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydev_ipython/qt_for_kernel.py +37 -34
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydev_ipython/qt_loaders.py +86 -73
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydev_ipython/version.py +7 -7
- debugpy-1.8.6/src/debugpy/_vendored/pydevd/pydev_pysrc.py +1 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydev_run_in_console.py +23 -24
- debugpy-1.8.6/src/debugpy/_vendored/pydevd/pydev_sitecustomize/sitecustomize.py +267 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydevconsole.py +55 -47
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydevd.py +732 -508
- debugpy-1.8.6/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/_always_live_program.py +40 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/_check.py +1 -0
- debugpy-1.8.6/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/_test_attach_to_process.py +11 -0
- debugpy-1.8.6/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/_test_attach_to_process_linux.py +75 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/add_code_to_python_process.py +130 -125
- debugpy-1.8.6/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/attach_amd64.dll +0 -0
- debugpy-1.8.6/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/attach_amd64.pdb +0 -0
- debugpy-1.8.6/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/attach_pydevd.py +89 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/attach_script.py +41 -32
- debugpy-1.8.6/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/attach_x86.dll +0 -0
- debugpy-1.8.6/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/attach_x86.pdb +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/common/py_utils.hpp +1 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/common/py_version.hpp +9 -1
- debugpy-1.8.6/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/inject_dll_amd64.exe +0 -0
- debugpy-1.8.6/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/inject_dll_amd64.pdb +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/inject_dll_x86.exe +0 -0
- debugpy-1.8.6/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/inject_dll_x86.pdb +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/linux_and_mac/lldb_prepare.py +10 -9
- debugpy-1.8.6/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/run_code_on_dllmain_amd64.dll +0 -0
- debugpy-1.8.6/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/run_code_on_dllmain_amd64.pdb +0 -0
- debugpy-1.8.6/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/run_code_on_dllmain_x86.dll +0 -0
- debugpy-1.8.6/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/run_code_on_dllmain_x86.pdb +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/winappdbg/__init__.py +103 -119
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/winappdbg/breakpoint.py +457 -516
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/winappdbg/compat.py +33 -15
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/winappdbg/crash.py +336 -281
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/winappdbg/debug.py +101 -131
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/winappdbg/disasm.py +148 -153
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/winappdbg/event.py +310 -302
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/winappdbg/interactive.py +235 -208
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/winappdbg/module.py +185 -218
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/winappdbg/process.py +428 -564
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/winappdbg/registry.py +54 -53
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/winappdbg/search.py +69 -73
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/winappdbg/sql.py +158 -170
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/winappdbg/system.py +143 -213
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/winappdbg/textio.py +302 -333
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/winappdbg/thread.py +220 -239
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/winappdbg/util.py +198 -177
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/winappdbg/win32/__init__.py +11 -11
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/winappdbg/win32/advapi32.py +1191 -713
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/winappdbg/win32/context_amd64.py +248 -194
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/winappdbg/win32/context_i386.py +132 -120
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/winappdbg/win32/dbghelp.py +450 -346
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/winappdbg/win32/defines.py +305 -286
- debugpy-1.8.6/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/winappdbg/win32/gdi32.py +526 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/winappdbg/win32/kernel32.py +1479 -1097
- debugpy-1.8.6/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/winappdbg/win32/ntdll.py +579 -0
- debugpy-1.8.6/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/winappdbg/win32/peb_teb.py +3517 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/winappdbg/win32/psapi.py +54 -31
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/winappdbg/win32/shell32.py +170 -149
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/winappdbg/win32/shlwapi.py +190 -108
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/winappdbg/win32/user32.py +542 -437
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/winappdbg/win32/version.py +489 -442
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/winappdbg/win32/wtsapi32.py +83 -65
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/winappdbg/window.py +70 -76
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/windows/attach.cpp +17 -9
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/windows/compile_windows.bat +1 -1
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydevd_file_utils.py +141 -120
- {debugpy-1.8.3/src/debugpy/_vendored/pydevd/pydevd_plugins/extensions/types → debugpy-1.8.6/src/debugpy/_vendored/pydevd/pydevd_plugins}/__init__.py +1 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydevd_plugins/django_debug.py +175 -149
- {debugpy-1.8.3/src/debugpy/_vendored/pydevd/pydevd_plugins → debugpy-1.8.6/src/debugpy/_vendored/pydevd/pydevd_plugins/extensions}/__init__.py +1 -0
- {debugpy-1.8.3/src/debugpy/_vendored/pydevd/pydevd_plugins/extensions → debugpy-1.8.6/src/debugpy/_vendored/pydevd/pydevd_plugins/extensions/types}/__init__.py +1 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydevd_plugins/extensions/types/pydevd_helpers.py +5 -5
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydevd_plugins/extensions/types/pydevd_plugin_numpy_types.py +28 -28
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydevd_plugins/extensions/types/pydevd_plugin_pandas_types.py +22 -30
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydevd_plugins/extensions/types/pydevd_plugins_django_form_str.py +3 -2
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydevd_plugins/jinja2_debug.py +130 -108
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydevd_plugins/pydevd_line_validation.py +27 -14
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydevd_tracing.py +85 -66
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/setup_pydevd_cython.py +96 -59
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_version.py +3 -3
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/common/messaging.py +2 -1
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/server/cli.py +32 -17
- {debugpy-1.8.3 → debugpy-1.8.6/src/debugpy.egg-info}/PKG-INFO +1 -1
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy.egg-info/SOURCES.txt +6 -9
- debugpy-1.8.3/src/debugpy/_vendored/pydevd/_pydev_bundle/_pydev_filesystem_encoding.py +0 -41
- debugpy-1.8.3/src/debugpy/_vendored/pydevd/_pydev_runfiles/pydev_runfiles_coverage.py +0 -76
- debugpy-1.8.3/src/debugpy/_vendored/pydevd/_pydevd_bundle/_debug_adapter/__main__pydevd_gen_debug_adapter_protocol.py +0 -592
- debugpy-1.8.3/src/debugpy/_vendored/pydevd/_pydevd_bundle/_debug_adapter/pydevd_schema.py +0 -19514
- debugpy-1.8.3/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_additional_thread_info.py +0 -19
- debugpy-1.8.3/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_additional_thread_info_regular.py +0 -153
- debugpy-1.8.3/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_json_debug_options.py +0 -204
- debugpy-1.8.3/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_plugin_utils.py +0 -91
- debugpy-1.8.3/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_trace_api.py +0 -62
- debugpy-1.8.3/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_vm_type.py +0 -41
- debugpy-1.8.3/src/debugpy/_vendored/pydevd/_pydevd_frame_eval/pydevd_frame_eval_main.py +0 -48
- debugpy-1.8.3/src/debugpy/_vendored/pydevd/_pydevd_frame_eval/vendored/bytecode-0.13.0.dev0.dist-info/COPYING +0 -21
- debugpy-1.8.3/src/debugpy/_vendored/pydevd/_pydevd_frame_eval/vendored/bytecode-0.13.0.dev0.dist-info/INSTALLER +0 -1
- debugpy-1.8.3/src/debugpy/_vendored/pydevd/_pydevd_frame_eval/vendored/bytecode-0.13.0.dev0.dist-info/METADATA +0 -77
- debugpy-1.8.3/src/debugpy/_vendored/pydevd/_pydevd_frame_eval/vendored/bytecode-0.13.0.dev0.dist-info/RECORD +0 -42
- debugpy-1.8.3/src/debugpy/_vendored/pydevd/_pydevd_frame_eval/vendored/bytecode-0.13.0.dev0.dist-info/REQUESTED +0 -0
- debugpy-1.8.3/src/debugpy/_vendored/pydevd/_pydevd_frame_eval/vendored/bytecode-0.13.0.dev0.dist-info/WHEEL +0 -5
- debugpy-1.8.3/src/debugpy/_vendored/pydevd/_pydevd_frame_eval/vendored/bytecode-0.13.0.dev0.dist-info/direct_url.json +0 -1
- debugpy-1.8.3/src/debugpy/_vendored/pydevd/_pydevd_frame_eval/vendored/bytecode-0.13.0.dev0.dist-info/top_level.txt +0 -1
- debugpy-1.8.3/src/debugpy/_vendored/pydevd/pydev_ipython/qt.py +0 -23
- debugpy-1.8.3/src/debugpy/_vendored/pydevd/pydev_pysrc.py +0 -1
- debugpy-1.8.3/src/debugpy/_vendored/pydevd/pydev_sitecustomize/sitecustomize.py +0 -237
- debugpy-1.8.3/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/_always_live_program.py +0 -32
- debugpy-1.8.3/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/_test_attach_to_process.py +0 -9
- debugpy-1.8.3/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/_test_attach_to_process_linux.py +0 -74
- debugpy-1.8.3/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/attach_amd64.dll +0 -0
- debugpy-1.8.3/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/attach_amd64.pdb +0 -0
- debugpy-1.8.3/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/attach_pydevd.py +0 -79
- debugpy-1.8.3/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/attach_x86.dll +0 -0
- debugpy-1.8.3/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/attach_x86.pdb +0 -0
- debugpy-1.8.3/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/inject_dll_amd64.exe +0 -0
- debugpy-1.8.3/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/inject_dll_amd64.pdb +0 -0
- debugpy-1.8.3/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/inject_dll_x86.pdb +0 -0
- debugpy-1.8.3/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/run_code_on_dllmain_amd64.dll +0 -0
- debugpy-1.8.3/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/run_code_on_dllmain_amd64.pdb +0 -0
- debugpy-1.8.3/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/run_code_on_dllmain_x86.dll +0 -0
- debugpy-1.8.3/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/run_code_on_dllmain_x86.pdb +0 -0
- debugpy-1.8.3/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/winappdbg/win32/gdi32.py +0 -507
- debugpy-1.8.3/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/winappdbg/win32/ntdll.py +0 -539
- debugpy-1.8.3/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/winappdbg/win32/peb_teb.py +0 -3435
- {debugpy-1.8.3 → debugpy-1.8.6}/DESCRIPTION.md +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/LICENSE +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/MANIFEST.in +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/README.md +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/pyproject.toml +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/setup.cfg +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/setup.py +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/ThirdPartyNotices.txt +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/__init__.py +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/__main__.py +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/__init__.py +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/_pydevd_packaging.py +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/_util.py +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/force_pydevd.py +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydev_bundle/__init__.py +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydev_runfiles/__init__.py +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_bundle/__init__.py +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_bundle/_debug_adapter/__init__.py +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_bundle/_debug_adapter/debugProtocolCustom.json +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_bundle/pydevd_concurrency_analyser/__init__.py +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_frame_eval/.gitignore +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_frame_eval/__init__.py +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_frame_eval/pydevd_frame_evaluator.pxd +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_frame_eval/pydevd_frame_evaluator.pyx +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_frame_eval/pydevd_frame_evaluator.template.pyx +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_frame_eval/release_mem.h +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_frame_eval/vendored/README.txt +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/_pydevd_frame_eval/vendored/__init__.py +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydev_ipython/README +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydev_ipython/__init__.py +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydev_sitecustomize/__not_in_default_pythonpath.txt +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/README.txt +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/common/py_custom_pyeval_settrace.hpp +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/common/py_custom_pyeval_settrace_310.hpp +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/common/py_custom_pyeval_settrace_311.hpp +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/common/py_custom_pyeval_settrace_common.hpp +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/common/py_settrace.hpp +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/common/python.h +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/common/ref_utils.hpp +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/linux_and_mac/.gitignore +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/linux_and_mac/attach.cpp +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/linux_and_mac/compile_linux.sh +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/linux_and_mac/compile_mac.sh +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/linux_and_mac/compile_manylinux.cmd +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/windows/attach.h +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/windows/inject_dll.cpp +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/windows/py_win_helpers.hpp +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/windows/run_code_in_memory.hpp +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/windows/run_code_on_dllmain.cpp +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/windows/stdafx.cpp +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/windows/stdafx.h +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydevd_attach_to_process/windows/targetver.h +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/_vendored/pydevd/pydevd_plugins/extensions/README.md +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/adapter/__init__.py +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/adapter/__main__.py +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/adapter/clients.py +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/adapter/components.py +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/adapter/launchers.py +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/adapter/servers.py +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/adapter/sessions.py +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/common/__init__.py +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/common/json.py +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/common/log.py +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/common/singleton.py +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/common/sockets.py +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/common/stacks.py +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/common/timestamp.py +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/common/util.py +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/launcher/__init__.py +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/launcher/__main__.py +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/launcher/debuggee.py +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/launcher/handlers.py +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/launcher/output.py +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/launcher/winapi.py +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/public_api.py +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/server/__init__.py +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/server/api.py +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy/server/attach_pid_injected.py +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy.egg-info/dependency_links.txt +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy.egg-info/entry_points.txt +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/src/debugpy.egg-info/top_level.txt +0 -0
- {debugpy-1.8.3 → debugpy-1.8.6}/versioneer.py +0 -0
|
@@ -45,7 +45,7 @@ from __future__ import with_statement
|
|
|
45
45
|
|
|
46
46
|
__revision__ = "$Id$"
|
|
47
47
|
|
|
48
|
-
__all__ = [
|
|
48
|
+
__all__ = ["Process"]
|
|
49
49
|
|
|
50
50
|
import sys
|
|
51
51
|
from winappdbg import win32
|
|
@@ -55,8 +55,7 @@ from winappdbg.util import Regenerator, PathOperations, MemoryAddresses
|
|
|
55
55
|
from winappdbg.module import Module, _ModuleContainer
|
|
56
56
|
from winappdbg.thread import Thread, _ThreadContainer
|
|
57
57
|
from winappdbg.window import Window
|
|
58
|
-
from winappdbg.search import Search,
|
|
59
|
-
Pattern, BytePattern, TextPattern, RegExpPattern, HexPattern
|
|
58
|
+
from winappdbg.search import Search, Pattern, BytePattern, TextPattern, RegExpPattern, HexPattern
|
|
60
59
|
from winappdbg.disasm import Disassembler
|
|
61
60
|
|
|
62
61
|
import re
|
|
@@ -70,7 +69,7 @@ import traceback
|
|
|
70
69
|
# delayed import
|
|
71
70
|
System = None
|
|
72
71
|
|
|
73
|
-
|
|
72
|
+
# ==============================================================================
|
|
74
73
|
|
|
75
74
|
# TODO
|
|
76
75
|
# * Remote GetLastError()
|
|
@@ -79,7 +78,8 @@ System = None
|
|
|
79
78
|
# retrieve the original memory contents where code breakpoints are enabled.
|
|
80
79
|
# * A memory cache could be implemented here.
|
|
81
80
|
|
|
82
|
-
|
|
81
|
+
|
|
82
|
+
class Process(_ThreadContainer, _ModuleContainer):
|
|
83
83
|
"""
|
|
84
84
|
Interface to a process. Contains threads and modules snapshots.
|
|
85
85
|
|
|
@@ -150,7 +150,7 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
150
150
|
@ivar fileName: Filename of the main module. Use L{get_filename} instead.
|
|
151
151
|
"""
|
|
152
152
|
|
|
153
|
-
def __init__(self, dwProcessId, hProcess
|
|
153
|
+
def __init__(self, dwProcessId, hProcess=None, fileName=None):
|
|
154
154
|
"""
|
|
155
155
|
@type dwProcessId: int
|
|
156
156
|
@param dwProcessId: Global process ID.
|
|
@@ -165,8 +165,8 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
165
165
|
_ModuleContainer.__init__(self)
|
|
166
166
|
|
|
167
167
|
self.dwProcessId = dwProcessId
|
|
168
|
-
self.hProcess
|
|
169
|
-
self.fileName
|
|
168
|
+
self.hProcess = hProcess
|
|
169
|
+
self.fileName = fileName
|
|
170
170
|
|
|
171
171
|
def get_pid(self):
|
|
172
172
|
"""
|
|
@@ -184,7 +184,7 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
184
184
|
self.fileName = self.get_image_name()
|
|
185
185
|
return self.fileName
|
|
186
186
|
|
|
187
|
-
def open_handle(self, dwDesiredAccess
|
|
187
|
+
def open_handle(self, dwDesiredAccess=win32.PROCESS_ALL_ACCESS):
|
|
188
188
|
"""
|
|
189
189
|
Opens a new handle to the process.
|
|
190
190
|
|
|
@@ -208,8 +208,7 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
208
208
|
try:
|
|
209
209
|
self.close_handle()
|
|
210
210
|
except Exception:
|
|
211
|
-
warnings.warn(
|
|
212
|
-
"Failed to close process handle: %s" % traceback.format_exc())
|
|
211
|
+
warnings.warn("Failed to close process handle: %s" % traceback.format_exc())
|
|
213
212
|
|
|
214
213
|
self.hProcess = hProcess
|
|
215
214
|
|
|
@@ -223,14 +222,14 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
223
222
|
setting L{hProcess} to C{None} should be enough.
|
|
224
223
|
"""
|
|
225
224
|
try:
|
|
226
|
-
if hasattr(self.hProcess,
|
|
225
|
+
if hasattr(self.hProcess, "close"):
|
|
227
226
|
self.hProcess.close()
|
|
228
227
|
elif self.hProcess not in (None, win32.INVALID_HANDLE_VALUE):
|
|
229
228
|
win32.CloseHandle(self.hProcess)
|
|
230
229
|
finally:
|
|
231
230
|
self.hProcess = None
|
|
232
231
|
|
|
233
|
-
def get_handle(self, dwDesiredAccess
|
|
232
|
+
def get_handle(self, dwDesiredAccess=win32.PROCESS_ALL_ACCESS):
|
|
234
233
|
"""
|
|
235
234
|
Returns a handle to the process with I{at least} the access rights
|
|
236
235
|
requested.
|
|
@@ -261,26 +260,26 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
261
260
|
self.open_handle(dwAccess | dwDesiredAccess)
|
|
262
261
|
return self.hProcess
|
|
263
262
|
|
|
264
|
-
|
|
263
|
+
# ------------------------------------------------------------------------------
|
|
265
264
|
|
|
266
265
|
# Not really sure if it's a good idea...
|
|
267
|
-
## def __eq__(self, aProcess):
|
|
268
|
-
## """
|
|
269
|
-
## Compare two Process objects. The comparison is made using the IDs.
|
|
270
|
-
##
|
|
271
|
-
## @warning:
|
|
272
|
-
## If you have two Process instances with different handles the
|
|
273
|
-
## equality operator still returns C{True}, so be careful!
|
|
274
|
-
##
|
|
275
|
-
## @type aProcess: L{Process}
|
|
276
|
-
## @param aProcess: Another Process object.
|
|
277
|
-
##
|
|
278
|
-
## @rtype: bool
|
|
279
|
-
## @return: C{True} if the two process IDs are equal,
|
|
280
|
-
## C{False} otherwise.
|
|
281
|
-
## """
|
|
282
|
-
## return isinstance(aProcess, Process) and \
|
|
283
|
-
## self.get_pid() == aProcess.get_pid()
|
|
266
|
+
## def __eq__(self, aProcess):
|
|
267
|
+
## """
|
|
268
|
+
## Compare two Process objects. The comparison is made using the IDs.
|
|
269
|
+
##
|
|
270
|
+
## @warning:
|
|
271
|
+
## If you have two Process instances with different handles the
|
|
272
|
+
## equality operator still returns C{True}, so be careful!
|
|
273
|
+
##
|
|
274
|
+
## @type aProcess: L{Process}
|
|
275
|
+
## @param aProcess: Another Process object.
|
|
276
|
+
##
|
|
277
|
+
## @rtype: bool
|
|
278
|
+
## @return: C{True} if the two process IDs are equal,
|
|
279
|
+
## C{False} otherwise.
|
|
280
|
+
## """
|
|
281
|
+
## return isinstance(aProcess, Process) and \
|
|
282
|
+
## self.get_pid() == aProcess.get_pid()
|
|
284
283
|
|
|
285
284
|
def __contains__(self, anObject):
|
|
286
285
|
"""
|
|
@@ -293,8 +292,7 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
293
292
|
@rtype: bool
|
|
294
293
|
@return: C{True} if the requested object was found in the snapshot.
|
|
295
294
|
"""
|
|
296
|
-
return _ThreadContainer.__contains__(self, anObject) or
|
|
297
|
-
_ModuleContainer.__contains__(self, anObject)
|
|
295
|
+
return _ThreadContainer.__contains__(self, anObject) or _ModuleContainer.__contains__(self, anObject)
|
|
298
296
|
|
|
299
297
|
def __len__(self):
|
|
300
298
|
"""
|
|
@@ -302,10 +300,9 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
302
300
|
@rtype: int
|
|
303
301
|
@return: Count of L{Thread} and L{Module} objects in this snapshot.
|
|
304
302
|
"""
|
|
305
|
-
return _ThreadContainer.__len__(self) +
|
|
306
|
-
_ModuleContainer.__len__(self)
|
|
303
|
+
return _ThreadContainer.__len__(self) + _ModuleContainer.__len__(self)
|
|
307
304
|
|
|
308
|
-
class __ThreadsAndModulesIterator
|
|
305
|
+
class __ThreadsAndModulesIterator(object):
|
|
309
306
|
"""
|
|
310
307
|
Iterator object for L{Process} objects.
|
|
311
308
|
Iterates through L{Thread} objects first, L{Module} objects next.
|
|
@@ -317,30 +314,30 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
317
314
|
@param container: L{Thread} and L{Module} container.
|
|
318
315
|
"""
|
|
319
316
|
self.__container = container
|
|
320
|
-
self.__iterator
|
|
321
|
-
self.__state
|
|
317
|
+
self.__iterator = None
|
|
318
|
+
self.__state = 0
|
|
322
319
|
|
|
323
320
|
def __iter__(self):
|
|
324
|
-
|
|
321
|
+
"x.__iter__() <==> iter(x)"
|
|
325
322
|
return self
|
|
326
323
|
|
|
327
324
|
def next(self):
|
|
328
|
-
|
|
325
|
+
"x.next() -> the next value, or raise StopIteration"
|
|
329
326
|
if self.__state == 0:
|
|
330
327
|
self.__iterator = self.__container.iter_threads()
|
|
331
|
-
self.__state
|
|
328
|
+
self.__state = 1
|
|
332
329
|
if self.__state == 1:
|
|
333
330
|
try:
|
|
334
331
|
return self.__iterator.next()
|
|
335
332
|
except StopIteration:
|
|
336
333
|
self.__iterator = self.__container.iter_modules()
|
|
337
|
-
self.__state
|
|
334
|
+
self.__state = 2
|
|
338
335
|
if self.__state == 2:
|
|
339
336
|
try:
|
|
340
337
|
return self.__iterator.next()
|
|
341
338
|
except StopIteration:
|
|
342
339
|
self.__iterator = None
|
|
343
|
-
self.__state
|
|
340
|
+
self.__state = 3
|
|
344
341
|
raise StopIteration
|
|
345
342
|
|
|
346
343
|
def __iter__(self):
|
|
@@ -352,9 +349,9 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
352
349
|
"""
|
|
353
350
|
return self.__ThreadsAndModulesIterator(self)
|
|
354
351
|
|
|
355
|
-
|
|
352
|
+
# ------------------------------------------------------------------------------
|
|
356
353
|
|
|
357
|
-
def wait(self, dwTimeout
|
|
354
|
+
def wait(self, dwTimeout=None):
|
|
358
355
|
"""
|
|
359
356
|
Waits for the process to finish executing.
|
|
360
357
|
|
|
@@ -362,7 +359,7 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
362
359
|
"""
|
|
363
360
|
self.get_handle(win32.SYNCHRONIZE).wait(dwTimeout)
|
|
364
361
|
|
|
365
|
-
def kill(self, dwExitCode
|
|
362
|
+
def kill(self, dwExitCode=0):
|
|
366
363
|
"""
|
|
367
364
|
Terminates the execution of the process.
|
|
368
365
|
|
|
@@ -377,7 +374,7 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
377
374
|
|
|
378
375
|
@raise WindowsError: On error an exception is raised.
|
|
379
376
|
"""
|
|
380
|
-
self.scan_threads()
|
|
377
|
+
self.scan_threads() # force refresh the snapshot
|
|
381
378
|
suspended = list()
|
|
382
379
|
try:
|
|
383
380
|
for aThread in self.iter_threads():
|
|
@@ -398,7 +395,7 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
398
395
|
@raise WindowsError: On error an exception is raised.
|
|
399
396
|
"""
|
|
400
397
|
if self.get_thread_count() == 0:
|
|
401
|
-
self.scan_threads()
|
|
398
|
+
self.scan_threads() # only refresh the snapshot if empty
|
|
402
399
|
resumed = list()
|
|
403
400
|
try:
|
|
404
401
|
for aThread in self.iter_threads():
|
|
@@ -459,9 +456,9 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
459
456
|
dwAccess = win32.PROCESS_QUERY_LIMITED_INFORMATION
|
|
460
457
|
else:
|
|
461
458
|
dwAccess = win32.PROCESS_QUERY_INFORMATION
|
|
462
|
-
return win32.GetExitCodeProcess(
|
|
459
|
+
return win32.GetExitCodeProcess(self.get_handle(dwAccess))
|
|
463
460
|
|
|
464
|
-
|
|
461
|
+
# ------------------------------------------------------------------------------
|
|
465
462
|
|
|
466
463
|
def scan(self):
|
|
467
464
|
"""
|
|
@@ -482,10 +479,10 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
482
479
|
finally:
|
|
483
480
|
self.close_handle()
|
|
484
481
|
|
|
485
|
-
|
|
482
|
+
# ------------------------------------------------------------------------------
|
|
486
483
|
|
|
487
484
|
# Regular expression to find hexadecimal values of any size.
|
|
488
|
-
__hexa_parameter = re.compile(
|
|
485
|
+
__hexa_parameter = re.compile("0x[0-9A-Fa-f]+")
|
|
489
486
|
|
|
490
487
|
def __fixup_labels(self, disasm):
|
|
491
488
|
"""
|
|
@@ -504,7 +501,7 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
504
501
|
s, e = m.span()
|
|
505
502
|
value = text[s:e]
|
|
506
503
|
try:
|
|
507
|
-
label = self.get_label_at_address(
|
|
504
|
+
label = self.get_label_at_address(int(value, 0x10))
|
|
508
505
|
except Exception:
|
|
509
506
|
label = None
|
|
510
507
|
if label:
|
|
@@ -537,7 +534,7 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
537
534
|
try:
|
|
538
535
|
disasm = self.__disasm
|
|
539
536
|
except AttributeError:
|
|
540
|
-
disasm = self.__disasm = Disassembler(
|
|
537
|
+
disasm = self.__disasm = Disassembler(self.get_arch())
|
|
541
538
|
return disasm.decode(lpAddress, code)
|
|
542
539
|
|
|
543
540
|
def disassemble(self, lpAddress, dwSize):
|
|
@@ -558,14 +555,14 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
558
555
|
- Disassembly line of instruction.
|
|
559
556
|
- Hexadecimal dump of instruction.
|
|
560
557
|
"""
|
|
561
|
-
data
|
|
558
|
+
data = self.read(lpAddress, dwSize)
|
|
562
559
|
disasm = self.disassemble_string(lpAddress, data)
|
|
563
560
|
self.__fixup_labels(disasm)
|
|
564
561
|
return disasm
|
|
565
562
|
|
|
566
563
|
# FIXME
|
|
567
564
|
# This algorithm really bad, I've got to write a better one :P
|
|
568
|
-
def disassemble_around(self, lpAddress, dwSize
|
|
565
|
+
def disassemble_around(self, lpAddress, dwSize=64):
|
|
569
566
|
"""
|
|
570
567
|
Disassemble around the given address.
|
|
571
568
|
|
|
@@ -584,21 +581,21 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
584
581
|
- Disassembly line of instruction.
|
|
585
582
|
- Hexadecimal dump of instruction.
|
|
586
583
|
"""
|
|
587
|
-
dwDelta
|
|
588
|
-
addr_1
|
|
589
|
-
addr_2
|
|
590
|
-
size_1
|
|
591
|
-
size_2
|
|
592
|
-
data
|
|
593
|
-
data_1
|
|
594
|
-
data_2
|
|
584
|
+
dwDelta = int(float(dwSize) / 2.0)
|
|
585
|
+
addr_1 = lpAddress - dwDelta
|
|
586
|
+
addr_2 = lpAddress
|
|
587
|
+
size_1 = dwDelta
|
|
588
|
+
size_2 = dwSize - dwDelta
|
|
589
|
+
data = self.read(addr_1, dwSize)
|
|
590
|
+
data_1 = data[:size_1]
|
|
591
|
+
data_2 = data[size_1:]
|
|
595
592
|
disasm_1 = self.disassemble_string(addr_1, data_1)
|
|
596
593
|
disasm_2 = self.disassemble_string(addr_2, data_2)
|
|
597
|
-
disasm
|
|
594
|
+
disasm = disasm_1 + disasm_2
|
|
598
595
|
self.__fixup_labels(disasm)
|
|
599
596
|
return disasm
|
|
600
597
|
|
|
601
|
-
def disassemble_around_pc(self, dwThreadId, dwSize
|
|
598
|
+
def disassemble_around_pc(self, dwThreadId, dwSize=64):
|
|
602
599
|
"""
|
|
603
600
|
Disassemble around the program counter of the given thread.
|
|
604
601
|
|
|
@@ -659,7 +656,7 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
659
656
|
aThread = self.get_thread(dwThreadId)
|
|
660
657
|
return self.disassemble_instruction(aThread.get_pc())
|
|
661
658
|
|
|
662
|
-
|
|
659
|
+
# ------------------------------------------------------------------------------
|
|
663
660
|
|
|
664
661
|
def flush_instruction_cache(self):
|
|
665
662
|
"""
|
|
@@ -676,7 +673,7 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
676
673
|
# Maybe PROCESS_VM_OPERATION ???
|
|
677
674
|
# In any case we're only calling this from the debugger,
|
|
678
675
|
# so it should be fine (we already have PROCESS_ALL_ACCESS).
|
|
679
|
-
win32.FlushInstructionCache(
|
|
676
|
+
win32.FlushInstructionCache(self.get_handle())
|
|
680
677
|
|
|
681
678
|
def debug_break(self):
|
|
682
679
|
"""
|
|
@@ -687,7 +684,7 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
687
684
|
# The exception is raised by a new thread.
|
|
688
685
|
# When continuing the exception, the thread dies by itself.
|
|
689
686
|
# This thread is hidden from the debugger.
|
|
690
|
-
win32.DebugBreakProcess(
|
|
687
|
+
win32.DebugBreakProcess(self.get_handle())
|
|
691
688
|
|
|
692
689
|
def is_wow64(self):
|
|
693
690
|
"""
|
|
@@ -709,7 +706,7 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
709
706
|
try:
|
|
710
707
|
wow64 = self.__wow64
|
|
711
708
|
except AttributeError:
|
|
712
|
-
if
|
|
709
|
+
if win32.bits == 32 and not win32.wow64:
|
|
713
710
|
wow64 = False
|
|
714
711
|
else:
|
|
715
712
|
if win32.PROCESS_ALL_ACCESS == win32.PROCESS_ALL_ACCESS_VISTA:
|
|
@@ -759,13 +756,11 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
759
756
|
|
|
760
757
|
# Are we in a 32 bit machine?
|
|
761
758
|
if win32.bits == 32 and not win32.wow64:
|
|
762
|
-
|
|
763
759
|
# All processes are 32 bits.
|
|
764
760
|
return 32
|
|
765
761
|
|
|
766
762
|
# Is the process inside WOW64?
|
|
767
763
|
if self.is_wow64():
|
|
768
|
-
|
|
769
764
|
# The process is 32 bits.
|
|
770
765
|
return 32
|
|
771
766
|
|
|
@@ -775,7 +770,7 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
775
770
|
# TODO: get_os, to test compatibility run
|
|
776
771
|
# See: http://msdn.microsoft.com/en-us/library/windows/desktop/ms683224(v=vs.85).aspx
|
|
777
772
|
|
|
778
|
-
|
|
773
|
+
# ------------------------------------------------------------------------------
|
|
779
774
|
|
|
780
775
|
def get_start_time(self):
|
|
781
776
|
"""
|
|
@@ -827,14 +822,14 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
827
822
|
if self.is_alive():
|
|
828
823
|
ExitTime = win32.GetSystemTimeAsFileTime()
|
|
829
824
|
CreationTime = CreationTime.dwLowDateTime + (CreationTime.dwHighDateTime << 32)
|
|
830
|
-
ExitTime
|
|
831
|
-
RunningTime
|
|
832
|
-
return RunningTime / 10000
|
|
825
|
+
ExitTime = ExitTime.dwLowDateTime + (ExitTime.dwHighDateTime << 32)
|
|
826
|
+
RunningTime = ExitTime - CreationTime
|
|
827
|
+
return RunningTime / 10000 # 100 nanoseconds steps => milliseconds
|
|
833
828
|
|
|
834
|
-
|
|
829
|
+
# ------------------------------------------------------------------------------
|
|
835
830
|
|
|
836
831
|
def __load_System_class(self):
|
|
837
|
-
global System
|
|
832
|
+
global System # delayed import
|
|
838
833
|
if System is None:
|
|
839
834
|
from system import System
|
|
840
835
|
|
|
@@ -852,7 +847,7 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
852
847
|
pid = self.get_pid()
|
|
853
848
|
return [d for d in System.get_active_services() if d.ProcessId == pid]
|
|
854
849
|
|
|
855
|
-
|
|
850
|
+
# ------------------------------------------------------------------------------
|
|
856
851
|
|
|
857
852
|
def get_dep_policy(self):
|
|
858
853
|
"""
|
|
@@ -884,7 +879,7 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
884
879
|
msg = "This method is only available in Windows XP SP3 and above."
|
|
885
880
|
raise NotImplementedError(msg)
|
|
886
881
|
|
|
887
|
-
|
|
882
|
+
# ------------------------------------------------------------------------------
|
|
888
883
|
|
|
889
884
|
def get_peb(self):
|
|
890
885
|
"""
|
|
@@ -895,8 +890,7 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
895
890
|
@return: PEB structure.
|
|
896
891
|
@raise WindowsError: An exception is raised on error.
|
|
897
892
|
"""
|
|
898
|
-
self.get_handle(
|
|
899
|
-
win32.PROCESS_QUERY_INFORMATION )
|
|
893
|
+
self.get_handle(win32.PROCESS_VM_READ | win32.PROCESS_QUERY_INFORMATION)
|
|
900
894
|
return self.read_structure(self.get_peb_address(), win32.PEB)
|
|
901
895
|
|
|
902
896
|
def get_peb_address(self):
|
|
@@ -911,8 +905,7 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
911
905
|
return self._peb_ptr
|
|
912
906
|
except AttributeError:
|
|
913
907
|
hProcess = self.get_handle(win32.PROCESS_QUERY_INFORMATION)
|
|
914
|
-
pbi = win32.NtQueryInformationProcess(hProcess,
|
|
915
|
-
win32.ProcessBasicInformation)
|
|
908
|
+
pbi = win32.NtQueryInformationProcess(hProcess, win32.ProcessBasicInformation)
|
|
916
909
|
address = pbi.PebBaseAddress
|
|
917
910
|
self._peb_ptr = address
|
|
918
911
|
return address
|
|
@@ -961,18 +954,17 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
961
954
|
if not name:
|
|
962
955
|
name = None
|
|
963
956
|
except (KeyError, AttributeError, WindowsError):
|
|
964
|
-
## traceback.print_exc() # XXX DEBUG
|
|
957
|
+
## traceback.print_exc() # XXX DEBUG
|
|
965
958
|
name = None
|
|
966
959
|
|
|
967
960
|
# Method 2: QueryFullProcessImageName()
|
|
968
961
|
# Not implemented until Windows Vista.
|
|
969
962
|
if not name:
|
|
970
963
|
try:
|
|
971
|
-
hProcess = self.get_handle(
|
|
972
|
-
win32.PROCESS_QUERY_LIMITED_INFORMATION)
|
|
964
|
+
hProcess = self.get_handle(win32.PROCESS_QUERY_LIMITED_INFORMATION)
|
|
973
965
|
name = win32.QueryFullProcessImageName(hProcess)
|
|
974
966
|
except (AttributeError, WindowsError):
|
|
975
|
-
## traceback.print_exc() # XXX DEBUG
|
|
967
|
+
## traceback.print_exc() # XXX DEBUG
|
|
976
968
|
name = None
|
|
977
969
|
|
|
978
970
|
# Method 3: GetProcessImageFileName()
|
|
@@ -989,7 +981,7 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
989
981
|
else:
|
|
990
982
|
name = None
|
|
991
983
|
except (AttributeError, WindowsError):
|
|
992
|
-
## traceback.print_exc() # XXX DEBUG
|
|
984
|
+
## traceback.print_exc() # XXX DEBUG
|
|
993
985
|
if not name:
|
|
994
986
|
name = None
|
|
995
987
|
|
|
@@ -1000,20 +992,18 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
1000
992
|
# in usermode space (see http://www.ragestorm.net/blogs/?p=163).
|
|
1001
993
|
if not name:
|
|
1002
994
|
try:
|
|
1003
|
-
hProcess = self.get_handle(
|
|
1004
|
-
win32.PROCESS_QUERY_INFORMATION )
|
|
995
|
+
hProcess = self.get_handle(win32.PROCESS_VM_READ | win32.PROCESS_QUERY_INFORMATION)
|
|
1005
996
|
try:
|
|
1006
997
|
name = win32.GetModuleFileNameEx(hProcess)
|
|
1007
998
|
except WindowsError:
|
|
1008
|
-
## traceback.print_exc() # XXX DEBUG
|
|
1009
|
-
name = win32.GetModuleFileNameEx(
|
|
1010
|
-
hProcess, self.get_image_base())
|
|
999
|
+
## traceback.print_exc() # XXX DEBUG
|
|
1000
|
+
name = win32.GetModuleFileNameEx(hProcess, self.get_image_base())
|
|
1011
1001
|
if name:
|
|
1012
1002
|
name = PathOperations.native_to_win32_pathname(name)
|
|
1013
1003
|
else:
|
|
1014
1004
|
name = None
|
|
1015
1005
|
except (AttributeError, WindowsError):
|
|
1016
|
-
## traceback.print_exc() # XXX DEBUG
|
|
1006
|
+
## traceback.print_exc() # XXX DEBUG
|
|
1017
1007
|
if not name:
|
|
1018
1008
|
name = None
|
|
1019
1009
|
|
|
@@ -1026,17 +1016,15 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
1026
1016
|
if not name:
|
|
1027
1017
|
try:
|
|
1028
1018
|
peb = self.get_peb()
|
|
1029
|
-
pp = self.read_structure(peb.ProcessParameters,
|
|
1030
|
-
win32.RTL_USER_PROCESS_PARAMETERS)
|
|
1019
|
+
pp = self.read_structure(peb.ProcessParameters, win32.RTL_USER_PROCESS_PARAMETERS)
|
|
1031
1020
|
s = pp.ImagePathName
|
|
1032
|
-
name = self.peek_string(s.Buffer,
|
|
1033
|
-
dwMaxSize=s.MaximumLength, fUnicode=True)
|
|
1021
|
+
name = self.peek_string(s.Buffer, dwMaxSize=s.MaximumLength, fUnicode=True)
|
|
1034
1022
|
if name:
|
|
1035
1023
|
name = PathOperations.native_to_win32_pathname(name)
|
|
1036
1024
|
else:
|
|
1037
1025
|
name = None
|
|
1038
1026
|
except (AttributeError, WindowsError):
|
|
1039
|
-
## traceback.print_exc() # XXX DEBUG
|
|
1027
|
+
## traceback.print_exc() # XXX DEBUG
|
|
1040
1028
|
name = None
|
|
1041
1029
|
|
|
1042
1030
|
# Method 6: Module.get_filename()
|
|
@@ -1051,7 +1039,7 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
1051
1039
|
if not name:
|
|
1052
1040
|
name = None
|
|
1053
1041
|
except (AttributeError, WindowsError):
|
|
1054
|
-
## traceback.print_exc() # XXX DEBUG
|
|
1042
|
+
## traceback.print_exc() # XXX DEBUG
|
|
1055
1043
|
name = None
|
|
1056
1044
|
|
|
1057
1045
|
# Remember the filename.
|
|
@@ -1072,8 +1060,7 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
1072
1060
|
@raise WindowsError: On error an exception is raised.
|
|
1073
1061
|
"""
|
|
1074
1062
|
peb = self.get_peb()
|
|
1075
|
-
pp = self.read_structure(peb.ProcessParameters,
|
|
1076
|
-
win32.RTL_USER_PROCESS_PARAMETERS)
|
|
1063
|
+
pp = self.read_structure(peb.ProcessParameters, win32.RTL_USER_PROCESS_PARAMETERS)
|
|
1077
1064
|
s = pp.CommandLine
|
|
1078
1065
|
return (s.Buffer, s.MaximumLength)
|
|
1079
1066
|
|
|
@@ -1092,8 +1079,7 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
1092
1079
|
@raise WindowsError: On error an exception is raised.
|
|
1093
1080
|
"""
|
|
1094
1081
|
peb = self.get_peb()
|
|
1095
|
-
pp = self.read_structure(peb.ProcessParameters,
|
|
1096
|
-
win32.RTL_USER_PROCESS_PARAMETERS)
|
|
1082
|
+
pp = self.read_structure(peb.ProcessParameters, win32.RTL_USER_PROCESS_PARAMETERS)
|
|
1097
1083
|
Environment = pp.Environment
|
|
1098
1084
|
try:
|
|
1099
1085
|
EnvironmentSize = pp.EnvironmentSize
|
|
@@ -1112,11 +1098,10 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
1112
1098
|
@raise WindowsError: On error an exception is raised.
|
|
1113
1099
|
"""
|
|
1114
1100
|
(Buffer, MaximumLength) = self.get_command_line_block()
|
|
1115
|
-
CommandLine = self.peek_string(Buffer, dwMaxSize=MaximumLength,
|
|
1116
|
-
fUnicode=True)
|
|
1101
|
+
CommandLine = self.peek_string(Buffer, dwMaxSize=MaximumLength, fUnicode=True)
|
|
1117
1102
|
gst = win32.GuessStringType
|
|
1118
1103
|
if gst.t_default == gst.t_ansi:
|
|
1119
|
-
CommandLine = CommandLine.encode(
|
|
1104
|
+
CommandLine = CommandLine.encode("cp1252")
|
|
1120
1105
|
return CommandLine
|
|
1121
1106
|
|
|
1122
1107
|
def get_environment_variables(self):
|
|
@@ -1140,7 +1125,7 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
1140
1125
|
# renders garbage.
|
|
1141
1126
|
|
|
1142
1127
|
# Read the environment block contents.
|
|
1143
|
-
data = self.peek(
|
|
1128
|
+
data = self.peek(*self.get_environment_block())
|
|
1144
1129
|
|
|
1145
1130
|
# Put them into a Unicode buffer.
|
|
1146
1131
|
tmp = ctypes.create_string_buffer(data)
|
|
@@ -1150,26 +1135,23 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
1150
1135
|
|
|
1151
1136
|
# Skip until the first Unicode null char is found.
|
|
1152
1137
|
pos = 0
|
|
1153
|
-
while buffer[pos] !=
|
|
1138
|
+
while buffer[pos] != "\0":
|
|
1154
1139
|
pos += 1
|
|
1155
1140
|
pos += 1
|
|
1156
1141
|
|
|
1157
1142
|
# Loop for each environment variable...
|
|
1158
1143
|
environment = []
|
|
1159
|
-
while buffer[pos] !=
|
|
1160
|
-
|
|
1144
|
+
while buffer[pos] != "\0":
|
|
1161
1145
|
# Until we find a null char...
|
|
1162
1146
|
env_name_pos = pos
|
|
1163
|
-
env_name =
|
|
1147
|
+
env_name = ""
|
|
1164
1148
|
found_name = False
|
|
1165
|
-
while buffer[pos] !=
|
|
1166
|
-
|
|
1149
|
+
while buffer[pos] != "\0":
|
|
1167
1150
|
# Get the current char.
|
|
1168
1151
|
char = buffer[pos]
|
|
1169
1152
|
|
|
1170
1153
|
# Is it an equal sign?
|
|
1171
|
-
if char ==
|
|
1172
|
-
|
|
1154
|
+
if char == "=":
|
|
1173
1155
|
# Skip leading equal signs.
|
|
1174
1156
|
if env_name_pos == pos:
|
|
1175
1157
|
env_name_pos += 1
|
|
@@ -1192,8 +1174,8 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
1192
1174
|
break
|
|
1193
1175
|
|
|
1194
1176
|
# Read the variable value until we find a null char.
|
|
1195
|
-
env_value =
|
|
1196
|
-
while buffer[pos] !=
|
|
1177
|
+
env_value = ""
|
|
1178
|
+
while buffer[pos] != "\0":
|
|
1197
1179
|
env_value += buffer[pos]
|
|
1198
1180
|
pos += 1
|
|
1199
1181
|
|
|
@@ -1201,7 +1183,7 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
1201
1183
|
pos += 1
|
|
1202
1184
|
|
|
1203
1185
|
# Add to the list of environment variables found.
|
|
1204
|
-
environment.append(
|
|
1186
|
+
environment.append((env_name, env_value))
|
|
1205
1187
|
|
|
1206
1188
|
# Remove the last entry, it's garbage.
|
|
1207
1189
|
if environment:
|
|
@@ -1210,7 +1192,7 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
1210
1192
|
# Return the environment variables.
|
|
1211
1193
|
return environment
|
|
1212
1194
|
|
|
1213
|
-
def get_environment_data(self, fUnicode
|
|
1195
|
+
def get_environment_data(self, fUnicode=None):
|
|
1214
1196
|
"""
|
|
1215
1197
|
Retrieves the environment block data with wich the program is running.
|
|
1216
1198
|
|
|
@@ -1231,21 +1213,17 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
1231
1213
|
"""
|
|
1232
1214
|
|
|
1233
1215
|
# Issue a deprecation warning.
|
|
1234
|
-
warnings.warn(
|
|
1235
|
-
"Process.get_environment_data() is deprecated" \
|
|
1236
|
-
" since WinAppDbg 1.5.",
|
|
1237
|
-
DeprecationWarning)
|
|
1216
|
+
warnings.warn("Process.get_environment_data() is deprecated" " since WinAppDbg 1.5.", DeprecationWarning)
|
|
1238
1217
|
|
|
1239
1218
|
# Get the environment variables.
|
|
1240
|
-
block = [
|
|
1241
|
-
in self.get_environment_variables() ]
|
|
1219
|
+
block = [key + "=" + value for (key, value) in self.get_environment_variables()]
|
|
1242
1220
|
|
|
1243
1221
|
# Convert the data to ANSI if requested.
|
|
1244
1222
|
if fUnicode is None:
|
|
1245
1223
|
gst = win32.GuessStringType
|
|
1246
1224
|
fUnicode = gst.t_default == gst.t_unicode
|
|
1247
1225
|
if not fUnicode:
|
|
1248
|
-
block = [x.encode(
|
|
1226
|
+
block = [x.encode("cp1252") for x in block]
|
|
1249
1227
|
|
|
1250
1228
|
# Return the environment data.
|
|
1251
1229
|
return block
|
|
@@ -1267,10 +1245,7 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
1267
1245
|
"""
|
|
1268
1246
|
|
|
1269
1247
|
# Issue a deprecation warning.
|
|
1270
|
-
warnings.warn(
|
|
1271
|
-
"Process.parse_environment_data() is deprecated" \
|
|
1272
|
-
" since WinAppDbg 1.5.",
|
|
1273
|
-
DeprecationWarning)
|
|
1248
|
+
warnings.warn("Process.parse_environment_data() is deprecated" " since WinAppDbg 1.5.", DeprecationWarning)
|
|
1274
1249
|
|
|
1275
1250
|
# Create an empty environment dictionary.
|
|
1276
1251
|
environment = dict()
|
|
@@ -1282,19 +1257,19 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
1282
1257
|
# Prepare the tokens (ANSI or Unicode).
|
|
1283
1258
|
gst = win32.GuessStringType
|
|
1284
1259
|
if type(block[0]) == gst.t_ansi:
|
|
1285
|
-
equals =
|
|
1286
|
-
terminator =
|
|
1260
|
+
equals = "="
|
|
1261
|
+
terminator = "\0"
|
|
1287
1262
|
else:
|
|
1288
|
-
equals =
|
|
1289
|
-
terminator =
|
|
1263
|
+
equals = "="
|
|
1264
|
+
terminator = "\0"
|
|
1290
1265
|
|
|
1291
1266
|
# Split the blocks into key/value pairs.
|
|
1292
1267
|
for chunk in block:
|
|
1293
1268
|
sep = chunk.find(equals, 1)
|
|
1294
1269
|
if sep < 0:
|
|
1295
|
-
## raise Exception()
|
|
1296
|
-
continue
|
|
1297
|
-
key, value = chunk[:sep], chunk[sep+1:]
|
|
1270
|
+
## raise Exception()
|
|
1271
|
+
continue # corrupted environment block?
|
|
1272
|
+
key, value = chunk[:sep], chunk[sep + 1 :]
|
|
1298
1273
|
|
|
1299
1274
|
# For duplicated keys, append the value.
|
|
1300
1275
|
# Values are separated using null terminators.
|
|
@@ -1306,7 +1281,7 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
1306
1281
|
# Return the environment dictionary.
|
|
1307
1282
|
return environment
|
|
1308
1283
|
|
|
1309
|
-
def get_environment(self, fUnicode
|
|
1284
|
+
def get_environment(self, fUnicode=None):
|
|
1310
1285
|
"""
|
|
1311
1286
|
Retrieves the environment with wich the program is running.
|
|
1312
1287
|
|
|
@@ -1336,23 +1311,22 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
1336
1311
|
gst = win32.GuessStringType
|
|
1337
1312
|
fUnicode = gst.t_default == gst.t_unicode
|
|
1338
1313
|
if not fUnicode:
|
|
1339
|
-
variables = [
|
|
1340
|
-
for (key, value) in variables ]
|
|
1314
|
+
variables = [(key.encode("cp1252"), value.encode("cp1252")) for (key, value) in variables]
|
|
1341
1315
|
|
|
1342
1316
|
# Add the variables to a dictionary, concatenating duplicates.
|
|
1343
1317
|
environment = dict()
|
|
1344
1318
|
for key, value in variables:
|
|
1345
1319
|
if key in environment:
|
|
1346
|
-
environment[key] = environment[key] +
|
|
1320
|
+
environment[key] = environment[key] + "\0" + value
|
|
1347
1321
|
else:
|
|
1348
1322
|
environment[key] = value
|
|
1349
1323
|
|
|
1350
1324
|
# Return the dictionary.
|
|
1351
1325
|
return environment
|
|
1352
1326
|
|
|
1353
|
-
|
|
1327
|
+
# ------------------------------------------------------------------------------
|
|
1354
1328
|
|
|
1355
|
-
def search(self, pattern, minAddr
|
|
1329
|
+
def search(self, pattern, minAddr=None, maxAddr=None):
|
|
1356
1330
|
"""
|
|
1357
1331
|
Search for the given pattern within the process memory.
|
|
1358
1332
|
|
|
@@ -1388,13 +1362,12 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
1388
1362
|
if isinstance(pattern, str):
|
|
1389
1363
|
return self.search_bytes(pattern, minAddr, maxAddr)
|
|
1390
1364
|
if isinstance(pattern, compat.unicode):
|
|
1391
|
-
return self.search_bytes(pattern.encode("utf-16le"),
|
|
1392
|
-
minAddr, maxAddr)
|
|
1365
|
+
return self.search_bytes(pattern.encode("utf-16le"), minAddr, maxAddr)
|
|
1393
1366
|
if isinstance(pattern, Pattern):
|
|
1394
1367
|
return Search.search_process(self, pattern, minAddr, maxAddr)
|
|
1395
1368
|
raise TypeError("Unknown pattern type: %r" % type(pattern))
|
|
1396
1369
|
|
|
1397
|
-
def search_bytes(self, bytes, minAddr
|
|
1370
|
+
def search_bytes(self, bytes, minAddr=None, maxAddr=None):
|
|
1398
1371
|
"""
|
|
1399
1372
|
Search for the given byte pattern within the process memory.
|
|
1400
1373
|
|
|
@@ -1418,10 +1391,7 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
1418
1391
|
for addr, size, data in matches:
|
|
1419
1392
|
yield addr
|
|
1420
1393
|
|
|
1421
|
-
def search_text(self, text, encoding
|
|
1422
|
-
caseSensitive = False,
|
|
1423
|
-
minAddr = None,
|
|
1424
|
-
maxAddr = None):
|
|
1394
|
+
def search_text(self, text, encoding="utf-16le", caseSensitive=False, minAddr=None, maxAddr=None):
|
|
1425
1395
|
"""
|
|
1426
1396
|
Search for the given text within the process memory.
|
|
1427
1397
|
|
|
@@ -1456,10 +1426,7 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
1456
1426
|
for addr, size, data in matches:
|
|
1457
1427
|
yield addr, data
|
|
1458
1428
|
|
|
1459
|
-
def search_regexp(self, regexp, flags =
|
|
1460
|
-
minAddr = None,
|
|
1461
|
-
maxAddr = None,
|
|
1462
|
-
bufferPages = -1):
|
|
1429
|
+
def search_regexp(self, regexp, flags=0, minAddr=None, maxAddr=None, bufferPages=-1):
|
|
1463
1430
|
"""
|
|
1464
1431
|
Search for the given regular expression within the process memory.
|
|
1465
1432
|
|
|
@@ -1500,11 +1467,9 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
1500
1467
|
process memory.
|
|
1501
1468
|
"""
|
|
1502
1469
|
pattern = RegExpPattern(regexp, flags)
|
|
1503
|
-
return Search.search_process(self, pattern,
|
|
1504
|
-
minAddr, maxAddr,
|
|
1505
|
-
bufferPages)
|
|
1470
|
+
return Search.search_process(self, pattern, minAddr, maxAddr, bufferPages)
|
|
1506
1471
|
|
|
1507
|
-
def search_hexa(self, hexa, minAddr
|
|
1472
|
+
def search_hexa(self, hexa, minAddr=None, maxAddr=None):
|
|
1508
1473
|
"""
|
|
1509
1474
|
Search for the given hexadecimal pattern within the process memory.
|
|
1510
1475
|
|
|
@@ -1541,7 +1506,7 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
1541
1506
|
for addr, size, data in matches:
|
|
1542
1507
|
yield addr, data
|
|
1543
1508
|
|
|
1544
|
-
def strings(self, minSize
|
|
1509
|
+
def strings(self, minSize=4, maxSize=1024):
|
|
1545
1510
|
"""
|
|
1546
1511
|
Extract ASCII strings from the process memory.
|
|
1547
1512
|
|
|
@@ -1558,10 +1523,9 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
1558
1523
|
- The size of the string.
|
|
1559
1524
|
- The string.
|
|
1560
1525
|
"""
|
|
1561
|
-
return Search.extract_ascii_strings(self, minSize
|
|
1562
|
-
maxSize = maxSize)
|
|
1526
|
+
return Search.extract_ascii_strings(self, minSize=minSize, maxSize=maxSize)
|
|
1563
1527
|
|
|
1564
|
-
|
|
1528
|
+
# ------------------------------------------------------------------------------
|
|
1565
1529
|
|
|
1566
1530
|
def __read_c_type(self, address, format, c_type):
|
|
1567
1531
|
size = ctypes.sizeof(c_type)
|
|
@@ -1571,7 +1535,7 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
1571
1535
|
return struct.unpack(format, packed)[0]
|
|
1572
1536
|
|
|
1573
1537
|
def __write_c_type(self, address, format, unpacked):
|
|
1574
|
-
packed = struct.pack(
|
|
1538
|
+
packed = struct.pack("@L", unpacked)
|
|
1575
1539
|
self.write(address, packed)
|
|
1576
1540
|
|
|
1577
1541
|
# XXX TODO
|
|
@@ -1593,8 +1557,7 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
1593
1557
|
|
|
1594
1558
|
@raise WindowsError: On error an exception is raised.
|
|
1595
1559
|
"""
|
|
1596
|
-
hProcess = self.get_handle(
|
|
1597
|
-
win32.PROCESS_QUERY_INFORMATION )
|
|
1560
|
+
hProcess = self.get_handle(win32.PROCESS_VM_READ | win32.PROCESS_QUERY_INFORMATION)
|
|
1598
1561
|
if not self.is_buffer(lpBaseAddress, nSize):
|
|
1599
1562
|
raise ctypes.WinError(win32.ERROR_INVALID_ADDRESS)
|
|
1600
1563
|
data = win32.ReadProcessMemory(hProcess, lpBaseAddress, nSize)
|
|
@@ -1636,7 +1599,7 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
1636
1599
|
|
|
1637
1600
|
@raise WindowsError: On error an exception is raised.
|
|
1638
1601
|
"""
|
|
1639
|
-
return ord(
|
|
1602
|
+
return ord(self.read(lpBaseAddress, 1))
|
|
1640
1603
|
|
|
1641
1604
|
def write_char(self, lpBaseAddress, char):
|
|
1642
1605
|
"""
|
|
@@ -1670,7 +1633,7 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
1670
1633
|
|
|
1671
1634
|
@raise WindowsError: On error an exception is raised.
|
|
1672
1635
|
"""
|
|
1673
|
-
return self.__read_c_type(lpBaseAddress, compat.b(
|
|
1636
|
+
return self.__read_c_type(lpBaseAddress, compat.b("@l"), ctypes.c_int)
|
|
1674
1637
|
|
|
1675
1638
|
def write_int(self, lpBaseAddress, unpackedValue):
|
|
1676
1639
|
"""
|
|
@@ -1688,7 +1651,7 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
1688
1651
|
|
|
1689
1652
|
@raise WindowsError: On error an exception is raised.
|
|
1690
1653
|
"""
|
|
1691
|
-
self.__write_c_type(lpBaseAddress,
|
|
1654
|
+
self.__write_c_type(lpBaseAddress, "@l", unpackedValue)
|
|
1692
1655
|
|
|
1693
1656
|
def read_uint(self, lpBaseAddress):
|
|
1694
1657
|
"""
|
|
@@ -1704,7 +1667,7 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
1704
1667
|
|
|
1705
1668
|
@raise WindowsError: On error an exception is raised.
|
|
1706
1669
|
"""
|
|
1707
|
-
return self.__read_c_type(lpBaseAddress,
|
|
1670
|
+
return self.__read_c_type(lpBaseAddress, "@L", ctypes.c_uint)
|
|
1708
1671
|
|
|
1709
1672
|
def write_uint(self, lpBaseAddress, unpackedValue):
|
|
1710
1673
|
"""
|
|
@@ -1722,7 +1685,7 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
1722
1685
|
|
|
1723
1686
|
@raise WindowsError: On error an exception is raised.
|
|
1724
1687
|
"""
|
|
1725
|
-
self.__write_c_type(lpBaseAddress,
|
|
1688
|
+
self.__write_c_type(lpBaseAddress, "@L", unpackedValue)
|
|
1726
1689
|
|
|
1727
1690
|
def read_float(self, lpBaseAddress):
|
|
1728
1691
|
"""
|
|
@@ -1738,7 +1701,7 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
1738
1701
|
|
|
1739
1702
|
@raise WindowsError: On error an exception is raised.
|
|
1740
1703
|
"""
|
|
1741
|
-
return self.__read_c_type(lpBaseAddress,
|
|
1704
|
+
return self.__read_c_type(lpBaseAddress, "@f", ctypes.c_float)
|
|
1742
1705
|
|
|
1743
1706
|
def write_float(self, lpBaseAddress, unpackedValue):
|
|
1744
1707
|
"""
|
|
@@ -1756,7 +1719,7 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
1756
1719
|
|
|
1757
1720
|
@raise WindowsError: On error an exception is raised.
|
|
1758
1721
|
"""
|
|
1759
|
-
self.__write_c_type(lpBaseAddress,
|
|
1722
|
+
self.__write_c_type(lpBaseAddress, "@f", unpackedValue)
|
|
1760
1723
|
|
|
1761
1724
|
def read_double(self, lpBaseAddress):
|
|
1762
1725
|
"""
|
|
@@ -1772,7 +1735,7 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
1772
1735
|
|
|
1773
1736
|
@raise WindowsError: On error an exception is raised.
|
|
1774
1737
|
"""
|
|
1775
|
-
return self.__read_c_type(lpBaseAddress,
|
|
1738
|
+
return self.__read_c_type(lpBaseAddress, "@d", ctypes.c_double)
|
|
1776
1739
|
|
|
1777
1740
|
def write_double(self, lpBaseAddress, unpackedValue):
|
|
1778
1741
|
"""
|
|
@@ -1790,7 +1753,7 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
1790
1753
|
|
|
1791
1754
|
@raise WindowsError: On error an exception is raised.
|
|
1792
1755
|
"""
|
|
1793
|
-
self.__write_c_type(lpBaseAddress,
|
|
1756
|
+
self.__write_c_type(lpBaseAddress, "@d", unpackedValue)
|
|
1794
1757
|
|
|
1795
1758
|
def read_pointer(self, lpBaseAddress):
|
|
1796
1759
|
"""
|
|
@@ -1806,7 +1769,7 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
1806
1769
|
|
|
1807
1770
|
@raise WindowsError: On error an exception is raised.
|
|
1808
1771
|
"""
|
|
1809
|
-
return self.__read_c_type(lpBaseAddress,
|
|
1772
|
+
return self.__read_c_type(lpBaseAddress, "@P", ctypes.c_void_p)
|
|
1810
1773
|
|
|
1811
1774
|
def write_pointer(self, lpBaseAddress, unpackedValue):
|
|
1812
1775
|
"""
|
|
@@ -1824,7 +1787,7 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
1824
1787
|
|
|
1825
1788
|
@raise WindowsError: On error an exception is raised.
|
|
1826
1789
|
"""
|
|
1827
|
-
self.__write_c_type(lpBaseAddress,
|
|
1790
|
+
self.__write_c_type(lpBaseAddress, "@P", unpackedValue)
|
|
1828
1791
|
|
|
1829
1792
|
def read_dword(self, lpBaseAddress):
|
|
1830
1793
|
"""
|
|
@@ -1840,7 +1803,7 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
1840
1803
|
|
|
1841
1804
|
@raise WindowsError: On error an exception is raised.
|
|
1842
1805
|
"""
|
|
1843
|
-
return self.__read_c_type(lpBaseAddress,
|
|
1806
|
+
return self.__read_c_type(lpBaseAddress, "=L", win32.DWORD)
|
|
1844
1807
|
|
|
1845
1808
|
def write_dword(self, lpBaseAddress, unpackedValue):
|
|
1846
1809
|
"""
|
|
@@ -1858,7 +1821,7 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
1858
1821
|
|
|
1859
1822
|
@raise WindowsError: On error an exception is raised.
|
|
1860
1823
|
"""
|
|
1861
|
-
self.__write_c_type(lpBaseAddress,
|
|
1824
|
+
self.__write_c_type(lpBaseAddress, "=L", unpackedValue)
|
|
1862
1825
|
|
|
1863
1826
|
def read_qword(self, lpBaseAddress):
|
|
1864
1827
|
"""
|
|
@@ -1874,7 +1837,7 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
1874
1837
|
|
|
1875
1838
|
@raise WindowsError: On error an exception is raised.
|
|
1876
1839
|
"""
|
|
1877
|
-
return self.__read_c_type(lpBaseAddress,
|
|
1840
|
+
return self.__read_c_type(lpBaseAddress, "=Q", win32.QWORD)
|
|
1878
1841
|
|
|
1879
1842
|
def write_qword(self, lpBaseAddress, unpackedValue):
|
|
1880
1843
|
"""
|
|
@@ -1892,7 +1855,7 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
1892
1855
|
|
|
1893
1856
|
@raise WindowsError: On error an exception is raised.
|
|
1894
1857
|
"""
|
|
1895
|
-
self.__write_c_type(lpBaseAddress,
|
|
1858
|
+
self.__write_c_type(lpBaseAddress, "=Q", unpackedValue)
|
|
1896
1859
|
|
|
1897
1860
|
def read_structure(self, lpBaseAddress, stype):
|
|
1898
1861
|
"""
|
|
@@ -1916,36 +1879,36 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
1916
1879
|
lpBaseAddress = ctypes.cast(lpBaseAddress, ctypes.c_void_p)
|
|
1917
1880
|
data = self.read(lpBaseAddress, ctypes.sizeof(stype))
|
|
1918
1881
|
buff = ctypes.create_string_buffer(data)
|
|
1919
|
-
ptr
|
|
1882
|
+
ptr = ctypes.cast(ctypes.pointer(buff), ctypes.POINTER(stype))
|
|
1920
1883
|
return ptr.contents
|
|
1921
1884
|
|
|
1922
|
-
# XXX TODO
|
|
1923
|
-
## def write_structure(self, lpBaseAddress, sStructure):
|
|
1924
|
-
## """
|
|
1925
|
-
## Writes a ctypes structure into the memory of the process.
|
|
1926
|
-
##
|
|
1927
|
-
## @note: Page permissions may be changed temporarily while writing.
|
|
1928
|
-
##
|
|
1929
|
-
## @see: L{write}
|
|
1930
|
-
##
|
|
1931
|
-
## @type lpBaseAddress: int
|
|
1932
|
-
## @param lpBaseAddress: Memory address to begin writing.
|
|
1933
|
-
##
|
|
1934
|
-
## @type sStructure: ctypes.Structure or a subclass' instance.
|
|
1935
|
-
## @param sStructure: Structure definition.
|
|
1936
|
-
##
|
|
1937
|
-
## @rtype: int
|
|
1938
|
-
## @return: Structure instance filled in with data
|
|
1939
|
-
## read from the process memory.
|
|
1940
|
-
##
|
|
1941
|
-
## @raise WindowsError: On error an exception is raised.
|
|
1942
|
-
## """
|
|
1943
|
-
## size = ctypes.sizeof(sStructure)
|
|
1944
|
-
## data = ctypes.create_string_buffer("", size = size)
|
|
1945
|
-
## win32.CopyMemory(ctypes.byref(data), ctypes.byref(sStructure), size)
|
|
1946
|
-
## self.write(lpBaseAddress, data.raw)
|
|
1947
|
-
|
|
1948
|
-
def read_string(self, lpBaseAddress, nChars, fUnicode
|
|
1885
|
+
# XXX TODO
|
|
1886
|
+
## def write_structure(self, lpBaseAddress, sStructure):
|
|
1887
|
+
## """
|
|
1888
|
+
## Writes a ctypes structure into the memory of the process.
|
|
1889
|
+
##
|
|
1890
|
+
## @note: Page permissions may be changed temporarily while writing.
|
|
1891
|
+
##
|
|
1892
|
+
## @see: L{write}
|
|
1893
|
+
##
|
|
1894
|
+
## @type lpBaseAddress: int
|
|
1895
|
+
## @param lpBaseAddress: Memory address to begin writing.
|
|
1896
|
+
##
|
|
1897
|
+
## @type sStructure: ctypes.Structure or a subclass' instance.
|
|
1898
|
+
## @param sStructure: Structure definition.
|
|
1899
|
+
##
|
|
1900
|
+
## @rtype: int
|
|
1901
|
+
## @return: Structure instance filled in with data
|
|
1902
|
+
## read from the process memory.
|
|
1903
|
+
##
|
|
1904
|
+
## @raise WindowsError: On error an exception is raised.
|
|
1905
|
+
## """
|
|
1906
|
+
## size = ctypes.sizeof(sStructure)
|
|
1907
|
+
## data = ctypes.create_string_buffer("", size = size)
|
|
1908
|
+
## win32.CopyMemory(ctypes.byref(data), ctypes.byref(sStructure), size)
|
|
1909
|
+
## self.write(lpBaseAddress, data.raw)
|
|
1910
|
+
|
|
1911
|
+
def read_string(self, lpBaseAddress, nChars, fUnicode=False):
|
|
1949
1912
|
"""
|
|
1950
1913
|
Reads an ASCII or Unicode string
|
|
1951
1914
|
from the address space of the process.
|
|
@@ -1972,23 +1935,23 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
1972
1935
|
nChars = nChars * 2
|
|
1973
1936
|
szString = self.read(lpBaseAddress, nChars)
|
|
1974
1937
|
if fUnicode:
|
|
1975
|
-
szString = compat.unicode(szString,
|
|
1938
|
+
szString = compat.unicode(szString, "U16", "ignore")
|
|
1976
1939
|
return szString
|
|
1977
1940
|
|
|
1978
|
-
|
|
1941
|
+
# ------------------------------------------------------------------------------
|
|
1979
1942
|
|
|
1980
1943
|
# FIXME this won't work properly with a different endianness!
|
|
1981
1944
|
def __peek_c_type(self, address, format, c_type):
|
|
1982
1945
|
size = ctypes.sizeof(c_type)
|
|
1983
1946
|
packed = self.peek(address, size)
|
|
1984
1947
|
if len(packed) < size:
|
|
1985
|
-
packed =
|
|
1948
|
+
packed = "\0" * (size - len(packed)) + packed
|
|
1986
1949
|
elif len(packed) > size:
|
|
1987
1950
|
packed = packed[:size]
|
|
1988
1951
|
return struct.unpack(format, packed)[0]
|
|
1989
1952
|
|
|
1990
1953
|
def __poke_c_type(self, address, format, unpacked):
|
|
1991
|
-
packed = struct.pack(
|
|
1954
|
+
packed = struct.pack("@L", unpacked)
|
|
1992
1955
|
return self.poke(address, packed)
|
|
1993
1956
|
|
|
1994
1957
|
def peek(self, lpBaseAddress, nSize):
|
|
@@ -2011,25 +1974,20 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
2011
1974
|
# + Maybe change page permissions before trying to read?
|
|
2012
1975
|
# + Maybe use mquery instead of get_memory_map?
|
|
2013
1976
|
# (less syscalls if we break out of the loop earlier)
|
|
2014
|
-
data =
|
|
1977
|
+
data = ""
|
|
2015
1978
|
if nSize > 0:
|
|
2016
1979
|
try:
|
|
2017
|
-
hProcess = self.get_handle(
|
|
2018
|
-
|
|
2019
|
-
for mbi in self.get_memory_map(lpBaseAddress,
|
|
2020
|
-
lpBaseAddress + nSize):
|
|
1980
|
+
hProcess = self.get_handle(win32.PROCESS_VM_READ | win32.PROCESS_QUERY_INFORMATION)
|
|
1981
|
+
for mbi in self.get_memory_map(lpBaseAddress, lpBaseAddress + nSize):
|
|
2021
1982
|
if not mbi.is_readable():
|
|
2022
1983
|
nSize = mbi.BaseAddress - lpBaseAddress
|
|
2023
1984
|
break
|
|
2024
1985
|
if nSize > 0:
|
|
2025
|
-
data = win32.ReadProcessMemory(
|
|
2026
|
-
hProcess, lpBaseAddress, nSize)
|
|
1986
|
+
data = win32.ReadProcessMemory(hProcess, lpBaseAddress, nSize)
|
|
2027
1987
|
except WindowsError:
|
|
2028
1988
|
e = sys.exc_info()[1]
|
|
2029
1989
|
msg = "Error reading process %d address %s: %s"
|
|
2030
|
-
msg %= (self.get_pid(),
|
|
2031
|
-
HexDump.address(lpBaseAddress),
|
|
2032
|
-
e.strerror)
|
|
1990
|
+
msg %= (self.get_pid(), HexDump.address(lpBaseAddress), e.strerror)
|
|
2033
1991
|
warnings.warn(msg)
|
|
2034
1992
|
return data
|
|
2035
1993
|
|
|
@@ -2052,9 +2010,7 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
2052
2010
|
May be less than the number of bytes to write.
|
|
2053
2011
|
"""
|
|
2054
2012
|
assert isinstance(lpBuffer, compat.bytes)
|
|
2055
|
-
hProcess = self.get_handle(
|
|
2056
|
-
win32.PROCESS_VM_OPERATION |
|
|
2057
|
-
win32.PROCESS_QUERY_INFORMATION )
|
|
2013
|
+
hProcess = self.get_handle(win32.PROCESS_VM_WRITE | win32.PROCESS_VM_OPERATION | win32.PROCESS_QUERY_INFORMATION)
|
|
2058
2014
|
mbi = self.mquery(lpBaseAddress)
|
|
2059
2015
|
if not mbi.has_content():
|
|
2060
2016
|
raise ctypes.WinError(win32.ERROR_INVALID_ADDRESS)
|
|
@@ -2071,11 +2027,8 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
2071
2027
|
self.mprotect(lpBaseAddress, len(lpBuffer), prot)
|
|
2072
2028
|
except Exception:
|
|
2073
2029
|
prot = None
|
|
2074
|
-
msg =
|
|
2075
|
-
|
|
2076
|
-
msg = msg % (self.get_pid(),
|
|
2077
|
-
HexDump.address(lpBaseAddress, self.get_bits()),
|
|
2078
|
-
traceback.format_exc())
|
|
2030
|
+
msg = "Failed to adjust page permissions" " for process %s at address %s: %s"
|
|
2031
|
+
msg = msg % (self.get_pid(), HexDump.address(lpBaseAddress, self.get_bits()), traceback.format_exc())
|
|
2079
2032
|
warnings.warn(msg, RuntimeWarning)
|
|
2080
2033
|
try:
|
|
2081
2034
|
r = win32.WriteProcessMemory(hProcess, lpBaseAddress, lpBuffer)
|
|
@@ -2135,7 +2088,7 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
2135
2088
|
@return: Integer value read from the process memory.
|
|
2136
2089
|
Returns zero on error.
|
|
2137
2090
|
"""
|
|
2138
|
-
return self.__peek_c_type(lpBaseAddress,
|
|
2091
|
+
return self.__peek_c_type(lpBaseAddress, "@l", ctypes.c_int)
|
|
2139
2092
|
|
|
2140
2093
|
def poke_int(self, lpBaseAddress, unpackedValue):
|
|
2141
2094
|
"""
|
|
@@ -2155,7 +2108,7 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
2155
2108
|
@return: Number of bytes written.
|
|
2156
2109
|
May be less than the number of bytes to write.
|
|
2157
2110
|
"""
|
|
2158
|
-
return self.__poke_c_type(lpBaseAddress,
|
|
2111
|
+
return self.__poke_c_type(lpBaseAddress, "@l", unpackedValue)
|
|
2159
2112
|
|
|
2160
2113
|
def peek_uint(self, lpBaseAddress):
|
|
2161
2114
|
"""
|
|
@@ -2170,7 +2123,7 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
2170
2123
|
@return: Integer value read from the process memory.
|
|
2171
2124
|
Returns zero on error.
|
|
2172
2125
|
"""
|
|
2173
|
-
return self.__peek_c_type(lpBaseAddress,
|
|
2126
|
+
return self.__peek_c_type(lpBaseAddress, "@L", ctypes.c_uint)
|
|
2174
2127
|
|
|
2175
2128
|
def poke_uint(self, lpBaseAddress, unpackedValue):
|
|
2176
2129
|
"""
|
|
@@ -2190,7 +2143,7 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
2190
2143
|
@return: Number of bytes written.
|
|
2191
2144
|
May be less than the number of bytes to write.
|
|
2192
2145
|
"""
|
|
2193
|
-
return self.__poke_c_type(lpBaseAddress,
|
|
2146
|
+
return self.__poke_c_type(lpBaseAddress, "@L", unpackedValue)
|
|
2194
2147
|
|
|
2195
2148
|
def peek_float(self, lpBaseAddress):
|
|
2196
2149
|
"""
|
|
@@ -2205,7 +2158,7 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
2205
2158
|
@return: Integer value read from the process memory.
|
|
2206
2159
|
Returns zero on error.
|
|
2207
2160
|
"""
|
|
2208
|
-
return self.__peek_c_type(lpBaseAddress,
|
|
2161
|
+
return self.__peek_c_type(lpBaseAddress, "@f", ctypes.c_float)
|
|
2209
2162
|
|
|
2210
2163
|
def poke_float(self, lpBaseAddress, unpackedValue):
|
|
2211
2164
|
"""
|
|
@@ -2225,7 +2178,7 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
2225
2178
|
@return: Number of bytes written.
|
|
2226
2179
|
May be less than the number of bytes to write.
|
|
2227
2180
|
"""
|
|
2228
|
-
return self.__poke_c_type(lpBaseAddress,
|
|
2181
|
+
return self.__poke_c_type(lpBaseAddress, "@f", unpackedValue)
|
|
2229
2182
|
|
|
2230
2183
|
def peek_double(self, lpBaseAddress):
|
|
2231
2184
|
"""
|
|
@@ -2240,7 +2193,7 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
2240
2193
|
@return: Integer value read from the process memory.
|
|
2241
2194
|
Returns zero on error.
|
|
2242
2195
|
"""
|
|
2243
|
-
return self.__peek_c_type(lpBaseAddress,
|
|
2196
|
+
return self.__peek_c_type(lpBaseAddress, "@d", ctypes.c_double)
|
|
2244
2197
|
|
|
2245
2198
|
def poke_double(self, lpBaseAddress, unpackedValue):
|
|
2246
2199
|
"""
|
|
@@ -2260,7 +2213,7 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
2260
2213
|
@return: Number of bytes written.
|
|
2261
2214
|
May be less than the number of bytes to write.
|
|
2262
2215
|
"""
|
|
2263
|
-
return self.__poke_c_type(lpBaseAddress,
|
|
2216
|
+
return self.__poke_c_type(lpBaseAddress, "@d", unpackedValue)
|
|
2264
2217
|
|
|
2265
2218
|
def peek_dword(self, lpBaseAddress):
|
|
2266
2219
|
"""
|
|
@@ -2275,7 +2228,7 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
2275
2228
|
@return: Integer value read from the process memory.
|
|
2276
2229
|
Returns zero on error.
|
|
2277
2230
|
"""
|
|
2278
|
-
return self.__peek_c_type(lpBaseAddress,
|
|
2231
|
+
return self.__peek_c_type(lpBaseAddress, "=L", win32.DWORD)
|
|
2279
2232
|
|
|
2280
2233
|
def poke_dword(self, lpBaseAddress, unpackedValue):
|
|
2281
2234
|
"""
|
|
@@ -2295,7 +2248,7 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
2295
2248
|
@return: Number of bytes written.
|
|
2296
2249
|
May be less than the number of bytes to write.
|
|
2297
2250
|
"""
|
|
2298
|
-
return self.__poke_c_type(lpBaseAddress,
|
|
2251
|
+
return self.__poke_c_type(lpBaseAddress, "=L", unpackedValue)
|
|
2299
2252
|
|
|
2300
2253
|
def peek_qword(self, lpBaseAddress):
|
|
2301
2254
|
"""
|
|
@@ -2310,7 +2263,7 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
2310
2263
|
@return: Integer value read from the process memory.
|
|
2311
2264
|
Returns zero on error.
|
|
2312
2265
|
"""
|
|
2313
|
-
return self.__peek_c_type(lpBaseAddress,
|
|
2266
|
+
return self.__peek_c_type(lpBaseAddress, "=Q", win32.QWORD)
|
|
2314
2267
|
|
|
2315
2268
|
def poke_qword(self, lpBaseAddress, unpackedValue):
|
|
2316
2269
|
"""
|
|
@@ -2330,7 +2283,7 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
2330
2283
|
@return: Number of bytes written.
|
|
2331
2284
|
May be less than the number of bytes to write.
|
|
2332
2285
|
"""
|
|
2333
|
-
return self.__poke_c_type(lpBaseAddress,
|
|
2286
|
+
return self.__poke_c_type(lpBaseAddress, "=Q", unpackedValue)
|
|
2334
2287
|
|
|
2335
2288
|
def peek_pointer(self, lpBaseAddress):
|
|
2336
2289
|
"""
|
|
@@ -2345,7 +2298,7 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
2345
2298
|
@return: Pointer value read from the process memory.
|
|
2346
2299
|
Returns zero on error.
|
|
2347
2300
|
"""
|
|
2348
|
-
return self.__peek_c_type(lpBaseAddress,
|
|
2301
|
+
return self.__peek_c_type(lpBaseAddress, "@P", ctypes.c_void_p)
|
|
2349
2302
|
|
|
2350
2303
|
def poke_pointer(self, lpBaseAddress, unpackedValue):
|
|
2351
2304
|
"""
|
|
@@ -2365,9 +2318,9 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
2365
2318
|
@return: Number of bytes written.
|
|
2366
2319
|
May be less than the number of bytes to write.
|
|
2367
2320
|
"""
|
|
2368
|
-
return self.__poke_c_type(lpBaseAddress,
|
|
2321
|
+
return self.__poke_c_type(lpBaseAddress, "@P", unpackedValue)
|
|
2369
2322
|
|
|
2370
|
-
def peek_string(self, lpBaseAddress, fUnicode
|
|
2323
|
+
def peek_string(self, lpBaseAddress, fUnicode=False, dwMaxSize=0x1000):
|
|
2371
2324
|
"""
|
|
2372
2325
|
Tries to read an ASCII or Unicode string
|
|
2373
2326
|
from the address space of the process.
|
|
@@ -2393,8 +2346,8 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
2393
2346
|
# Validate the parameters.
|
|
2394
2347
|
if not lpBaseAddress or dwMaxSize == 0:
|
|
2395
2348
|
if fUnicode:
|
|
2396
|
-
return
|
|
2397
|
-
return
|
|
2349
|
+
return ""
|
|
2350
|
+
return ""
|
|
2398
2351
|
if not dwMaxSize:
|
|
2399
2352
|
dwMaxSize = 0x1000
|
|
2400
2353
|
|
|
@@ -2403,31 +2356,29 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
2403
2356
|
|
|
2404
2357
|
# If the string is Unicode...
|
|
2405
2358
|
if fUnicode:
|
|
2406
|
-
|
|
2407
2359
|
# Decode the string.
|
|
2408
|
-
szString = compat.unicode(szString,
|
|
2409
|
-
## try:
|
|
2410
|
-
## szString = compat.unicode(szString, 'U16')
|
|
2411
|
-
## except UnicodeDecodeError:
|
|
2412
|
-
## szString = struct.unpack('H' * (len(szString) / 2), szString)
|
|
2413
|
-
## szString = [ unichr(c) for c in szString ]
|
|
2414
|
-
## szString = u''.join(szString)
|
|
2360
|
+
szString = compat.unicode(szString, "U16", "replace")
|
|
2361
|
+
## try:
|
|
2362
|
+
## szString = compat.unicode(szString, 'U16')
|
|
2363
|
+
## except UnicodeDecodeError:
|
|
2364
|
+
## szString = struct.unpack('H' * (len(szString) / 2), szString)
|
|
2365
|
+
## szString = [ unichr(c) for c in szString ]
|
|
2366
|
+
## szString = u''.join(szString)
|
|
2415
2367
|
|
|
2416
2368
|
# Truncate the string when the first null char is found.
|
|
2417
|
-
szString = szString[
|
|
2369
|
+
szString = szString[: szString.find("\0")]
|
|
2418
2370
|
|
|
2419
2371
|
# If the string is ANSI...
|
|
2420
2372
|
else:
|
|
2421
|
-
|
|
2422
2373
|
# Truncate the string when the first null char is found.
|
|
2423
|
-
szString = szString[
|
|
2374
|
+
szString = szString[: szString.find("\0")]
|
|
2424
2375
|
|
|
2425
2376
|
# Return the decoded string.
|
|
2426
2377
|
return szString
|
|
2427
2378
|
|
|
2428
2379
|
# TODO
|
|
2429
2380
|
# try to avoid reading the same page twice by caching it
|
|
2430
|
-
def peek_pointers_in_data(self, data, peekSize
|
|
2381
|
+
def peek_pointers_in_data(self, data, peekSize=16, peekStep=1):
|
|
2431
2382
|
"""
|
|
2432
2383
|
Tries to guess which values in the given data are valid pointers,
|
|
2433
2384
|
and reads some data from them.
|
|
@@ -2452,23 +2403,23 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
2452
2403
|
result = dict()
|
|
2453
2404
|
ptrSize = win32.sizeof(win32.LPVOID)
|
|
2454
2405
|
if ptrSize == 4:
|
|
2455
|
-
ptrFmt =
|
|
2406
|
+
ptrFmt = "<L"
|
|
2456
2407
|
else:
|
|
2457
|
-
ptrFmt =
|
|
2408
|
+
ptrFmt = "<Q"
|
|
2458
2409
|
if len(data) > 0:
|
|
2459
2410
|
for i in compat.xrange(0, len(data), peekStep):
|
|
2460
|
-
packed
|
|
2411
|
+
packed = data[i : i + ptrSize]
|
|
2461
2412
|
if len(packed) == ptrSize:
|
|
2462
|
-
address
|
|
2463
|
-
## if not address & (~0xFFFF): continue
|
|
2464
|
-
peek_data
|
|
2413
|
+
address = struct.unpack(ptrFmt, packed)[0]
|
|
2414
|
+
## if not address & (~0xFFFF): continue
|
|
2415
|
+
peek_data = self.peek(address, peekSize)
|
|
2465
2416
|
if peek_data:
|
|
2466
2417
|
result[i] = peek_data
|
|
2467
2418
|
return result
|
|
2468
2419
|
|
|
2469
|
-
|
|
2420
|
+
# ------------------------------------------------------------------------------
|
|
2470
2421
|
|
|
2471
|
-
def malloc(self, dwSize, lpAddress
|
|
2422
|
+
def malloc(self, dwSize, lpAddress=None):
|
|
2472
2423
|
"""
|
|
2473
2424
|
Allocates memory into the address space of the process.
|
|
2474
2425
|
|
|
@@ -2547,7 +2498,7 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
2547
2498
|
hProcess = self.get_handle(win32.PROCESS_VM_OPERATION)
|
|
2548
2499
|
win32.VirtualFreeEx(hProcess, lpAddress)
|
|
2549
2500
|
|
|
2550
|
-
|
|
2501
|
+
# ------------------------------------------------------------------------------
|
|
2551
2502
|
|
|
2552
2503
|
def is_pointer(self, address):
|
|
2553
2504
|
"""
|
|
@@ -3031,7 +2982,7 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
3031
2982
|
size = size - mbi.RegionSize
|
|
3032
2983
|
return True
|
|
3033
2984
|
|
|
3034
|
-
def get_memory_map(self, minAddr
|
|
2985
|
+
def get_memory_map(self, minAddr=None, maxAddr=None):
|
|
3035
2986
|
"""
|
|
3036
2987
|
Produces a memory map to the process address space.
|
|
3037
2988
|
|
|
@@ -3050,7 +3001,7 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
3050
3001
|
"""
|
|
3051
3002
|
return list(self.iter_memory_map(minAddr, maxAddr))
|
|
3052
3003
|
|
|
3053
|
-
def generate_memory_map(self, minAddr
|
|
3004
|
+
def generate_memory_map(self, minAddr=None, maxAddr=None):
|
|
3054
3005
|
"""
|
|
3055
3006
|
Returns a L{Regenerator} that can iterate indefinitely over the memory
|
|
3056
3007
|
map to the process address space.
|
|
@@ -3070,7 +3021,7 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
3070
3021
|
"""
|
|
3071
3022
|
return Regenerator(self.iter_memory_map, minAddr, maxAddr)
|
|
3072
3023
|
|
|
3073
|
-
def iter_memory_map(self, minAddr
|
|
3024
|
+
def iter_memory_map(self, minAddr=None, maxAddr=None):
|
|
3074
3025
|
"""
|
|
3075
3026
|
Produces an iterator over the memory map to the process address space.
|
|
3076
3027
|
|
|
@@ -3087,8 +3038,8 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
3087
3038
|
@rtype: iterator of L{win32.MemoryBasicInformation}
|
|
3088
3039
|
@return: List of memory region information objects.
|
|
3089
3040
|
"""
|
|
3090
|
-
minAddr, maxAddr = MemoryAddresses.align_address_range(minAddr,maxAddr)
|
|
3091
|
-
prevAddr
|
|
3041
|
+
minAddr, maxAddr = MemoryAddresses.align_address_range(minAddr, maxAddr)
|
|
3042
|
+
prevAddr = minAddr - 1
|
|
3092
3043
|
currentAddr = minAddr
|
|
3093
3044
|
while prevAddr < currentAddr < maxAddr:
|
|
3094
3045
|
try:
|
|
@@ -3099,10 +3050,10 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
3099
3050
|
break
|
|
3100
3051
|
raise
|
|
3101
3052
|
yield mbi
|
|
3102
|
-
prevAddr
|
|
3053
|
+
prevAddr = currentAddr
|
|
3103
3054
|
currentAddr = mbi.BaseAddress + mbi.RegionSize
|
|
3104
3055
|
|
|
3105
|
-
def get_mapped_filenames(self, memoryMap
|
|
3056
|
+
def get_mapped_filenames(self, memoryMap=None):
|
|
3106
3057
|
"""
|
|
3107
3058
|
Retrieves the filenames for memory mapped files in the debugee.
|
|
3108
3059
|
|
|
@@ -3114,8 +3065,7 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
3114
3065
|
@return: Dictionary mapping memory addresses to file names.
|
|
3115
3066
|
Native filenames are converted to Win32 filenames when possible.
|
|
3116
3067
|
"""
|
|
3117
|
-
hProcess = self.get_handle(
|
|
3118
|
-
win32.PROCESS_QUERY_INFORMATION )
|
|
3068
|
+
hProcess = self.get_handle(win32.PROCESS_VM_READ | win32.PROCESS_QUERY_INFORMATION)
|
|
3119
3069
|
if not memoryMap:
|
|
3120
3070
|
memoryMap = self.get_memory_map()
|
|
3121
3071
|
mappedFilenames = dict()
|
|
@@ -3123,24 +3073,24 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
3123
3073
|
if mbi.Type not in (win32.MEM_IMAGE, win32.MEM_MAPPED):
|
|
3124
3074
|
continue
|
|
3125
3075
|
baseAddress = mbi.BaseAddress
|
|
3126
|
-
fileName
|
|
3076
|
+
fileName = ""
|
|
3127
3077
|
try:
|
|
3128
3078
|
fileName = win32.GetMappedFileName(hProcess, baseAddress)
|
|
3129
3079
|
fileName = PathOperations.native_to_win32_pathname(fileName)
|
|
3130
3080
|
except WindowsError:
|
|
3131
|
-
#e = sys.exc_info()[1]
|
|
3132
|
-
#try:
|
|
3081
|
+
# e = sys.exc_info()[1]
|
|
3082
|
+
# try:
|
|
3133
3083
|
# msg = "Can't get mapped file name at address %s in process " \
|
|
3134
3084
|
# "%d, reason: %s" % (HexDump.address(baseAddress),
|
|
3135
3085
|
# self.get_pid(),
|
|
3136
3086
|
# e.strerror)
|
|
3137
3087
|
# warnings.warn(msg, Warning)
|
|
3138
|
-
#except Exception:
|
|
3088
|
+
# except Exception:
|
|
3139
3089
|
pass
|
|
3140
3090
|
mappedFilenames[baseAddress] = fileName
|
|
3141
3091
|
return mappedFilenames
|
|
3142
3092
|
|
|
3143
|
-
def generate_memory_snapshot(self, minAddr
|
|
3093
|
+
def generate_memory_snapshot(self, minAddr=None, maxAddr=None):
|
|
3144
3094
|
"""
|
|
3145
3095
|
Returns a L{Regenerator} that allows you to iterate through the memory
|
|
3146
3096
|
contents of a process indefinitely.
|
|
@@ -3185,7 +3135,7 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
3185
3135
|
"""
|
|
3186
3136
|
return Regenerator(self.iter_memory_snapshot, minAddr, maxAddr)
|
|
3187
3137
|
|
|
3188
|
-
def iter_memory_snapshot(self, minAddr
|
|
3138
|
+
def iter_memory_snapshot(self, minAddr=None, maxAddr=None):
|
|
3189
3139
|
"""
|
|
3190
3140
|
Returns an iterator that allows you to go through the memory contents
|
|
3191
3141
|
of a process.
|
|
@@ -3257,7 +3207,7 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
3257
3207
|
minAddr = MemoryAddresses.align_address_to_page_start(minAddr)
|
|
3258
3208
|
mbi = memory[0]
|
|
3259
3209
|
if mbi.BaseAddress < minAddr:
|
|
3260
|
-
mbi.RegionSize
|
|
3210
|
+
mbi.RegionSize = mbi.BaseAddress + mbi.RegionSize - minAddr
|
|
3261
3211
|
mbi.BaseAddress = minAddr
|
|
3262
3212
|
|
|
3263
3213
|
# Trim the last memory information block if needed.
|
|
@@ -3270,7 +3220,7 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
3270
3220
|
|
|
3271
3221
|
# Read the contents of each block and yield it.
|
|
3272
3222
|
while memory:
|
|
3273
|
-
mbi = memory.pop(0)
|
|
3223
|
+
mbi = memory.pop(0) # so the garbage collector can take it
|
|
3274
3224
|
mbi.filename = filenames.get(mbi.BaseAddress, None)
|
|
3275
3225
|
if mbi.has_content():
|
|
3276
3226
|
mbi.content = self.read(mbi.BaseAddress, mbi.RegionSize)
|
|
@@ -3278,7 +3228,7 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
3278
3228
|
mbi.content = None
|
|
3279
3229
|
yield mbi
|
|
3280
3230
|
|
|
3281
|
-
def take_memory_snapshot(self, minAddr
|
|
3231
|
+
def take_memory_snapshot(self, minAddr=None, maxAddr=None):
|
|
3282
3232
|
"""
|
|
3283
3233
|
Takes a snapshot of the memory contents of the process.
|
|
3284
3234
|
|
|
@@ -3316,11 +3266,9 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
3316
3266
|
- C{filename}: Mapped filename, or C{None}.
|
|
3317
3267
|
- C{content}: Memory contents, or C{None}.
|
|
3318
3268
|
"""
|
|
3319
|
-
return list(
|
|
3269
|
+
return list(self.iter_memory_snapshot(minAddr, maxAddr))
|
|
3320
3270
|
|
|
3321
|
-
def restore_memory_snapshot(self, snapshot,
|
|
3322
|
-
bSkipMappedFiles = True,
|
|
3323
|
-
bSkipOnError = False):
|
|
3271
|
+
def restore_memory_snapshot(self, snapshot, bSkipMappedFiles=True, bSkipOnError=False):
|
|
3324
3272
|
"""
|
|
3325
3273
|
Attempts to restore the memory state as it was when the given snapshot
|
|
3326
3274
|
was taken.
|
|
@@ -3352,42 +3300,34 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
3352
3300
|
@raise RuntimeError: An error occured while restoring the snapshot.
|
|
3353
3301
|
@raise TypeError: A snapshot of the wrong type was passed.
|
|
3354
3302
|
"""
|
|
3355
|
-
if not snapshot or not isinstance(snapshot, list)
|
|
3356
|
-
|
|
3357
|
-
raise TypeError( "Only snapshots returned by " \
|
|
3358
|
-
"take_memory_snapshot() can be used here." )
|
|
3303
|
+
if not snapshot or not isinstance(snapshot, list) or not isinstance(snapshot[0], win32.MemoryBasicInformation):
|
|
3304
|
+
raise TypeError("Only snapshots returned by " "take_memory_snapshot() can be used here.")
|
|
3359
3305
|
|
|
3360
3306
|
# Get the process handle.
|
|
3361
|
-
hProcess = self.get_handle(
|
|
3362
|
-
|
|
3363
|
-
|
|
3364
|
-
win32.PROCESS_QUERY_INFORMATION )
|
|
3307
|
+
hProcess = self.get_handle(
|
|
3308
|
+
win32.PROCESS_VM_WRITE | win32.PROCESS_VM_OPERATION | win32.PROCESS_SUSPEND_RESUME | win32.PROCESS_QUERY_INFORMATION
|
|
3309
|
+
)
|
|
3365
3310
|
|
|
3366
3311
|
# Freeze the process.
|
|
3367
3312
|
self.suspend()
|
|
3368
3313
|
try:
|
|
3369
|
-
|
|
3370
3314
|
# For each memory region in the snapshot...
|
|
3371
3315
|
for old_mbi in snapshot:
|
|
3372
|
-
|
|
3373
3316
|
# If the region matches, restore it directly.
|
|
3374
3317
|
new_mbi = self.mquery(old_mbi.BaseAddress)
|
|
3375
|
-
if new_mbi.BaseAddress == old_mbi.BaseAddress and
|
|
3376
|
-
|
|
3377
|
-
self.__restore_mbi(hProcess, new_mbi, old_mbi,
|
|
3378
|
-
bSkipMappedFiles)
|
|
3318
|
+
if new_mbi.BaseAddress == old_mbi.BaseAddress and new_mbi.RegionSize == old_mbi.RegionSize:
|
|
3319
|
+
self.__restore_mbi(hProcess, new_mbi, old_mbi, bSkipMappedFiles)
|
|
3379
3320
|
|
|
3380
3321
|
# If the region doesn't match, restore it page by page.
|
|
3381
3322
|
else:
|
|
3382
|
-
|
|
3383
3323
|
# We need a copy so we don't corrupt the snapshot.
|
|
3384
3324
|
old_mbi = win32.MemoryBasicInformation(old_mbi)
|
|
3385
3325
|
|
|
3386
3326
|
# Get the overlapping range of pages.
|
|
3387
3327
|
old_start = old_mbi.BaseAddress
|
|
3388
|
-
old_end
|
|
3328
|
+
old_end = old_start + old_mbi.RegionSize
|
|
3389
3329
|
new_start = new_mbi.BaseAddress
|
|
3390
|
-
new_end
|
|
3330
|
+
new_end = new_start + new_mbi.RegionSize
|
|
3391
3331
|
if old_start > new_start:
|
|
3392
3332
|
start = old_start
|
|
3393
3333
|
else:
|
|
@@ -3405,114 +3345,83 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
3405
3345
|
while address < end:
|
|
3406
3346
|
old_mbi.BaseAddress = address
|
|
3407
3347
|
new_mbi.BaseAddress = address
|
|
3408
|
-
self.__restore_mbi(hProcess, new_mbi, old_mbi,
|
|
3409
|
-
bSkipMappedFiles, bSkipOnError)
|
|
3348
|
+
self.__restore_mbi(hProcess, new_mbi, old_mbi, bSkipMappedFiles, bSkipOnError)
|
|
3410
3349
|
address = address + step
|
|
3411
3350
|
|
|
3412
3351
|
# Resume execution.
|
|
3413
3352
|
finally:
|
|
3414
3353
|
self.resume()
|
|
3415
3354
|
|
|
3416
|
-
def __restore_mbi(self, hProcess, new_mbi, old_mbi, bSkipMappedFiles,
|
|
3417
|
-
bSkipOnError):
|
|
3355
|
+
def __restore_mbi(self, hProcess, new_mbi, old_mbi, bSkipMappedFiles, bSkipOnError):
|
|
3418
3356
|
"""
|
|
3419
3357
|
Used internally by L{restore_memory_snapshot}.
|
|
3420
3358
|
"""
|
|
3421
3359
|
|
|
3422
|
-
## print "Restoring %s-%s" % (
|
|
3423
|
-
## HexDump.address(old_mbi.BaseAddress, self.get_bits()),
|
|
3424
|
-
## HexDump.address(old_mbi.BaseAddress + old_mbi.RegionSize,
|
|
3425
|
-
## self.get_bits()))
|
|
3360
|
+
## print "Restoring %s-%s" % (
|
|
3361
|
+
## HexDump.address(old_mbi.BaseAddress, self.get_bits()),
|
|
3362
|
+
## HexDump.address(old_mbi.BaseAddress + old_mbi.RegionSize,
|
|
3363
|
+
## self.get_bits()))
|
|
3426
3364
|
|
|
3427
3365
|
try:
|
|
3428
|
-
|
|
3429
3366
|
# Restore the region state.
|
|
3430
3367
|
if new_mbi.State != old_mbi.State:
|
|
3431
3368
|
if new_mbi.is_free():
|
|
3432
3369
|
if old_mbi.is_reserved():
|
|
3433
|
-
|
|
3434
3370
|
# Free -> Reserved
|
|
3435
|
-
address = win32.VirtualAllocEx(
|
|
3436
|
-
|
|
3437
|
-
|
|
3438
|
-
win32.MEM_RESERVE,
|
|
3439
|
-
old_mbi.Protect)
|
|
3371
|
+
address = win32.VirtualAllocEx(
|
|
3372
|
+
hProcess, old_mbi.BaseAddress, old_mbi.RegionSize, win32.MEM_RESERVE, old_mbi.Protect
|
|
3373
|
+
)
|
|
3440
3374
|
if address != old_mbi.BaseAddress:
|
|
3441
3375
|
self.free(address)
|
|
3442
3376
|
msg = "Error restoring region at address %s"
|
|
3443
|
-
msg = msg % HexDump(old_mbi.BaseAddress,
|
|
3444
|
-
self.get_bits())
|
|
3377
|
+
msg = msg % HexDump(old_mbi.BaseAddress, self.get_bits())
|
|
3445
3378
|
raise RuntimeError(msg)
|
|
3446
3379
|
# permissions already restored
|
|
3447
3380
|
new_mbi.Protect = old_mbi.Protect
|
|
3448
3381
|
|
|
3449
|
-
else:
|
|
3450
|
-
|
|
3382
|
+
else: # elif old_mbi.is_commited():
|
|
3451
3383
|
# Free -> Commited
|
|
3452
|
-
address = win32.VirtualAllocEx(
|
|
3453
|
-
|
|
3454
|
-
|
|
3455
|
-
win32.MEM_RESERVE | \
|
|
3456
|
-
win32.MEM_COMMIT,
|
|
3457
|
-
old_mbi.Protect)
|
|
3384
|
+
address = win32.VirtualAllocEx(
|
|
3385
|
+
hProcess, old_mbi.BaseAddress, old_mbi.RegionSize, win32.MEM_RESERVE | win32.MEM_COMMIT, old_mbi.Protect
|
|
3386
|
+
)
|
|
3458
3387
|
if address != old_mbi.BaseAddress:
|
|
3459
3388
|
self.free(address)
|
|
3460
3389
|
msg = "Error restoring region at address %s"
|
|
3461
|
-
msg = msg % HexDump(old_mbi.BaseAddress,
|
|
3462
|
-
self.get_bits())
|
|
3390
|
+
msg = msg % HexDump(old_mbi.BaseAddress, self.get_bits())
|
|
3463
3391
|
raise RuntimeError(msg)
|
|
3464
3392
|
# permissions already restored
|
|
3465
3393
|
new_mbi.Protect = old_mbi.Protect
|
|
3466
3394
|
|
|
3467
3395
|
elif new_mbi.is_reserved():
|
|
3468
3396
|
if old_mbi.is_commited():
|
|
3469
|
-
|
|
3470
3397
|
# Reserved -> Commited
|
|
3471
|
-
address = win32.VirtualAllocEx(hProcess,
|
|
3472
|
-
old_mbi.BaseAddress,
|
|
3473
|
-
old_mbi.RegionSize,
|
|
3474
|
-
win32.MEM_COMMIT,
|
|
3475
|
-
old_mbi.Protect)
|
|
3398
|
+
address = win32.VirtualAllocEx(hProcess, old_mbi.BaseAddress, old_mbi.RegionSize, win32.MEM_COMMIT, old_mbi.Protect)
|
|
3476
3399
|
if address != old_mbi.BaseAddress:
|
|
3477
3400
|
self.free(address)
|
|
3478
3401
|
msg = "Error restoring region at address %s"
|
|
3479
|
-
msg = msg % HexDump(old_mbi.BaseAddress,
|
|
3480
|
-
self.get_bits())
|
|
3402
|
+
msg = msg % HexDump(old_mbi.BaseAddress, self.get_bits())
|
|
3481
3403
|
raise RuntimeError(msg)
|
|
3482
3404
|
# permissions already restored
|
|
3483
3405
|
new_mbi.Protect = old_mbi.Protect
|
|
3484
3406
|
|
|
3485
|
-
else:
|
|
3486
|
-
|
|
3407
|
+
else: # elif old_mbi.is_free():
|
|
3487
3408
|
# Reserved -> Free
|
|
3488
|
-
win32.VirtualFreeEx(hProcess,
|
|
3489
|
-
old_mbi.BaseAddress,
|
|
3490
|
-
old_mbi.RegionSize,
|
|
3491
|
-
win32.MEM_RELEASE)
|
|
3409
|
+
win32.VirtualFreeEx(hProcess, old_mbi.BaseAddress, old_mbi.RegionSize, win32.MEM_RELEASE)
|
|
3492
3410
|
|
|
3493
|
-
else:
|
|
3411
|
+
else: # elif new_mbi.is_commited():
|
|
3494
3412
|
if old_mbi.is_reserved():
|
|
3495
|
-
|
|
3496
3413
|
# Commited -> Reserved
|
|
3497
|
-
win32.VirtualFreeEx(hProcess,
|
|
3498
|
-
old_mbi.BaseAddress,
|
|
3499
|
-
old_mbi.RegionSize,
|
|
3500
|
-
win32.MEM_DECOMMIT)
|
|
3501
|
-
|
|
3502
|
-
else: # elif old_mbi.is_free():
|
|
3414
|
+
win32.VirtualFreeEx(hProcess, old_mbi.BaseAddress, old_mbi.RegionSize, win32.MEM_DECOMMIT)
|
|
3503
3415
|
|
|
3416
|
+
else: # elif old_mbi.is_free():
|
|
3504
3417
|
# Commited -> Free
|
|
3505
|
-
win32.VirtualFreeEx(hProcess,
|
|
3506
|
-
old_mbi.BaseAddress,
|
|
3507
|
-
old_mbi.RegionSize,
|
|
3508
|
-
win32.MEM_DECOMMIT | win32.MEM_RELEASE)
|
|
3418
|
+
win32.VirtualFreeEx(hProcess, old_mbi.BaseAddress, old_mbi.RegionSize, win32.MEM_DECOMMIT | win32.MEM_RELEASE)
|
|
3509
3419
|
|
|
3510
3420
|
new_mbi.State = old_mbi.State
|
|
3511
3421
|
|
|
3512
3422
|
# Restore the region permissions.
|
|
3513
3423
|
if old_mbi.is_commited() and old_mbi.Protect != new_mbi.Protect:
|
|
3514
|
-
win32.VirtualProtectEx(hProcess, old_mbi.BaseAddress,
|
|
3515
|
-
old_mbi.RegionSize, old_mbi.Protect)
|
|
3424
|
+
win32.VirtualProtectEx(hProcess, old_mbi.BaseAddress, old_mbi.RegionSize, old_mbi.Protect)
|
|
3516
3425
|
new_mbi.Protect = old_mbi.Protect
|
|
3517
3426
|
|
|
3518
3427
|
# Restore the region data.
|
|
@@ -3530,14 +3439,12 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
3530
3439
|
if not bSkipOnError:
|
|
3531
3440
|
raise
|
|
3532
3441
|
msg = "Error restoring region at address %s: %s"
|
|
3533
|
-
msg = msg % (
|
|
3534
|
-
HexDump(old_mbi.BaseAddress, self.get_bits()),
|
|
3535
|
-
traceback.format_exc())
|
|
3442
|
+
msg = msg % (HexDump(old_mbi.BaseAddress, self.get_bits()), traceback.format_exc())
|
|
3536
3443
|
warnings.warn(msg, RuntimeWarning)
|
|
3537
3444
|
|
|
3538
|
-
|
|
3445
|
+
# ------------------------------------------------------------------------------
|
|
3539
3446
|
|
|
3540
|
-
def inject_code(self, payload, lpParameter
|
|
3447
|
+
def inject_code(self, payload, lpParameter=0):
|
|
3541
3448
|
"""
|
|
3542
3449
|
Injects relocatable code into the process memory and executes it.
|
|
3543
3450
|
|
|
@@ -3560,20 +3467,18 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
3560
3467
|
"""
|
|
3561
3468
|
|
|
3562
3469
|
# Uncomment for debugging...
|
|
3563
|
-
## payload = '\xCC' + payload
|
|
3470
|
+
## payload = '\xCC' + payload
|
|
3564
3471
|
|
|
3565
3472
|
# Allocate the memory for the shellcode.
|
|
3566
3473
|
lpStartAddress = self.malloc(len(payload))
|
|
3567
3474
|
|
|
3568
3475
|
# Catch exceptions so we can free the memory on error.
|
|
3569
3476
|
try:
|
|
3570
|
-
|
|
3571
3477
|
# Write the shellcode to our memory location.
|
|
3572
3478
|
self.write(lpStartAddress, payload)
|
|
3573
3479
|
|
|
3574
3480
|
# Start a new thread for the shellcode to run.
|
|
3575
|
-
aThread = self.start_thread(lpStartAddress, lpParameter,
|
|
3576
|
-
bSuspended = False)
|
|
3481
|
+
aThread = self.start_thread(lpStartAddress, lpParameter, bSuspended=False)
|
|
3577
3482
|
|
|
3578
3483
|
# Remember the shellcode address.
|
|
3579
3484
|
# It will be freed ONLY by the Thread.kill() method
|
|
@@ -3594,8 +3499,7 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
3594
3499
|
# The shellcode should check for errors, otherwise it just crashes
|
|
3595
3500
|
# when the DLL can't be loaded or the procedure can't be found.
|
|
3596
3501
|
# On error the shellcode should execute an int3 instruction.
|
|
3597
|
-
def inject_dll(self, dllname, procname
|
|
3598
|
-
bWait = True, dwTimeout = None):
|
|
3502
|
+
def inject_dll(self, dllname, procname=None, lpParameter=0, bWait=True, dwTimeout=None):
|
|
3599
3503
|
"""
|
|
3600
3504
|
Injects a DLL into the process memory.
|
|
3601
3505
|
|
|
@@ -3652,13 +3556,12 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
3652
3556
|
"""
|
|
3653
3557
|
|
|
3654
3558
|
# Resolve kernel32.dll
|
|
3655
|
-
aModule = self.get_module_by_name(compat.b(
|
|
3559
|
+
aModule = self.get_module_by_name(compat.b("kernel32.dll"))
|
|
3656
3560
|
if aModule is None:
|
|
3657
3561
|
self.scan_modules()
|
|
3658
|
-
aModule = self.get_module_by_name(compat.b(
|
|
3562
|
+
aModule = self.get_module_by_name(compat.b("kernel32.dll"))
|
|
3659
3563
|
if aModule is None:
|
|
3660
|
-
raise RuntimeError(
|
|
3661
|
-
"Cannot resolve kernel32.dll in the remote process")
|
|
3564
|
+
raise RuntimeError("Cannot resolve kernel32.dll in the remote process")
|
|
3662
3565
|
|
|
3663
3566
|
# Old method, using shellcode.
|
|
3664
3567
|
if procname:
|
|
@@ -3667,88 +3570,81 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
3667
3570
|
dllname = compat.b(dllname)
|
|
3668
3571
|
|
|
3669
3572
|
# Resolve kernel32.dll!LoadLibraryA
|
|
3670
|
-
pllib = aModule.resolve(compat.b(
|
|
3573
|
+
pllib = aModule.resolve(compat.b("LoadLibraryA"))
|
|
3671
3574
|
if not pllib:
|
|
3672
|
-
raise RuntimeError(
|
|
3673
|
-
"Cannot resolve kernel32.dll!LoadLibraryA"
|
|
3674
|
-
" in the remote process")
|
|
3575
|
+
raise RuntimeError("Cannot resolve kernel32.dll!LoadLibraryA" " in the remote process")
|
|
3675
3576
|
|
|
3676
3577
|
# Resolve kernel32.dll!GetProcAddress
|
|
3677
|
-
pgpad = aModule.resolve(compat.b(
|
|
3578
|
+
pgpad = aModule.resolve(compat.b("GetProcAddress"))
|
|
3678
3579
|
if not pgpad:
|
|
3679
|
-
raise RuntimeError(
|
|
3680
|
-
"Cannot resolve kernel32.dll!GetProcAddress"
|
|
3681
|
-
" in the remote process")
|
|
3580
|
+
raise RuntimeError("Cannot resolve kernel32.dll!GetProcAddress" " in the remote process")
|
|
3682
3581
|
|
|
3683
3582
|
# Resolve kernel32.dll!VirtualFree
|
|
3684
|
-
pvf = aModule.resolve(compat.b(
|
|
3583
|
+
pvf = aModule.resolve(compat.b("VirtualFree"))
|
|
3685
3584
|
if not pvf:
|
|
3686
|
-
raise RuntimeError(
|
|
3687
|
-
"Cannot resolve kernel32.dll!VirtualFree"
|
|
3688
|
-
" in the remote process")
|
|
3585
|
+
raise RuntimeError("Cannot resolve kernel32.dll!VirtualFree" " in the remote process")
|
|
3689
3586
|
|
|
3690
3587
|
# Shellcode follows...
|
|
3691
|
-
code
|
|
3588
|
+
code = compat.b("")
|
|
3692
3589
|
|
|
3693
3590
|
# push dllname
|
|
3694
|
-
code += compat.b(
|
|
3591
|
+
code += compat.b("\xe8") + struct.pack("<L", len(dllname) + 1) + dllname + compat.b("\0")
|
|
3695
3592
|
|
|
3696
3593
|
# mov eax, LoadLibraryA
|
|
3697
|
-
code += compat.b(
|
|
3594
|
+
code += compat.b("\xb8") + struct.pack("<L", pllib)
|
|
3698
3595
|
|
|
3699
3596
|
# call eax
|
|
3700
|
-
code += compat.b(
|
|
3597
|
+
code += compat.b("\xff\xd0")
|
|
3701
3598
|
|
|
3702
3599
|
if procname:
|
|
3703
|
-
|
|
3704
3600
|
# push procname
|
|
3705
|
-
code += compat.b(
|
|
3706
|
-
code += procname + compat.b(
|
|
3601
|
+
code += compat.b("\xe8") + struct.pack("<L", len(procname) + 1)
|
|
3602
|
+
code += procname + compat.b("\0")
|
|
3707
3603
|
|
|
3708
3604
|
# push eax
|
|
3709
|
-
code += compat.b(
|
|
3605
|
+
code += compat.b("\x50")
|
|
3710
3606
|
|
|
3711
3607
|
# mov eax, GetProcAddress
|
|
3712
|
-
code += compat.b(
|
|
3608
|
+
code += compat.b("\xb8") + struct.pack("<L", pgpad)
|
|
3713
3609
|
|
|
3714
3610
|
# call eax
|
|
3715
|
-
code += compat.b(
|
|
3611
|
+
code += compat.b("\xff\xd0")
|
|
3716
3612
|
|
|
3717
3613
|
# mov ebp, esp ; preserve stack pointer
|
|
3718
|
-
code += compat.b(
|
|
3614
|
+
code += compat.b("\x8b\xec")
|
|
3719
3615
|
|
|
3720
3616
|
# push lpParameter
|
|
3721
|
-
code += compat.b(
|
|
3617
|
+
code += compat.b("\x68") + struct.pack("<L", lpParameter)
|
|
3722
3618
|
|
|
3723
3619
|
# call eax
|
|
3724
|
-
code += compat.b(
|
|
3620
|
+
code += compat.b("\xff\xd0")
|
|
3725
3621
|
|
|
3726
3622
|
# mov esp, ebp ; restore stack pointer
|
|
3727
|
-
code += compat.b(
|
|
3623
|
+
code += compat.b("\x8b\xe5")
|
|
3728
3624
|
|
|
3729
3625
|
# pop edx ; our own return address
|
|
3730
|
-
code += compat.b(
|
|
3626
|
+
code += compat.b("\x5a")
|
|
3731
3627
|
|
|
3732
3628
|
# push MEM_RELEASE ; dwFreeType
|
|
3733
|
-
code += compat.b(
|
|
3629
|
+
code += compat.b("\x68") + struct.pack("<L", win32.MEM_RELEASE)
|
|
3734
3630
|
|
|
3735
3631
|
# push 0x1000 ; dwSize, shellcode max size 4096 bytes
|
|
3736
|
-
code += compat.b(
|
|
3632
|
+
code += compat.b("\x68") + struct.pack("<L", 0x1000)
|
|
3737
3633
|
|
|
3738
3634
|
# call $+5
|
|
3739
|
-
code += compat.b(
|
|
3635
|
+
code += compat.b("\xe8\x00\x00\x00\x00")
|
|
3740
3636
|
|
|
3741
3637
|
# and dword ptr [esp], 0xFFFFF000 ; align to page boundary
|
|
3742
|
-
code += compat.b(
|
|
3638
|
+
code += compat.b("\x81\x24\x24\x00\xf0\xff\xff")
|
|
3743
3639
|
|
|
3744
3640
|
# mov eax, VirtualFree
|
|
3745
|
-
code += compat.b(
|
|
3641
|
+
code += compat.b("\xb8") + struct.pack("<L", pvf)
|
|
3746
3642
|
|
|
3747
3643
|
# push edx ; our own return address
|
|
3748
|
-
code += compat.b(
|
|
3644
|
+
code += compat.b("\x52")
|
|
3749
3645
|
|
|
3750
3646
|
# jmp eax ; VirtualFree will return to our own return address
|
|
3751
|
-
code += compat.b(
|
|
3647
|
+
code += compat.b("\xff\xe0")
|
|
3752
3648
|
|
|
3753
3649
|
# Inject the shellcode.
|
|
3754
3650
|
# There's no need to free the memory,
|
|
@@ -3757,15 +3653,14 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
3757
3653
|
|
|
3758
3654
|
# New method, not using shellcode.
|
|
3759
3655
|
else:
|
|
3760
|
-
|
|
3761
3656
|
# Resolve kernel32.dll!LoadLibrary (A/W)
|
|
3762
|
-
if type(dllname) == type(
|
|
3763
|
-
pllibname = compat.b(
|
|
3657
|
+
if type(dllname) == type(""):
|
|
3658
|
+
pllibname = compat.b("LoadLibraryW")
|
|
3764
3659
|
bufferlen = (len(dllname) + 1) * 2
|
|
3765
|
-
dllname = win32.ctypes.create_unicode_buffer(dllname).raw[:bufferlen + 1]
|
|
3660
|
+
dllname = win32.ctypes.create_unicode_buffer(dllname).raw[: bufferlen + 1]
|
|
3766
3661
|
else:
|
|
3767
|
-
pllibname = compat.b(
|
|
3768
|
-
dllname
|
|
3662
|
+
pllibname = compat.b("LoadLibraryA")
|
|
3663
|
+
dllname = compat.b(dllname) + compat.b("\x00")
|
|
3769
3664
|
bufferlen = len(dllname)
|
|
3770
3665
|
pllib = aModule.resolve(pllibname)
|
|
3771
3666
|
if not pllib:
|
|
@@ -3788,10 +3683,7 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
3788
3683
|
# This specific error is caused by trying to spawn a new
|
|
3789
3684
|
# thread in a process belonging to a different Terminal
|
|
3790
3685
|
# Services session (for example a service).
|
|
3791
|
-
raise NotImplementedError(
|
|
3792
|
-
"Target process belongs to a different"
|
|
3793
|
-
" Terminal Services session, cannot inject!"
|
|
3794
|
-
)
|
|
3686
|
+
raise NotImplementedError("Target process belongs to a different" " Terminal Services session, cannot inject!")
|
|
3795
3687
|
|
|
3796
3688
|
# Remember the buffer address.
|
|
3797
3689
|
# It will be freed ONLY by the Thread.kill() method
|
|
@@ -3813,7 +3705,7 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
3813
3705
|
# Return the thread object.
|
|
3814
3706
|
return aThread
|
|
3815
3707
|
|
|
3816
|
-
def clean_exit(self, dwExitCode
|
|
3708
|
+
def clean_exit(self, dwExitCode=0, bWait=False, dwTimeout=None):
|
|
3817
3709
|
"""
|
|
3818
3710
|
Injects a new thread to call ExitProcess().
|
|
3819
3711
|
Optionally waits for the injected thread to finish.
|
|
@@ -3836,12 +3728,12 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
3836
3728
|
"""
|
|
3837
3729
|
if not dwExitCode:
|
|
3838
3730
|
dwExitCode = 0
|
|
3839
|
-
pExitProcess = self.resolve_label(
|
|
3731
|
+
pExitProcess = self.resolve_label("kernel32!ExitProcess")
|
|
3840
3732
|
aThread = self.start_thread(pExitProcess, dwExitCode)
|
|
3841
3733
|
if bWait:
|
|
3842
3734
|
aThread.wait(dwTimeout)
|
|
3843
3735
|
|
|
3844
|
-
|
|
3736
|
+
# ------------------------------------------------------------------------------
|
|
3845
3737
|
|
|
3846
3738
|
def _notify_create_process(self, event):
|
|
3847
3739
|
"""
|
|
@@ -3858,13 +3750,14 @@ class Process (_ThreadContainer, _ModuleContainer):
|
|
|
3858
3750
|
"""
|
|
3859
3751
|
# Do not use super() here.
|
|
3860
3752
|
bCallHandler = _ThreadContainer._notify_create_process(self, event)
|
|
3861
|
-
bCallHandler = bCallHandler and
|
|
3862
|
-
_ModuleContainer._notify_create_process(self, event)
|
|
3753
|
+
bCallHandler = bCallHandler and _ModuleContainer._notify_create_process(self, event)
|
|
3863
3754
|
return bCallHandler
|
|
3864
3755
|
|
|
3865
|
-
#==============================================================================
|
|
3866
3756
|
|
|
3867
|
-
|
|
3757
|
+
# ==============================================================================
|
|
3758
|
+
|
|
3759
|
+
|
|
3760
|
+
class _ProcessContainer(object):
|
|
3868
3761
|
"""
|
|
3869
3762
|
Encapsulates the capability to contain Process objects.
|
|
3870
3763
|
|
|
@@ -3905,10 +3798,10 @@ class _ProcessContainer (object):
|
|
|
3905
3798
|
"""
|
|
3906
3799
|
if not self.__processDict:
|
|
3907
3800
|
try:
|
|
3908
|
-
self.scan_processes()
|
|
3801
|
+
self.scan_processes() # remote desktop api (relative fn)
|
|
3909
3802
|
except Exception:
|
|
3910
3803
|
self.scan_processes_fast() # psapi (no filenames)
|
|
3911
|
-
self.scan_process_filenames()
|
|
3804
|
+
self.scan_process_filenames() # get the pathnames when possible
|
|
3912
3805
|
|
|
3913
3806
|
def __contains__(self, anObject):
|
|
3914
3807
|
"""
|
|
@@ -4009,7 +3902,7 @@ class _ProcessContainer (object):
|
|
|
4009
3902
|
self.__initialize_snapshot()
|
|
4010
3903
|
return len(self.__processDict)
|
|
4011
3904
|
|
|
4012
|
-
|
|
3905
|
+
# ------------------------------------------------------------------------------
|
|
4013
3906
|
|
|
4014
3907
|
# XXX TODO
|
|
4015
3908
|
# Support for string searches on the window captions.
|
|
@@ -4022,7 +3915,7 @@ class _ProcessContainer (object):
|
|
|
4022
3915
|
"""
|
|
4023
3916
|
window_list = list()
|
|
4024
3917
|
for process in self.iter_processes():
|
|
4025
|
-
window_list.extend(
|
|
3918
|
+
window_list.extend(process.get_windows())
|
|
4026
3919
|
return window_list
|
|
4027
3920
|
|
|
4028
3921
|
def get_pid_from_tid(self, dwThreadId):
|
|
@@ -4038,22 +3931,19 @@ class _ProcessContainer (object):
|
|
|
4038
3931
|
@raise KeyError: The thread does not exist.
|
|
4039
3932
|
"""
|
|
4040
3933
|
try:
|
|
4041
|
-
|
|
4042
3934
|
# No good, because in XP and below it tries to get the PID
|
|
4043
3935
|
# through the toolhelp API, and that's slow. We don't want
|
|
4044
3936
|
# to scan for threads over and over for each call.
|
|
4045
|
-
## dwProcessId = Thread(dwThreadId).get_pid()
|
|
3937
|
+
## dwProcessId = Thread(dwThreadId).get_pid()
|
|
4046
3938
|
|
|
4047
3939
|
# This API only exists in Windows 2003, Vista and above.
|
|
4048
3940
|
try:
|
|
4049
|
-
hThread = win32.OpenThread(
|
|
4050
|
-
win32.THREAD_QUERY_LIMITED_INFORMATION, False, dwThreadId)
|
|
3941
|
+
hThread = win32.OpenThread(win32.THREAD_QUERY_LIMITED_INFORMATION, False, dwThreadId)
|
|
4051
3942
|
except WindowsError:
|
|
4052
3943
|
e = sys.exc_info()[1]
|
|
4053
3944
|
if e.winerror != win32.ERROR_ACCESS_DENIED:
|
|
4054
3945
|
raise
|
|
4055
|
-
hThread = win32.OpenThread(
|
|
4056
|
-
win32.THREAD_QUERY_INFORMATION, False, dwThreadId)
|
|
3946
|
+
hThread = win32.OpenThread(win32.THREAD_QUERY_INFORMATION, False, dwThreadId)
|
|
4057
3947
|
try:
|
|
4058
3948
|
return win32.GetProcessIdOfThread(hThread)
|
|
4059
3949
|
finally:
|
|
@@ -4081,7 +3971,7 @@ class _ProcessContainer (object):
|
|
|
4081
3971
|
msg = "Unknown thread ID %d" % dwThreadId
|
|
4082
3972
|
raise KeyError(msg)
|
|
4083
3973
|
|
|
4084
|
-
|
|
3974
|
+
# ------------------------------------------------------------------------------
|
|
4085
3975
|
|
|
4086
3976
|
@staticmethod
|
|
4087
3977
|
def argv_to_cmdline(argv):
|
|
@@ -4102,13 +3992,10 @@ class _ProcessContainer (object):
|
|
|
4102
3992
|
else:
|
|
4103
3993
|
if '"' in token:
|
|
4104
3994
|
token = token.replace('"', '\\"')
|
|
4105
|
-
if
|
|
4106
|
-
'
|
|
4107
|
-
'\n' in token or \
|
|
4108
|
-
'\r' in token:
|
|
4109
|
-
token = '"%s"' % token
|
|
3995
|
+
if " " in token or "\t" in token or "\n" in token or "\r" in token:
|
|
3996
|
+
token = '"%s"' % token
|
|
4110
3997
|
cmdline.append(token)
|
|
4111
|
-
return
|
|
3998
|
+
return " ".join(cmdline)
|
|
4112
3999
|
|
|
4113
4000
|
@staticmethod
|
|
4114
4001
|
def cmdline_to_argv(lpCmdLine):
|
|
@@ -4196,14 +4083,14 @@ class _ProcessContainer (object):
|
|
|
4196
4083
|
"""
|
|
4197
4084
|
|
|
4198
4085
|
# Get the flags.
|
|
4199
|
-
bConsole
|
|
4200
|
-
bDebug
|
|
4201
|
-
bFollow
|
|
4202
|
-
bSuspended
|
|
4203
|
-
bInheritHandles
|
|
4204
|
-
dwParentProcessId
|
|
4205
|
-
iTrustLevel
|
|
4206
|
-
bAllowElevation
|
|
4086
|
+
bConsole = kwargs.pop("bConsole", False)
|
|
4087
|
+
bDebug = kwargs.pop("bDebug", False)
|
|
4088
|
+
bFollow = kwargs.pop("bFollow", False)
|
|
4089
|
+
bSuspended = kwargs.pop("bSuspended", False)
|
|
4090
|
+
bInheritHandles = kwargs.pop("bInheritHandles", False)
|
|
4091
|
+
dwParentProcessId = kwargs.pop("dwParentProcessId", None)
|
|
4092
|
+
iTrustLevel = kwargs.pop("iTrustLevel", 2)
|
|
4093
|
+
bAllowElevation = kwargs.pop("bAllowElevation", True)
|
|
4207
4094
|
if kwargs:
|
|
4208
4095
|
raise TypeError("Unknown keyword arguments: %s" % compat.keys(kwargs))
|
|
4209
4096
|
if not lpCmdLine:
|
|
@@ -4218,18 +4105,16 @@ class _ProcessContainer (object):
|
|
|
4218
4105
|
bAllowElevation = bAllowElevation or not self.is_admin()
|
|
4219
4106
|
except AttributeError:
|
|
4220
4107
|
bAllowElevation = True
|
|
4221
|
-
warnings.warn(
|
|
4222
|
-
"UAC elevation is only available in Windows Vista and above",
|
|
4223
|
-
RuntimeWarning)
|
|
4108
|
+
warnings.warn("UAC elevation is only available in Windows Vista and above", RuntimeWarning)
|
|
4224
4109
|
|
|
4225
4110
|
# Calculate the process creation flags.
|
|
4226
|
-
dwCreationFlags
|
|
4111
|
+
dwCreationFlags = 0
|
|
4227
4112
|
dwCreationFlags |= win32.CREATE_DEFAULT_ERROR_MODE
|
|
4228
4113
|
dwCreationFlags |= win32.CREATE_BREAKAWAY_FROM_JOB
|
|
4229
4114
|
##dwCreationFlags |= win32.CREATE_UNICODE_ENVIRONMENT
|
|
4230
4115
|
if not bConsole:
|
|
4231
4116
|
dwCreationFlags |= win32.DETACHED_PROCESS
|
|
4232
|
-
#dwCreationFlags |= win32.CREATE_NO_WINDOW # weird stuff happens
|
|
4117
|
+
# dwCreationFlags |= win32.CREATE_NO_WINDOW # weird stuff happens
|
|
4233
4118
|
if bSuspended:
|
|
4234
4119
|
dwCreationFlags |= win32.CREATE_SUSPENDED
|
|
4235
4120
|
if bDebug:
|
|
@@ -4247,22 +4132,16 @@ class _ProcessContainer (object):
|
|
|
4247
4132
|
ParentProcess = self.get_process(dwParentProcessId)
|
|
4248
4133
|
else:
|
|
4249
4134
|
ParentProcess = Process(dwParentProcessId)
|
|
4250
|
-
ParentProcessHandle = ParentProcess.get_handle(
|
|
4251
|
-
|
|
4252
|
-
AttributeListData = (
|
|
4253
|
-
(
|
|
4254
|
-
win32.PROC_THREAD_ATTRIBUTE_PARENT_PROCESS,
|
|
4255
|
-
ParentProcessHandle._as_parameter_
|
|
4256
|
-
),
|
|
4257
|
-
)
|
|
4135
|
+
ParentProcessHandle = ParentProcess.get_handle(win32.PROCESS_CREATE_PROCESS)
|
|
4136
|
+
AttributeListData = ((win32.PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, ParentProcessHandle._as_parameter_),)
|
|
4258
4137
|
AttributeList = win32.ProcThreadAttributeList(AttributeListData)
|
|
4259
|
-
StartupInfoEx
|
|
4260
|
-
StartupInfo
|
|
4261
|
-
StartupInfo.cb
|
|
4262
|
-
StartupInfo.lpReserved
|
|
4263
|
-
StartupInfo.lpDesktop
|
|
4264
|
-
StartupInfo.lpTitle
|
|
4265
|
-
StartupInfo.dwFlags
|
|
4138
|
+
StartupInfoEx = win32.STARTUPINFOEX()
|
|
4139
|
+
StartupInfo = StartupInfoEx.StartupInfo
|
|
4140
|
+
StartupInfo.cb = win32.sizeof(win32.STARTUPINFOEX)
|
|
4141
|
+
StartupInfo.lpReserved = 0
|
|
4142
|
+
StartupInfo.lpDesktop = 0
|
|
4143
|
+
StartupInfo.lpTitle = 0
|
|
4144
|
+
StartupInfo.dwFlags = 0
|
|
4266
4145
|
StartupInfo.cbReserved2 = 0
|
|
4267
4146
|
StartupInfo.lpReserved2 = 0
|
|
4268
4147
|
StartupInfoEx.lpAttributeList = AttributeList.value
|
|
@@ -4271,36 +4150,27 @@ class _ProcessContainer (object):
|
|
|
4271
4150
|
|
|
4272
4151
|
pi = None
|
|
4273
4152
|
try:
|
|
4274
|
-
|
|
4275
4153
|
# Create the process the easy way.
|
|
4276
4154
|
if iTrustLevel >= 2 and bAllowElevation:
|
|
4277
|
-
pi = win32.CreateProcess(
|
|
4278
|
-
|
|
4279
|
-
|
|
4280
|
-
lpStartupInfo = lpStartupInfo)
|
|
4155
|
+
pi = win32.CreateProcess(
|
|
4156
|
+
None, lpCmdLine, bInheritHandles=bInheritHandles, dwCreationFlags=dwCreationFlags, lpStartupInfo=lpStartupInfo
|
|
4157
|
+
)
|
|
4281
4158
|
|
|
4282
4159
|
# Create the process the hard way...
|
|
4283
4160
|
else:
|
|
4284
|
-
|
|
4285
4161
|
# If we allow elevation, use the current process token.
|
|
4286
4162
|
# If not, get the token from the current shell process.
|
|
4287
4163
|
hToken = None
|
|
4288
4164
|
try:
|
|
4289
4165
|
if not bAllowElevation:
|
|
4290
4166
|
if bFollow:
|
|
4291
|
-
msg =
|
|
4292
|
-
"Child processes can't be autofollowed"
|
|
4293
|
-
" when dropping UAC elevation.")
|
|
4167
|
+
msg = "Child processes can't be autofollowed" " when dropping UAC elevation."
|
|
4294
4168
|
raise NotImplementedError(msg)
|
|
4295
4169
|
if bConsole:
|
|
4296
|
-
msg =
|
|
4297
|
-
"Child processes can't inherit the debugger's"
|
|
4298
|
-
" console when dropping UAC elevation.")
|
|
4170
|
+
msg = "Child processes can't inherit the debugger's" " console when dropping UAC elevation."
|
|
4299
4171
|
raise NotImplementedError(msg)
|
|
4300
4172
|
if bInheritHandles:
|
|
4301
|
-
msg =
|
|
4302
|
-
"Child processes can't inherit the debugger's"
|
|
4303
|
-
" handles when dropping UAC elevation.")
|
|
4173
|
+
msg = "Child processes can't inherit the debugger's" " handles when dropping UAC elevation."
|
|
4304
4174
|
raise NotImplementedError(msg)
|
|
4305
4175
|
try:
|
|
4306
4176
|
hWnd = self.get_shell_window()
|
|
@@ -4308,8 +4178,7 @@ class _ProcessContainer (object):
|
|
|
4308
4178
|
hWnd = self.get_desktop_window()
|
|
4309
4179
|
shell = hWnd.get_process()
|
|
4310
4180
|
try:
|
|
4311
|
-
hShell = shell.get_handle(
|
|
4312
|
-
win32.PROCESS_QUERY_INFORMATION)
|
|
4181
|
+
hShell = shell.get_handle(win32.PROCESS_QUERY_INFORMATION)
|
|
4313
4182
|
with win32.OpenProcessToken(hShell) as hShellToken:
|
|
4314
4183
|
hToken = win32.DuplicateTokenEx(hShellToken)
|
|
4315
4184
|
finally:
|
|
@@ -4321,9 +4190,8 @@ class _ProcessContainer (object):
|
|
|
4321
4190
|
dwLevelId = win32.SAFER_LEVELID_NORMALUSER
|
|
4322
4191
|
else:
|
|
4323
4192
|
dwLevelId = win32.SAFER_LEVELID_UNTRUSTED
|
|
4324
|
-
with win32.SaferCreateLevel(dwLevelId
|
|
4325
|
-
hSaferToken = win32.SaferComputeTokenFromLevel(
|
|
4326
|
-
hSafer, hToken)[0]
|
|
4193
|
+
with win32.SaferCreateLevel(dwLevelId=dwLevelId) as hSafer:
|
|
4194
|
+
hSaferToken = win32.SaferComputeTokenFromLevel(hSafer, hToken)[0]
|
|
4327
4195
|
try:
|
|
4328
4196
|
if hToken is not None:
|
|
4329
4197
|
hToken.close()
|
|
@@ -4335,11 +4203,12 @@ class _ProcessContainer (object):
|
|
|
4335
4203
|
# If we have a computed token, call CreateProcessAsUser().
|
|
4336
4204
|
if bAllowElevation:
|
|
4337
4205
|
pi = win32.CreateProcessAsUser(
|
|
4338
|
-
|
|
4339
|
-
|
|
4340
|
-
|
|
4341
|
-
|
|
4342
|
-
|
|
4206
|
+
hToken=hToken,
|
|
4207
|
+
lpCommandLine=lpCmdLine,
|
|
4208
|
+
bInheritHandles=bInheritHandles,
|
|
4209
|
+
dwCreationFlags=dwCreationFlags,
|
|
4210
|
+
lpStartupInfo=lpStartupInfo,
|
|
4211
|
+
)
|
|
4343
4212
|
|
|
4344
4213
|
# If we have a primary token call CreateProcessWithToken().
|
|
4345
4214
|
# The problem is, there are many flags CreateProcess() and
|
|
@@ -4347,7 +4216,6 @@ class _ProcessContainer (object):
|
|
|
4347
4216
|
# and CreateProcessWithLogonW() don't, so we need to work
|
|
4348
4217
|
# around them.
|
|
4349
4218
|
else:
|
|
4350
|
-
|
|
4351
4219
|
# Remove the debug flags.
|
|
4352
4220
|
dwCreationFlags &= ~win32.DEBUG_PROCESS
|
|
4353
4221
|
dwCreationFlags &= ~win32.DEBUG_ONLY_THIS_PROCESS
|
|
@@ -4360,11 +4228,12 @@ class _ProcessContainer (object):
|
|
|
4360
4228
|
|
|
4361
4229
|
# Create the process using the new primary token.
|
|
4362
4230
|
pi = win32.CreateProcessWithToken(
|
|
4363
|
-
|
|
4364
|
-
|
|
4365
|
-
|
|
4366
|
-
|
|
4367
|
-
|
|
4231
|
+
hToken=hToken,
|
|
4232
|
+
dwLogonFlags=win32.LOGON_WITH_PROFILE,
|
|
4233
|
+
lpCommandLine=lpCmdLine,
|
|
4234
|
+
dwCreationFlags=dwCreationFlags,
|
|
4235
|
+
lpStartupInfo=lpStartupInfo,
|
|
4236
|
+
)
|
|
4368
4237
|
|
|
4369
4238
|
# Attach as a debugger, if requested.
|
|
4370
4239
|
if bDebug:
|
|
@@ -4382,7 +4251,7 @@ class _ProcessContainer (object):
|
|
|
4382
4251
|
# Wrap the new process and thread in Process and Thread objects,
|
|
4383
4252
|
# and add them to the corresponding snapshots.
|
|
4384
4253
|
aProcess = Process(pi.dwProcessId, pi.hProcess)
|
|
4385
|
-
aThread
|
|
4254
|
+
aThread = Thread(pi.dwThreadId, pi.hThread)
|
|
4386
4255
|
aProcess._add_thread(aThread)
|
|
4387
4256
|
self._add_process(aProcess)
|
|
4388
4257
|
|
|
@@ -4412,15 +4281,15 @@ class _ProcessContainer (object):
|
|
|
4412
4281
|
except Exception:
|
|
4413
4282
|
exp = None
|
|
4414
4283
|
if not exp:
|
|
4415
|
-
exp = os.getenv(
|
|
4284
|
+
exp = os.getenv("SystemRoot")
|
|
4416
4285
|
if exp:
|
|
4417
|
-
exp = os.path.join(exp,
|
|
4286
|
+
exp = os.path.join(exp, "explorer.exe")
|
|
4418
4287
|
exp_list = self.find_processes_by_filename(exp)
|
|
4419
4288
|
if exp_list:
|
|
4420
4289
|
return exp_list[0][0].get_pid()
|
|
4421
4290
|
return None
|
|
4422
4291
|
|
|
4423
|
-
|
|
4292
|
+
# ------------------------------------------------------------------------------
|
|
4424
4293
|
|
|
4425
4294
|
# XXX this methods musn't end up calling __initialize_snapshot by accident!
|
|
4426
4295
|
|
|
@@ -4441,13 +4310,11 @@ class _ProcessContainer (object):
|
|
|
4441
4310
|
has_threads = True
|
|
4442
4311
|
try:
|
|
4443
4312
|
try:
|
|
4444
|
-
|
|
4445
4313
|
# Try using the Toolhelp API
|
|
4446
4314
|
# to scan for processes and threads.
|
|
4447
4315
|
self.scan_processes_and_threads()
|
|
4448
4316
|
|
|
4449
4317
|
except Exception:
|
|
4450
|
-
|
|
4451
4318
|
# On error, try using the PSAPI to scan for process IDs only.
|
|
4452
4319
|
self.scan_processes_fast()
|
|
4453
4320
|
|
|
@@ -4460,7 +4327,6 @@ class _ProcessContainer (object):
|
|
|
4460
4327
|
has_threads = False
|
|
4461
4328
|
|
|
4462
4329
|
finally:
|
|
4463
|
-
|
|
4464
4330
|
# Try using the Remote Desktop API to scan for processes only.
|
|
4465
4331
|
# This will update the filenames when it's not possible
|
|
4466
4332
|
# to obtain them from the Toolhelp API.
|
|
@@ -4494,8 +4360,8 @@ class _ProcessContainer (object):
|
|
|
4494
4360
|
# since this information resides in usermode space.
|
|
4495
4361
|
# See: http://www.ragestorm.net/blogs/?p=163
|
|
4496
4362
|
|
|
4497
|
-
our_pid
|
|
4498
|
-
dead_pids
|
|
4363
|
+
our_pid = win32.GetCurrentProcessId()
|
|
4364
|
+
dead_pids = set(compat.iterkeys(self.__processDict))
|
|
4499
4365
|
found_tids = set()
|
|
4500
4366
|
|
|
4501
4367
|
# Ignore our own process if it's in the snapshot for some reason
|
|
@@ -4503,9 +4369,8 @@ class _ProcessContainer (object):
|
|
|
4503
4369
|
dead_pids.remove(our_pid)
|
|
4504
4370
|
|
|
4505
4371
|
# Take a snapshot of all processes and threads
|
|
4506
|
-
dwFlags
|
|
4372
|
+
dwFlags = win32.TH32CS_SNAPPROCESS | win32.TH32CS_SNAPTHREAD
|
|
4507
4373
|
with win32.CreateToolhelp32Snapshot(dwFlags) as hSnapshot:
|
|
4508
|
-
|
|
4509
4374
|
# Add all the processes (excluding our own)
|
|
4510
4375
|
pe = win32.Process32First(hSnapshot)
|
|
4511
4376
|
while pe is not None:
|
|
@@ -4537,7 +4402,7 @@ class _ProcessContainer (object):
|
|
|
4537
4402
|
dwThreadId = te.th32ThreadID
|
|
4538
4403
|
found_tids.add(dwThreadId)
|
|
4539
4404
|
if not aProcess._has_thread_id(dwThreadId):
|
|
4540
|
-
aThread = Thread(dwThreadId, process
|
|
4405
|
+
aThread = Thread(dwThreadId, process=aProcess)
|
|
4541
4406
|
aProcess._add_thread(aThread)
|
|
4542
4407
|
te = win32.Thread32Next(hSnapshot)
|
|
4543
4408
|
|
|
@@ -4547,7 +4412,7 @@ class _ProcessContainer (object):
|
|
|
4547
4412
|
|
|
4548
4413
|
# Remove dead threads
|
|
4549
4414
|
for aProcess in compat.itervalues(self.__processDict):
|
|
4550
|
-
dead_tids = set(
|
|
4415
|
+
dead_tids = set(aProcess._get_thread_ids())
|
|
4551
4416
|
dead_tids.difference_update(found_tids)
|
|
4552
4417
|
for tid in dead_tids:
|
|
4553
4418
|
aProcess._del_thread(tid)
|
|
@@ -4597,8 +4462,8 @@ class _ProcessContainer (object):
|
|
|
4597
4462
|
|
|
4598
4463
|
# Get the previous list of PIDs.
|
|
4599
4464
|
# We'll be removing live PIDs from it as we find them.
|
|
4600
|
-
our_pid
|
|
4601
|
-
dead_pids
|
|
4465
|
+
our_pid = win32.GetCurrentProcessId()
|
|
4466
|
+
dead_pids = set(compat.iterkeys(self.__processDict))
|
|
4602
4467
|
|
|
4603
4468
|
# Ignore our own PID.
|
|
4604
4469
|
if our_pid in dead_pids:
|
|
@@ -4607,16 +4472,15 @@ class _ProcessContainer (object):
|
|
|
4607
4472
|
# Get the list of processes from the Remote Desktop API.
|
|
4608
4473
|
pProcessInfo = None
|
|
4609
4474
|
try:
|
|
4610
|
-
pProcessInfo, dwCount = win32.WTSEnumerateProcesses(
|
|
4611
|
-
win32.WTS_CURRENT_SERVER_HANDLE)
|
|
4475
|
+
pProcessInfo, dwCount = win32.WTSEnumerateProcesses(win32.WTS_CURRENT_SERVER_HANDLE)
|
|
4612
4476
|
|
|
4613
4477
|
# For each process found...
|
|
4614
4478
|
for index in compat.xrange(dwCount):
|
|
4615
4479
|
sProcessInfo = pProcessInfo[index]
|
|
4616
4480
|
|
|
4617
|
-
## # Ignore processes belonging to other sessions.
|
|
4618
|
-
## if sProcessInfo.SessionId != win32.WTS_CURRENT_SESSION:
|
|
4619
|
-
## continue
|
|
4481
|
+
## # Ignore processes belonging to other sessions.
|
|
4482
|
+
## if sProcessInfo.SessionId != win32.WTS_CURRENT_SESSION:
|
|
4483
|
+
## continue
|
|
4620
4484
|
|
|
4621
4485
|
# Ignore our own PID.
|
|
4622
4486
|
pid = sProcessInfo.ProcessId
|
|
@@ -4634,7 +4498,7 @@ class _ProcessContainer (object):
|
|
|
4634
4498
|
|
|
4635
4499
|
# If the process is new, add a new Process object.
|
|
4636
4500
|
if pid not in self.__processDict:
|
|
4637
|
-
aProcess = Process(pid, fileName
|
|
4501
|
+
aProcess = Process(pid, fileName=fileName)
|
|
4638
4502
|
self._add_process(aProcess)
|
|
4639
4503
|
|
|
4640
4504
|
# If the process was already in the snapshot, and the
|
|
@@ -4674,11 +4538,11 @@ class _ProcessContainer (object):
|
|
|
4674
4538
|
"""
|
|
4675
4539
|
|
|
4676
4540
|
# Get the new and old list of pids
|
|
4677
|
-
new_pids = set(
|
|
4678
|
-
old_pids = set(
|
|
4541
|
+
new_pids = set(win32.EnumProcesses())
|
|
4542
|
+
old_pids = set(compat.iterkeys(self.__processDict))
|
|
4679
4543
|
|
|
4680
4544
|
# Ignore our own pid
|
|
4681
|
-
our_pid
|
|
4545
|
+
our_pid = win32.GetCurrentProcessId()
|
|
4682
4546
|
if our_pid in new_pids:
|
|
4683
4547
|
new_pids.remove(our_pid)
|
|
4684
4548
|
if our_pid in old_pids:
|
|
@@ -4686,7 +4550,7 @@ class _ProcessContainer (object):
|
|
|
4686
4550
|
|
|
4687
4551
|
# Add newly found pids
|
|
4688
4552
|
for pid in new_pids.difference(old_pids):
|
|
4689
|
-
self._add_process(
|
|
4553
|
+
self._add_process(Process(pid))
|
|
4690
4554
|
|
|
4691
4555
|
# Remove missing pids
|
|
4692
4556
|
for pid in old_pids.difference(new_pids):
|
|
@@ -4727,7 +4591,7 @@ class _ProcessContainer (object):
|
|
|
4727
4591
|
complete = False
|
|
4728
4592
|
return complete
|
|
4729
4593
|
|
|
4730
|
-
|
|
4594
|
+
# ------------------------------------------------------------------------------
|
|
4731
4595
|
|
|
4732
4596
|
def clear_dead_processes(self):
|
|
4733
4597
|
"""
|
|
@@ -4787,7 +4651,7 @@ class _ProcessContainer (object):
|
|
|
4787
4651
|
"""
|
|
4788
4652
|
Removes all L{Process}, L{Thread} and L{Module} objects in this snapshot.
|
|
4789
4653
|
"""
|
|
4790
|
-
#self.close_process_and_thread_handles()
|
|
4654
|
+
# self.close_process_and_thread_handles()
|
|
4791
4655
|
for aProcess in self.iter_processes():
|
|
4792
4656
|
aProcess.clear()
|
|
4793
4657
|
self.__processDict = dict()
|
|
@@ -4800,7 +4664,7 @@ class _ProcessContainer (object):
|
|
|
4800
4664
|
"""
|
|
4801
4665
|
self.clear_processes()
|
|
4802
4666
|
|
|
4803
|
-
|
|
4667
|
+
# ------------------------------------------------------------------------------
|
|
4804
4668
|
|
|
4805
4669
|
# Docs for these methods are taken from the _ThreadContainer class.
|
|
4806
4670
|
|
|
@@ -4829,12 +4693,12 @@ class _ProcessContainer (object):
|
|
|
4829
4693
|
count += aProcess.get_thread_count()
|
|
4830
4694
|
return count
|
|
4831
4695
|
|
|
4832
|
-
has_thread.__doc__
|
|
4833
|
-
get_thread.__doc__
|
|
4834
|
-
get_thread_ids.__doc__
|
|
4696
|
+
has_thread.__doc__ = _ThreadContainer.has_thread.__doc__
|
|
4697
|
+
get_thread.__doc__ = _ThreadContainer.get_thread.__doc__
|
|
4698
|
+
get_thread_ids.__doc__ = _ThreadContainer.get_thread_ids.__doc__
|
|
4835
4699
|
get_thread_count.__doc__ = _ThreadContainer.get_thread_count.__doc__
|
|
4836
4700
|
|
|
4837
|
-
|
|
4701
|
+
# ------------------------------------------------------------------------------
|
|
4838
4702
|
|
|
4839
4703
|
# Docs for these methods are taken from the _ModuleContainer class.
|
|
4840
4704
|
|
|
@@ -4846,7 +4710,7 @@ class _ProcessContainer (object):
|
|
|
4846
4710
|
|
|
4847
4711
|
get_module_count.__doc__ = _ModuleContainer.get_module_count.__doc__
|
|
4848
4712
|
|
|
4849
|
-
|
|
4713
|
+
# ------------------------------------------------------------------------------
|
|
4850
4714
|
|
|
4851
4715
|
def find_modules_by_base(self, lpBaseOfDll):
|
|
4852
4716
|
"""
|
|
@@ -4857,7 +4721,7 @@ class _ProcessContainer (object):
|
|
|
4857
4721
|
for aProcess in self.iter_processes():
|
|
4858
4722
|
if aProcess.has_module(lpBaseOfDll):
|
|
4859
4723
|
aModule = aProcess.get_module(lpBaseOfDll)
|
|
4860
|
-
found.append(
|
|
4724
|
+
found.append((aProcess, aModule))
|
|
4861
4725
|
return found
|
|
4862
4726
|
|
|
4863
4727
|
def find_modules_by_name(self, fileName):
|
|
@@ -4869,7 +4733,7 @@ class _ProcessContainer (object):
|
|
|
4869
4733
|
for aProcess in self.iter_processes():
|
|
4870
4734
|
aModule = aProcess.get_module_by_name(fileName)
|
|
4871
4735
|
if aModule is not None:
|
|
4872
|
-
found.append(
|
|
4736
|
+
found.append((aProcess, aModule))
|
|
4873
4737
|
return found
|
|
4874
4738
|
|
|
4875
4739
|
def find_modules_by_address(self, address):
|
|
@@ -4881,27 +4745,27 @@ class _ProcessContainer (object):
|
|
|
4881
4745
|
for aProcess in self.iter_processes():
|
|
4882
4746
|
aModule = aProcess.get_module_at_address(address)
|
|
4883
4747
|
if aModule is not None:
|
|
4884
|
-
found.append(
|
|
4748
|
+
found.append((aProcess, aModule))
|
|
4885
4749
|
return found
|
|
4886
4750
|
|
|
4887
4751
|
def __find_processes_by_filename(self, filename):
|
|
4888
4752
|
"""
|
|
4889
4753
|
Internally used by L{find_processes_by_filename}.
|
|
4890
4754
|
"""
|
|
4891
|
-
found
|
|
4755
|
+
found = list()
|
|
4892
4756
|
filename = filename.lower()
|
|
4893
4757
|
if PathOperations.path_is_absolute(filename):
|
|
4894
4758
|
for aProcess in self.iter_processes():
|
|
4895
4759
|
imagename = aProcess.get_filename()
|
|
4896
4760
|
if imagename and imagename.lower() == filename:
|
|
4897
|
-
found.append(
|
|
4761
|
+
found.append((aProcess, imagename))
|
|
4898
4762
|
else:
|
|
4899
4763
|
for aProcess in self.iter_processes():
|
|
4900
4764
|
imagename = aProcess.get_filename()
|
|
4901
4765
|
if imagename:
|
|
4902
4766
|
imagename = PathOperations.pathname_to_filename(imagename)
|
|
4903
4767
|
if imagename.lower() == filename:
|
|
4904
|
-
found.append(
|
|
4768
|
+
found.append((aProcess, imagename))
|
|
4905
4769
|
return found
|
|
4906
4770
|
|
|
4907
4771
|
def find_processes_by_filename(self, fileName):
|
|
@@ -4924,11 +4788,11 @@ class _ProcessContainer (object):
|
|
|
4924
4788
|
if not found:
|
|
4925
4789
|
fn, ext = PathOperations.split_extension(fileName)
|
|
4926
4790
|
if not ext:
|
|
4927
|
-
fileName =
|
|
4928
|
-
found
|
|
4791
|
+
fileName = "%s.exe" % fn
|
|
4792
|
+
found = self.__find_processes_by_filename(fileName)
|
|
4929
4793
|
return found
|
|
4930
4794
|
|
|
4931
|
-
|
|
4795
|
+
# ------------------------------------------------------------------------------
|
|
4932
4796
|
|
|
4933
4797
|
# XXX _notify_* methods should not trigger a scan
|
|
4934
4798
|
|
|
@@ -4939,17 +4803,17 @@ class _ProcessContainer (object):
|
|
|
4939
4803
|
@type aProcess: L{Process}
|
|
4940
4804
|
@param aProcess: Process object.
|
|
4941
4805
|
"""
|
|
4942
|
-
## if not isinstance(aProcess, Process):
|
|
4943
|
-
## if hasattr(aProcess, '__class__'):
|
|
4944
|
-
## typename = aProcess.__class__.__name__
|
|
4945
|
-
## else:
|
|
4946
|
-
## typename = str(type(aProcess))
|
|
4947
|
-
## msg = "Expected Process, got %s instead" % typename
|
|
4948
|
-
## raise TypeError(msg)
|
|
4806
|
+
## if not isinstance(aProcess, Process):
|
|
4807
|
+
## if hasattr(aProcess, '__class__'):
|
|
4808
|
+
## typename = aProcess.__class__.__name__
|
|
4809
|
+
## else:
|
|
4810
|
+
## typename = str(type(aProcess))
|
|
4811
|
+
## msg = "Expected Process, got %s instead" % typename
|
|
4812
|
+
## raise TypeError(msg)
|
|
4949
4813
|
dwProcessId = aProcess.dwProcessId
|
|
4950
|
-
## if dwProcessId in self.__processDict:
|
|
4951
|
-
## msg = "Process already exists: %d" % dwProcessId
|
|
4952
|
-
## raise KeyError(msg)
|
|
4814
|
+
## if dwProcessId in self.__processDict:
|
|
4815
|
+
## msg = "Process already exists: %d" % dwProcessId
|
|
4816
|
+
## raise KeyError(msg)
|
|
4953
4817
|
self.__processDict[dwProcessId] = aProcess
|
|
4954
4818
|
|
|
4955
4819
|
def _del_process(self, dwProcessId):
|
|
@@ -4967,7 +4831,7 @@ class _ProcessContainer (object):
|
|
|
4967
4831
|
msg = "Unknown process ID %d" % dwProcessId
|
|
4968
4832
|
warnings.warn(msg, RuntimeWarning)
|
|
4969
4833
|
if aProcess:
|
|
4970
|
-
aProcess.clear()
|
|
4834
|
+
aProcess.clear() # remove circular references
|
|
4971
4835
|
|
|
4972
4836
|
# Notify the creation of a new process.
|
|
4973
4837
|
def _notify_create_process(self, event):
|
|
@@ -4984,16 +4848,16 @@ class _ProcessContainer (object):
|
|
|
4984
4848
|
@return: C{True} to call the user-defined handle, C{False} otherwise.
|
|
4985
4849
|
"""
|
|
4986
4850
|
dwProcessId = event.get_pid()
|
|
4987
|
-
dwThreadId
|
|
4988
|
-
hProcess
|
|
4989
|
-
## if not self.has_process(dwProcessId): # XXX this would trigger a scan
|
|
4851
|
+
dwThreadId = event.get_tid()
|
|
4852
|
+
hProcess = event.get_process_handle()
|
|
4853
|
+
## if not self.has_process(dwProcessId): # XXX this would trigger a scan
|
|
4990
4854
|
if dwProcessId not in self.__processDict:
|
|
4991
4855
|
aProcess = Process(dwProcessId, hProcess)
|
|
4992
4856
|
self._add_process(aProcess)
|
|
4993
4857
|
aProcess.fileName = event.get_filename()
|
|
4994
4858
|
else:
|
|
4995
4859
|
aProcess = self.get_process(dwProcessId)
|
|
4996
|
-
#if hProcess != win32.INVALID_HANDLE_VALUE:
|
|
4860
|
+
# if hProcess != win32.INVALID_HANDLE_VALUE:
|
|
4997
4861
|
# aProcess.hProcess = hProcess # may have more privileges
|
|
4998
4862
|
if not aProcess.fileName:
|
|
4999
4863
|
fileName = event.get_filename()
|
|
@@ -5015,7 +4879,7 @@ class _ProcessContainer (object):
|
|
|
5015
4879
|
@return: C{True} to call the user-defined handle, C{False} otherwise.
|
|
5016
4880
|
"""
|
|
5017
4881
|
dwProcessId = event.get_pid()
|
|
5018
|
-
## if self.has_process(dwProcessId): # XXX this would trigger a scan
|
|
4882
|
+
## if self.has_process(dwProcessId): # XXX this would trigger a scan
|
|
5019
4883
|
if dwProcessId in self.__processDict:
|
|
5020
4884
|
self._del_process(dwProcessId)
|
|
5021
4885
|
return True
|