Debug Control

What is Debug Control?

Debug control refers to performing actions that change the state of the running debugger.

Examples include:

  • Loading/unloading a debugee
  • Transitioning from stopped to running or visa-versa
  • Switching thread contexts
  • Single-stepping
  • Running until return

It's helpful to think of changing the debuggers state as two-steps:

  1. Requesting the change in state
  2. Waiting for the expected state

Without explicit waits its easy to end up with race conditions and poor repeatability in scripts.

# Good
client.set_breakpoint(0x00401000, singleshoot=True)
client.go()
client.wait_for_debug_event(EventType.EVENT_BREAKPOINT)
    # Retrieved RIP after debugger reached target state
print(client.get_reg('eip'))

# Bad
client.set_breakpoint(0x00401000, singleshoot=True)
client.go()
    # Retrieved RIP without wait. It's possible to read an unintended value before the breakpoint is hit
print(client.get_reg('eip'))

Example: Debug Control

"""
Example: Debug Control (32/64 bit)
"""
import sys
from x64dbg_automate import X64DbgClient

if len(sys.argv) != 2:
    print("Usage: python sessions.py <x64dbg_path>")
    quit(1)

print('[+] Creating the x64dbg Automate session')
client = X64DbgClient(x64dbg_path=sys.argv[1])
client.start_session()

print('[+] Loading notepad and asking it to open a file')
client.load_executable('C:\\Windows\\System32\\notepad.exe', 'C:\\Users\\desktop.ini')

print('[+] Resuming from system breakpoint')
client.go()

print('[+] Waiting until the debugee is stopped at the entrypoint')
client.wait_until_stopped()

print('[+] Stepping-in 3 times')
client.stepi(3)

print('[+] Resuming from entrypoint + 3 step-ins')
client.go()

print('[+] Pausing the debugee')
client.pause()

print('[+] Resuming the debugee')
client.go()

print('[+] Unloading notepad')
client.unload_executable()

print('[+] Detaching the session')
client.detach_session()
[+] Creating the x64dbg Automate session
[+] Loading notepad and asking it to open a file
[+] Resuming from system breakpoint
[+] Waiting until the debugee is stopped at the entrypoint
[+] Stepping-in 3 times
[+] Resuming from entrypoint + 3 step-ins
[+] Pausing the debugee
[+] Resuming the debugee
[+] Unloading notepad
[+] Detaching the session

API Method Reference

load_executable(target_exe, cmdline='', current_dir='', wait_timeout=10)

Loads a new executable into the debugger. This method will block until the debugee is ready to receive a command.

Parameters:

Name Type Description Default
target_exe str

Path to the executable to load

required
cmdline str

Command line arguments to pass to the executable

''
current_dir str

Current working directory for the executable

''
wait_timeout int

Max time to wait for the debugee to be ready

10

Returns:

Type Description
bool

True if successful, False otherwise

Source code in x64dbg_automate/hla_xauto.py
def load_executable(self, target_exe: str, cmdline: str = "", current_dir: str = "", wait_timeout: int = 10) -> bool:
    """
    Loads a new executable into the debugger. This method will block until the debugee is ready to receive a command.

    Args:
        target_exe: Path to the executable to load
        cmdline: Command line arguments to pass to the executable
        current_dir: Current working directory for the executable
        wait_timeout: Max time to wait for the debugee to be ready

    Returns:
        True if successful, False otherwise
    """
    cmdline = cmdline.replace('"', r'\"')
    current_dir = current_dir.replace('"', r'\"')
    if len(current_dir) == 0:
        current_dir = "."
    if current_dir == "." or current_dir == "":
        target_exe = os.path.abspath(target_exe)
    else:
        target_exe = os.path.abspath(os.path.join(current_dir, target_exe))
    if not self.cmd_sync(f'init {target_exe}, "{cmdline}", "{current_dir}"'):
        return False
    return self.wait_cmd_ready(wait_timeout)

unload_executable(wait_timeout=10)

Unloads the currently loaded executable. This method will block until the debugger is no longer debugging.

Parameters:

Name Type Description Default
wait_timeout int

Max time to wait for the debugger finish unloading

10

Returns:

