ioncodes / idacode

An integration for IDA and VS Code which connects both to easily execute and debug IDAPython scripts.
725 stars 77 forks source link

debugpy may not free port #12

Open ioncodes opened 4 years ago

ioncodes commented 4 years ago

If specific (and currently unknown) conditions are met, debugpy may not be able to kill the spawned Python process (debug server). A possible solution would be to hook the process creation function, make a copy of the process ID and then force kill it once IDA closes. This is a very hacky solution but it seems like debugpy doesn't provide specific API to tear down the debug server.

This issue was created in reference to #11.

ioncodes commented 4 years ago

If anyone has an idea for a cleaner solution, let me know!

i1oveyou commented 4 months ago

If anyone has an idea for a cleaner solution, let me know!

may be this code written by gpt can work idacode_utils -> socket_handler.py

import tornado.websocket
import debugpy
import json
import tempfile
import idaapi
import idacode_utils.dbg as dbg
import idacode_utils.hooks as hooks
import idacode_utils.settings as settings

def create_env():
    return {
        "dbg": dbg,
        "__idacode__": True,
        "__name__": "__main__"
    }

def start_debug_server():
    if settings.LOGGING:
        tmp_path = tempfile.gettempdir()
        debugpy.log_to(tmp_path)
        print("[IDACode] Logging to {} with pattern debugpy.*.log".format(tmp_path))
    debugpy.configure({"python": settings.PYTHON})
    try:
        debugpy.listen((settings.HOST, settings.DEBUG_PORT))
        print("[IDACode] IDACode debug server listening on {address}:{port}".format(address=settings.HOST, port=settings.DEBUG_PORT))
    except Exception as e:
        print(f"[IDACode] Error starting debug server: {e}")

def stop_debug_server():
    try:
        #debugpy.stop()
        print("[IDACode] Debug server stopped")
    except Exception as e:
        print(f"[IDACode] Error stopping debug server: {e}")

class SocketHandler(tornado.websocket.WebSocketHandler):
    def open(self):
        print("[IDACode] Client connected")

    def on_message(self, message):
        message = json.loads(message.decode("utf8"))

        if message["event"] == "set_workspace":
            path = message["path"]
            hooks.set_script_folder(path)
            print("[IDACode] Set workspace folder to {}".format(path))
        elif message["event"] == "attach_debugger":
            stop_debug_server()  # Stop any existing debug server before starting a new one
            start_debug_server()
            self.write_message({
                "event": "debugger_ready"
            })
        elif message["event"] == "execute_script":
            script = message["path"]
            env = create_env()
            print("[IDACode] Executing {}".format(script))
            idaapi.execute_sync(
                lambda: idaapi.IDAPython_ExecScript(script, env),
                idaapi.MFF_WRITE
            )
        else:
            print("[IDACode] Invalid event {}".format(message['event']))

    def on_close(self):
        print("[IDACode] Client disconnected")
        stop_debug_server()  # Ensure the debug server is stopped when the client disconnects