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:
- Requesting the change in state
- 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 |
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"