Type Description
bool

True if successful, False otherwise

Source code in x64dbg_automate/hla_xauto.py
def unload_executable(self, wait_timeout: int = 10) -> bool:
    """
    Unloads the currently loaded executable. This method will block until the debugger is no longer debugging.

    Args:
        wait_timeout: Max time to wait for the debugger finish unloading

    Returns:
        True if successful, False otherwise
    """
    if not self.cmd_sync(f'stop'):
        return False
    return self.wait_until_not_debugging(wait_timeout)

attach(pid, wait_timeout=10)

Attaches the debugger to a running process. This method does NOT block until a breakpoint has been reached.

Parameters:

Name Type Description Default
pid int

Process Identifier (PID) of the running process.

required
wait_timeout int

Maximum time (in seconds) to wait for the debugger to be ready.

10

Returns:

Name Type Description
bool bool

True if the debugger attaches successfully, False otherwise.

Source code in x64dbg_automate/hla_xauto.py
def attach(self, pid: int, wait_timeout: int = 10) -> bool:
    """
    Attaches the debugger to a running process. This method does *NOT* block until a breakpoint has been reached.

    Args:
        pid (int): Process Identifier (PID) of the running process.
        wait_timeout (int): Maximum time (in seconds) to wait for the debugger to be ready.

    Returns:
        bool: True if the debugger attaches successfully, False otherwise.
    """
    if not self.cmd_sync(f"attach 0x{pid:x}"):
        return False
    return self.wait_until_debugging(wait_timeout)

detach(wait_timeout=10)

Detaches the debugger from the currently debugged process. This method will block until we are no longer debugging.

Parameters:

Name Type Description Default
wait_timeout int

Maximum time (in seconds) to wait for the debugger to be ready.

10

Returns:

Name Type Description
bool bool

True if the debugger detaches successfully, False otherwise.

Source code in x64dbg_automate/hla_xauto.py
def detach(self, wait_timeout: int = 10) -> bool:
    """
    Detaches the debugger from the currently debugged process.
    This method will block until we are no longer debugging.

    Args:
        wait_timeout (int): Maximum time (in seconds) to wait for the debugger to be ready.

    Returns:
        bool: True if the debugger detaches successfully, False otherwise.
    """
    if not self.cmd_sync("detach"):
        return False
    return self.wait_until_not_debugging(wait_timeout)

go(pass_exceptions=False, swallow_exceptions=False)

Resumes the debugee. This method will block until the debugee is in the running state.

Parameters:

Name Type Description Default
pass_exceptions bool

Pass exceptions to the debugee

False
swallow_exceptions bool

Swallow exceptions

False

Returns:

Type Description
bool

True if successful, False otherwise

Source code in x64dbg_automate/hla_xauto.py
def go(self, pass_exceptions: bool = False, swallow_exceptions: bool = False) -> bool:
    """
    Resumes the debugee. This method will block until the debugee is in the running state.

    Args:
        pass_exceptions: Pass exceptions to the debugee
        swallow_exceptions: Swallow exceptions

    Returns:
        True if successful, False otherwise
    """
    if pass_exceptions == True and swallow_exceptions == True:
        raise ValueError("Cannot pass and swallow exceptions at the same time")
    if pass_exceptions:
        prefix = 'e'
    elif swallow_exceptions:
        prefix = 'se'
    else:
        prefix = ''
    ip_start = self.get_reg('cip')
    if not self.cmd_sync(f"{prefix}go"):
        return False
    if self.get_reg('cip') == ip_start:
        self.wait_until_running(timeout=1)
    return True

pause()

Pauses the debugee. This method will block until the debugee is in the stopped state.

Returns:

Type Description
bool

True if successful, False otherwise

Source code in x64dbg_automate/hla_xauto.py
def pause(self) -> bool:
    """
    Pauses the debugee. This method will block until the debugee is in the stopped state.

    Returns:
        True if successful, False otherwise
    """
    if not self.cmd_sync(f"pause"):
        return False
    return self.wait_until_stopped()

stepi(step_count=1, pass_exceptions=False, swallow_exceptions=False, wait_for_ready=True, wait_timeout=2)

Steps into N instructions.

