Skip to content

Latest commit

 

History

History
166 lines (119 loc) · 5.64 KB

.switch.md

File metadata and controls

166 lines (119 loc) · 5.64 KB
description
Description of the '.switch' command in HyperDbg.

.switch (show the list and switch between active debugging processes)

Command

.switch

Syntax

.switch

.switch [pid ProcessId (hex)]

.switch [tid ThreadId (hex)]

Description

Shows a list of active debugging processes and threads or switches between different active debugging threads and processes. This command displays the list of intercepted threads that you can switch to these processes or threads. It won't show all of the threads of the target process.

{% hint style="success" %} If you don't specify any parameters to this command, it shows the list of threads and processes. {% endhint %}

{% hint style="info" %} This command won't use any Windows API for intercepting and pausing threads, and everything is done at the hypervisor level. {% endhint %}

Parameters

[pid ProcessId (hex)]

The target Process Id to switch.

[tid ThreadId (hex)]

The target Thread Id to switch.

Examples

The following command shows the list of active debugging threads/processes.

1b08:2050 u64HyperDbg> .switch
1a78 (process)
           2020 (thread)
*1b08 (process)
           1380 (thread)
           1ed4 (thread)
        -> 2050 (thread)

We'll use the following command to switch to thread id 0x2020.

1b08:2050 u64HyperDbg> .switch tid 2020
switched to thread id: 2020

As you can see, the arrow in the list of active debugging threads is changed.

1a78:2020 u86HyperDbg> .switch
*1a78 (process)
        -> 2020 (thread)
1b08 (process)
           1380 (thread)
           1ed4 (thread)
           2050 (thread)

It is also possible to switch by using process id.

1a78:428 u86HyperDbg> .switch pid 1b08
switched to process id: 1b08

Again, the active debugging process (thread) is changed.

1b08:1380 u64HyperDbg> .switch
1a78 (process)
           2020 (thread)
           0428 (thread)
           0940 (thread)
           13e4 (thread)
*1b08 (process)
        -> 1380 (thread)
           1ed4 (thread)
           2050 (thread)

IOCTL

This function works by calling DeviceIoControl with IOCTL = IOCTL_DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS. You have to send it in the following structure.

typedef struct _DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS
{
    BOOLEAN                                              IsStartingNewProcess;
    UINT32                                               ProcessId;
    UINT32                                               ThreadId;
    BOOLEAN                                              Is32Bit;
    BOOLEAN                                              IsPaused; // used in switching to threads
    DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS_ACTION_TYPE Action;
    UINT32                                               CountOfActiveDebuggingThreadsAndProcesses; // used in showing the list of active threads/processes
    UINT64                                               Token;
    UINT64                                               Result;

} DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS, *PDEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS;

First, you should set the Action to DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS_ACTION_QUERY_COUNT_OF_ACTIVE_DEBUGGING_THREADS in the above structure, when the IOCTL returns from the kernel, CountOfActiveDebuggingThreadsAndProcesses is filled with appropriate data from the process.

After getting the results from the kernel and if the Result is equal to DEBUGGER_OPERATION_WAS_SUCCESSFULL you should pass a new IOCTL to the kernel again.

The new IOCTL is equal to IOCTL_GET_DETAIL_OF_ACTIVE_THREADS_AND_PROCESSES. There is no need for the input buffer, but for the output buffer, you should allocate a memory with the size of the following structure multiplied by the count of threads/processes returned from the previous IOCTL.

typedef struct _USERMODE_DEBUGGING_THREAD_OR_PROCESS_STATE_DETAILS
{
    UINT32  ProcessId;
    UINT32  ThreadId;
    BOOLEAN IsProcess;

} USERMODE_DEBUGGING_THREAD_OR_PROCESS_STATE_DETAILS, *PUSERMODE_DEBUGGING_THREAD_OR_PROCESS_STATE_DETAILS;

The Action can be from the following enum:

typedef enum _DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS_ACTION_TYPE
{
    DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS_ACTION_ATTACH,
    DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS_ACTION_DETACH,
    DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS_ACTION_REMOVE_HOOKS,
    DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS_ACTION_KILL_PROCESS,
    DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS_ACTION_PAUSE_PROCESS,
    DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS_ACTION_SWITCH_BY_PROCESS_OR_THREAD,
    DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS_ACTION_QUERY_COUNT_OF_ACTIVE_DEBUGGING_THREADS,

} DEBUGGER_ATTACH_DETACH_USER_MODE_PROCESS_ACTION_TYPE;

Remarks

This command is logically designed to be used in VMI Mode. You can use the '.process' and the '.thread' commands in Debugger Mode.

Requirements

None

Related

.start (start a new process)

.restart (restart the process)

.attach (attach to a process)

.detach (detach from the process)

.kill (terminate the process)