Parameters:

Name Type Description Default
step_count int

Number of instructions to step through

1
pass_exceptions bool

Pass exceptions to the debugee during step

False
swallow_exceptions bool

Swallow exceptions during step

False
wait_for_ready bool

Block until debugger is stopped

True
wait_timeout int

Maximum time in seconds to wait for debugger to stop

2

Returns: bool: True if stepping operation was successful, False otherwise. Raises: ValueError: If both pass_exceptions and swallow_exceptions are True.

Source code in x64dbg_automate/hla_xauto.py
def stepi(self, step_count: int = 1, pass_exceptions: bool = False, swallow_exceptions: bool = False, wait_for_ready: bool = True, wait_timeout: int = 2) -> bool:
    """
    Steps into N instructions.

    Args:
        step_count: Number of instructions to step through
        pass_exceptions: Pass exceptions to the debugee during step
        swallow_exceptions: Swallow exceptions during step
        wait_for_ready: Block until debugger is stopped
        wait_timeout: Maximum time in seconds to wait for debugger to stop
    Returns:
        bool: True if stepping operation was successful, False otherwise.
    Raises:
        ValueError: If both pass_exceptions and swallow_exceptions are True.
    """
    if pass_exceptions == True and swallow_exceptions == True:
        raise ValueError("Cannot pass and swallow exceptions at the same time")
    if pass_exceptions:
        prefix = 'e'
    elif swallow_exceptions:
        prefix = 'se'
    else:
        prefix = ''
    res = self.cmd_sync(f"{prefix}sti 0x{step_count:x}")
    if res and wait_for_ready:
        self.wait_until_stopped(wait_timeout)
    return res

stepo(step_count=1, pass_exceptions=False, swallow_exceptions=False, wait_for_ready=True, wait_timeout=2)

Steps over N instructions.

Parameters:

Name Type Description Default
step_count int

Number of instructions to step through

1
pass_exceptions bool

Pass exceptions to the debugee during step

False
swallow_exceptions bool

Swallow exceptions during step

False
wait_for_ready bool

Block until debugger is stopped

True
wait_timeout int

Maximum time in seconds to wait for debugger to stop

2

Returns: bool: True if stepping operation was successful, False otherwise. Raises: ValueError: If both pass_exceptions and swallow_exceptions are True.

Source code in x64dbg_automate/hla_xauto.py
def stepo(self, step_count: int = 1, pass_exceptions: bool = False, swallow_exceptions: bool = False, wait_for_ready: bool = True, wait_timeout: int = 2) -> bool:
    """
    Steps over N instructions.

    Args:
        step_count: Number of instructions to step through
        pass_exceptions: Pass exceptions to the debugee during step
        swallow_exceptions: Swallow exceptions during step
        wait_for_ready: Block until debugger is stopped
        wait_timeout: Maximum time in seconds to wait for debugger to stop
    Returns:
        bool: True if stepping operation was successful, False otherwise.
    Raises:
        ValueError: If both pass_exceptions and swallow_exceptions are True.
    """
    if pass_exceptions == True and swallow_exceptions == True:
        raise ValueError("Cannot pass and swallow exceptions at the same time")
    if pass_exceptions:
        prefix = 'e'
    elif swallow_exceptions:
        prefix = 'se'
    else:
        prefix = ''
    res = self.cmd_sync(f"{prefix}sto 0x{step_count:x}")
    if res and wait_for_ready:
        self.wait_until_stopped(wait_timeout)
    return res

skip(skip_count=1, wait_for_ready=True, wait_timeout=2)

Skips over N instructions.

Parameters:

Name Type Description Default
skip_count int

Number of instructions to skip

1
wait_for_ready bool

Block until debugger is stopped

True
wait_timeout int

Maximum time in seconds to wait for debugger to stop

2

Returns: bool: True if stepping operation was successful, False otherwise.

Source code in x64dbg_automate/hla_xauto.py
def skip(self, skip_count: int = 1, wait_for_ready: bool = True, wait_timeout: int = 2) -> bool:
    """
    Skips over N instructions.

    Args:
        skip_count: Number of instructions to skip
        wait_for_ready: Block until debugger is stopped
        wait_timeout: Maximum time in seconds to wait for debugger to stop
    Returns:
        bool: True if stepping operation was successful, False otherwise.
    """
    res = self.cmd_sync(f"skip {skip_count}")
    if res and wait_for_ready:
        self.wait_until_stopped(wait_timeout)
    return res

ret(frames=1, wait_timeout=10)

Steps until a ret instruction is encountered.

Parameters:

Name Type Description Default
frames int

Number of ret instructions to seek

1
wait_timeout int

Maximum time in seconds to wait for debugger to stop

10

Returns: bool: True if stepping operation was successful, False otherwise.

Source code in x64dbg_automate/hla_xauto.py
def ret(self, frames: int = 1, wait_timeout: int = 10) -> bool:
    """
    Steps until a ret instruction is encountered.

    Args:
        frames: Number of ret instructions to seek
        wait_timeout: Maximum time in seconds to wait for debugger to stop
    Returns:
        bool: True if stepping operation was successful, False otherwise.
    """
    if not self.cmd_sync(f"rtr {frames}"):
        return False
    return self.wait_cmd_ready(wait_timeout)

thread_create(addr, arg=0)

Create a new thread in the debugee.

Parameters:

Name Type Description Default
addr int

Address of the thread entry point

required
arg int

Argument to pass to the thread

0
Source code in x64dbg_automate/hla_xauto.py
def thread_create(self, addr: int, arg: int = 0) -> int | None:
    """
    Create a new thread in the debugee.

    Args:
        addr: Address of the thread entry point
        arg: Argument to pass to the thread
    """
    success = self.cmd_sync(f'createthread 0x{addr:x}, 0x{arg:x}')
    if not success:
        return None
    tid, success = self.eval_sync('$result')
    if not success:
        return None
    return tid

thread_terminate(tid)

Kills a thread in the debugee.

Parameters:

Name Type Description Default
tid int

Thread ID to kill

required
Source code in x64dbg_automate/hla_xauto.py
def thread_terminate(self, tid: int):
    """
    Kills a thread in the debugee.

    Args:
        tid: Thread ID to kill
    """
    return self.cmd_sync(f'killthread 0x{tid:x}')

thread_pause(tid)

Pauses a thread in the debugee.

Parameters:

Name Type Description Default
tid int

Thread ID to kill

required
Source code in x64dbg_automate/hla_xauto.py
def thread_pause(self, tid: int):
    """
    Pauses a thread in the debugee.

    Args:
        tid: Thread ID to kill
    """
    return self.cmd_sync(f'suspendthread 0x{tid:x}')

thread_resume(tid)

Resumes a thread in the debugee.

Parameters:

Name Type Description Default
tid int

Thread ID to kill

required
Source code in x64dbg_automate/hla_xauto.py
def thread_resume(self, tid: int):
    """
    Resumes a thread in the debugee.

    Args:
        tid: Thread ID to kill
    """
    return self.cmd_sync(f'resumethread 0x{tid:x}')

switch_thread(tid)

Switches the currently observed debugger thread.

Parameters:

Name Type Description Default
tid int

Thread ID to kill

required
Source code in x64dbg_automate/hla_xauto.py
def switch_thread(self, tid: int):
    """
    Switches the currently observed debugger thread.

    Args:
        tid: Thread ID to kill
    """
    return self.cmd_sync(f'switchthread 0x{tid:x}')

wait_for_debug_event(event_type, timeout=5)

Wait for a debug event of a specific type to occur. This method returns the latest event of the specified type, which may have occurred before the method was called.

Returned events are removed from the queue. If the event has not occurred within the timeout, None is returned.

clear_debug_events can be used to ensure an empty debug event queue before calling this method.

Parameters:

Name Type Description Default
event_type EventType

The type of event to wait for

required
timeout int

The maximum time to wait for the event in seconds

5

Returns:

Type Description
DbgEvent | None

DbgEvent | None: The latest event of the specified type, or None if the event did not occur within the timeout.

Source code in x64dbg_automate/events.py
def wait_for_debug_event(self, event_type: EventType, timeout: int = 5) -> DbgEvent | None:
    """
    Wait for a debug event of a specific type to occur. This method returns the latest event of the specified type, which may have occurred before the method was called.

    Returned events are removed from the queue. If the event has not occurred within the timeout, None is returned.

    `clear_debug_events` can be used to ensure an empty debug event queue before calling this method.

    Args:
        event_type: The type of event to wait for
        timeout: The maximum time to wait for the event in seconds

    Returns:
        DbgEvent | None: The latest event of the specified type, or None if the event did not occur within the timeout.
    """
    while timeout > 0:
        for ix, event in enumerate(self._debug_events_q):
            if event.event_type == event_type:
                return self._debug_events_q.pop(ix)
        time.sleep(0.25)
        timeout -= 0.25
    return None

clear_debug_events(event_type=None)

Clear the debug event queue. If event_type is specified, only events of that type will be removed.

Parameters:

Name Type Description Default
event_type EventType | None

The type of event to clear. If None, all events will be cleared.

None
Source code in x64dbg_automate/events.py
def clear_debug_events(self, event_type: EventType | None = None) -> None:
    """
    Clear the debug event queue. If `event_type` is specified, only events of that type will be removed.

    Args:
        event_type: The type of event to clear. If None, all events will be cleared.
    """
    filtered = []
    for _ in range(len(self._debug_events_q)):
        event = self._debug_events_q.pop(0)
        if event.event_type != event_type and event_type is not None:
            filtered.append(event)
    self._debug_events_q = filtered

watch_debug_event(event_type, callback)

Register a callback to be invoked when a debug event of a specific type occurs.

Parameters:

Name Type Description Default
event_type EventType

The type of event to watch

required
callback callable

The callback to invoke when the event occurs. The callback should accept a single argument of type DbgEvent.

required
Source code in x64dbg_automate/events.py
def watch_debug_event(self, event_type: EventType, callback: callable):
    """
    Register a callback to be invoked when a debug event of a specific type occurs.

    Args:
        event_type: The type of event to watch
        callback: The callback to invoke when the event occurs. The callback should accept a single argument of type `DbgEvent`.
    """
    self.listeners[event_type] = self.listeners.get(event_type, []) + [callback]

unwatch_debug_event(event_type, callback)

Remove a callback registered with watch_debug_event

Parameters:

Name Type Description Default
event_type EventType

The type of event to unwatch

required
callback callable

The callback instance to remove

required
Source code in x64dbg_automate/events.py
def unwatch_debug_event(self, event_type: EventType, callback: callable):
    """
    Remove a callback registered with `watch_debug_event`

    Args:
        event_type: The type of event to unwatch
        callback: The callback instance to remove
    """
    self.listeners[event_type] = [x for x in self.listeners.get(event_type, []) if x != callback]

get_latest_debug_event()

Get the latest debug event that occurred in the debugee. The event is removed from the queue.

Source code in x64dbg_automate/events.py
def get_latest_debug_event(self) -> DbgEvent | None:
    """
    Get the latest debug event that occurred in the debugee. The event is removed from the queue.
    """
    if len(self._debug_events_q) == 0:
        return None
    return self._debug_events_q.pop()

peek_latest_debug_event()

Get the latest debug event that occurred in the debugee. The event is not removed from the queue.

Source code in x64dbg_automate/events.py
def peek_latest_debug_event(self) -> DbgEvent | None:
    """
    Get the latest debug event that occurred in the debugee. The event is not removed from the queue.
    """
    if len(self._debug_events_q) == 0:
        return None
    return self._debug_events_q[-1]

wait_until_debugging(timeout=10)

Blocks until the debugger enters a debugging state

Parameters:

Name Type Description Default
timeout int

The maximum time to wait in seconds

10

Returns:

Type Description
bool

True if the debugger is debugging, False otherwise

Source code in x64dbg_automate/commands_xauto.py
def wait_until_debugging(self, timeout: int = 10) -> bool:
    """
    Blocks until the debugger enters a debugging state

    Args:
        timeout: The maximum time to wait in seconds

    Returns:
        True if the debugger is debugging, False otherwise
    """
    slept = 0
    while True:
        if self.is_debugging():
            return True
        time.sleep(0.2)
        slept += 0.2
        if slept >= timeout:
            return False

wait_until_not_debugging(timeout=10)

Blocks until the debugger enters a not-debugging state

Parameters:

Name Type Description Default
timeout int

The maximum time to wait in seconds

10

Returns:

Type Description
bool

True if the debugger is not-debugging, False otherwise

Source code in x64dbg_automate/commands_xauto.py
def wait_until_not_debugging(self, timeout: int = 10) -> bool:
    """
    Blocks until the debugger enters a not-debugging state

    Args:
        timeout: The maximum time to wait in seconds

    Returns:
        True if the debugger is not-debugging, False otherwise
    """
    slept = 0
    while True:
        if not self.is_debugging():
            return True
        time.sleep(0.2)
        slept += 0.2
        if slept >= timeout:
            return False

wait_until_running(timeout=10)

Blocks until the debugger enters a running state

Parameters:

Name Type Description Default
timeout int

The maximum time to wait in seconds

10

Returns:

Type Description
bool

True if the debugger is running, False otherwise

Source code in x64dbg_automate/commands_xauto.py
def wait_until_running(self, timeout: int = 10) -> bool:
    """
    Blocks until the debugger enters a running state

    Args:
        timeout: The maximum time to wait in seconds

    Returns:
        True if the debugger is running, False otherwise
    """
    slept = 0
    while True:
        if self.is_running():
            return True
        time.sleep(0.08)
        slept += 0.08
        if slept >= timeout:
            return False

wait_until_stopped(timeout=10)

Blocks until the debugger enters a stopped state

Parameters:

Name Type Description Default
timeout int

The maximum time to wait in seconds

10

Returns:

Type Description
bool

True if the debugger is stopped, False otherwise

Source code in x64dbg_automate/commands_xauto.py
def wait_until_stopped(self, timeout: int = 10) -> bool:
    """
    Blocks until the debugger enters a stopped state

    Args:
        timeout: The maximum time to wait in seconds

    Returns:
        True if the debugger is stopped, False otherwise
    """
    slept = 0
    while True:
        if not self.is_running() or not self.is_debugging():
            return True
        time.sleep(0.2)
        slept += 0.2
        if slept >= timeout:
            return False

wait_cmd_ready(timeout=10)

Blocks until the debugger is ready to accept debug control commands (debugging + stopped)

Parameters:

Name Type Description Default
timeout int

The maximum time to wait in seconds

10

Returns:

Type Description
bool

True if the debugger is ready, False otherwise

Source code in x64dbg_automate/commands_xauto.py
def wait_cmd_ready(self, timeout: int = 10) -> bool:
    """
    Blocks until the debugger is ready to accept debug control commands (debugging + stopped)

    Args:
        timeout: The maximum time to wait in seconds

    Returns:
        True if the debugger is ready, False otherwise
    """
    return self.wait_until_debugging(timeout) and self.wait_until_stopped(timeout)

hide_debugger_peb()

Hides the debugger in the debugee's PEB

Returns:

Type Description
bool

Success

Source code in x64dbg_automate/hla_xauto.py
def hide_debugger_peb(self) -> bool:
    """
    Hides the debugger in the debugee's PEB

    Returns:
        Success
    """
    return self.cmd_sync(f'hide')

debugee_pid()

Retrieves the PID of the debugee

Returns:

Type Description
int | None

PID of the debugee, or None if the debugger is not debugging

Source code in x64dbg_automate/hla_xauto.py
def debugee_pid(self) -> int | None:
    """
    Retrieves the PID of the debugee

    Returns:
        PID of the debugee, or None if the debugger is not debugging
    """
    if self.is_debugging():
        pid, res = self.eval_sync(f'pid')
        if res:
            return pid
    return None

get_debugger_pid()

Retrieves the PID of the x64dbg process

Returns:

Type Description
int

The PID of the x64dbg process

Source code in x64dbg_automate/commands_xauto.py
def get_debugger_pid(self) -> int:
    """
    Retrieves the PID of the x64dbg process

    Returns:
        The PID of the x64dbg process
    """
    return self._send_request(XAutoCommand.XAUTO_REQ_DEBUGGER_PID)

is_running()

Checks if the debugee's state is "running"

Returns:

Type Description
bool

True if the debugee is running, False otherwise

Source code in x64dbg_automate/commands_xauto.py
def is_running(self) -> bool:
    """
    Checks if the debugee's state is "running"

    Returns:
        True if the debugee is running, False otherwise
    """
    return self._send_request(XAutoCommand.XAUTO_REQ_DBG_IS_RUNNING)

is_debugging()

Checks if the debugee's state is "debugging"

Returns:

Type Description
bool

True if the debugee is running, False otherwise

Source code in x64dbg_automate/commands_xauto.py
def is_debugging(self) -> bool:
    """
    Checks if the debugee's state is "debugging"

    Returns:
        True if the debugee is running, False otherwise
    """
    return self._send_request(XAutoCommand.XAUTO_REQ_DBG_IS_DEBUGGING)

API Model Reference

DbgEvent

Source code in x64dbg_automate/events.py
class DbgEvent():
    def __init__(self, event_type: str, event_data: list[any]):
        self.event_type = event_type

        if event_type == EventType.EVENT_BREAKPOINT:
            self.event_data = BreakpointEventData(
                type=event_data[0],
                addr=event_data[1],
                enabled=event_data[2],
                singleshoot=event_data[3],
                active=event_data[4],
                name=event_data[5],
                mod=event_data[6],
                slot=event_data[7],
                typeEx=event_data[8],
                hwSize=event_data[9],
                hitCount=event_data[10],
                fastResume=event_data[11],
                silent=event_data[12],
                breakCondition=event_data[13],
                logText=event_data[14],
                logCondition=event_data[15],
                commandText=event_data[16],
                commandCondition=event_data[17]
            )
        elif event_type == EventType.EVENT_SYSTEMBREAKPOINT:
            self.event_data = SysBreakpointEventData(
                reserved=event_data[0]
            )
        elif event_type == EventType.EVENT_CREATE_THREAD:
            self.event_data = CreateThreadEventData(
                dwThreadId=event_data[0],
                lpThreadLocalBase=event_data[1],
                lpStartAddress=event_data[2]
            )
        elif event_type == EventType.EVENT_EXIT_THREAD:
            self.event_data = ExitThreadEventData(
                dwThreadId=event_data[0],
                dwExitCode=event_data[1]
            )
        elif event_type == EventType.EVENT_LOAD_DLL:
            self.event_data = LoadDllEventData(
                modname=event_data[0],
                lpBaseOfDll=event_data[1]
            )
        elif event_type == EventType.EVENT_UNLOAD_DLL:
            self.event_data = UnloadDllEventData(
                lpBaseOfDll=event_data[0]
            )
        elif event_type == EventType.EVENT_OUTPUT_DEBUG_STRING:
            self.event_data = OutputDebugStringEventData(
                lpDebugStringData=event_data[0]
            )
        elif event_type == EventType.EVENT_EXCEPTION:
            self.event_data = ExceptionEventData(
                ExceptionCode=event_data[0],
                ExceptionFlags=event_data[1],
                ExceptionRecord=event_data[2],
                ExceptionAddress=event_data[3],
                NumberParameters=event_data[4],
                ExceptionInformation=event_data[5],
                dwFirstChance=event_data[6]
            )
        else:
            raise ValueError(f"Unknown event type: {event_type}")

EventType

Source code in x64dbg_automate/events.py
class EventType(StrEnum):
    EVENT_BREAKPOINT = "EVENT_BREAKPOINT"
    EVENT_SYSTEMBREAKPOINT = "EVENT_SYSTEMBREAKPOINT"
    EVENT_CREATE_THREAD = "EVENT_CREATE_THREAD"
    EVENT_EXIT_THREAD = "EVENT_EXIT_THREAD"
    EVENT_LOAD_DLL = "EVENT_LOAD_DLL"
    EVENT_UNLOAD_DLL = "EVENT_UNLOAD_DLL"
    EVENT_OUTPUT_DEBUG_STRING = "EVENT_OUTPUT_DEBUG_STRING"
    EVENT_EXCEPTION = "EVENT_EXCEPTION"