# sb, sd, sq (search virtual memory)

### Command

> sb : search virtual memory as Byte values
>
> sd : search virtual memory as Double-word values (4 bytes)
>
> sq : search virtual memory as Quad-word values (8 bytes)

### Syntax

> sb \[StartAddress (hex)] \[l Length (hex)] \[BytePattern (hex)] \[pid ProcessId (hex)]
>
> sd \[StartAddress (hex)] \[l Length (hex)] \[BytePattern (hex)] \[pid ProcessId (hex)]
>
> sq \[StartAddress (hex)] \[l Length (hex)] \[BytePattern (hex)] \[pid ProcessId (hex)]

### Description

Searches the **virtual** memory for a special byte(s).

### Parameters

**\[StartAddress (hex)]**

The **virtual** address of where we want to start searching from its address.

**\[l Length (hex)]**

Length of the searching area.

**\[BytePattern (hex)]**

Search for these bytes (pattern).

**\[pid ProcessId (hex)] (optional)**

The Process ID in the hex format that we want to see the memory from its context (**cr3**).

{% hint style="info" %}
If you don't specify the **pid**, then the default **pid** is the current process (**HyperDbg**) process layout of memory.
{% endhint %}

### Examples

The following command is used to search for `4156415748` starting from `nt!ExAllocatePoolWithTag` to `nt!ExAllocatePoolWithTag+ffff`.

```diff
HyperDbg> sb nt!ExAllocatePoolWithTag l ffff 41 56 41 57 48 
```

The following command is used to search for `4156415748` starting from `nt!ExAllocatePoolWithTag+100` to `nt!ExAllocatePoolWithTag+100+ffff`.

```diff
HyperDbg> sb nt!ExAllocatePoolWithTag+100 l ffff 41 56 41 57 48 
```

The following command is used to search for `4156415748` starting from ``fffff807`7356f010`` to ``fffff807`7356f010+ffff``.

```diff
HyperDbg> sb fffff807`7356f010 l ffff 41 56 41 57 48 
```

The following example is used when we want to search for `f0cc8549` from `7FF62C9016AD` to `7FF62C9016AD+fff` in a different process (process id = `1dd0`) .

```diff
HyperDbg> sd 7FF62C9016AD pid 1dd0 l fff f0cc8549 
```

The following example is used when we want to search for ``0f450000`00c0888b`` ``8b410000`0092b1b7`` from ``fffff807`7356f010`` to ``fffff807`7356f010+100``.

```diff
HyperDbg> sq fffff807`7356f010 l 100 0f450000`00c0888b 8b410000`0092b1b7
```

### IOCTL

This function works by calling **DeviceIoControl** with `IOCTL = IOCTL_DEBUGGER_SEARCH_MEMORY`, you have to send it in the following structure.

```c
typedef struct _DEBUGGER_SEARCH_MEMORY {

  UINT64 Address;                            // Target address to start searching
  UINT64 Length;                             // Length of bytes to search
  UINT32 ProcessId;                          // specifies the process id
  DEBUGGER_SEARCH_MEMORY_TYPE MemoryType;    // Type of memory
  DEBUGGER_SEARCH_MEMORY_BYTE_SIZE ByteSize; // Modification size
  UINT32 CountOf64Chunks;
  UINT32 FinalStructureSize;

} DEBUGGER_SEARCH_MEMORY, *PDEBUGGER_SEARCH_MEMORY;
```

The `Address` is where we want to start searching from its memory, and it can be both a **physical** address or a **virtual** address.

`ProcessId` is the process that we want to modify based on its memory layout (**cr3**), it can't be `null` or zero.

`MemoryType` shows whether the `Address` is a **physical** address or a **virtual** address.

You can see its values in the following enum :

```c
typedef enum _DEBUGGER_SEARCH_MEMORY_TYPE {
  SEARCH_PHYSICAL_MEMORY,
  SEARCH_VIRTUAL_MEMORY
} DEBUGGER_SEARCH_MEMORY_TYPE;
```

`ByteSize` shows whether we want to search the target Address in a **byte**, **dword**, or **qword** format.

```c
typedef enum _DEBUGGER_SEARCH_MEMORY_BYTE_SIZE {
  SEARCH_BYTE,
  SEARCH_DWORD,
  SEARCH_QWORD
} DEBUGGER_SEARCH_MEMORY_BYTE_SIZE;
```

The above structure is added on top of an array of 64-bit values, which is the new content to the memory.

For example, if you want to search in the memory address of the target for`0x90 0x90` then you should provide an array of `0x0000000000000090` and `0x0000000000000090` and append it to the end of the above structure. The count of these chunks is stored at `CountOf64Chunks` in the above structure and the final buffer that will be sent into the kernel has a size of `FinalStructureSize` bytes.

Also, you should provide a buffer (size = `MaximumSearchResults * sizeof(UINT64)`) as the output buffer, so the kernel-mode module will fill this buffer with a 64-bit array or addresses that match our search results.

You can read the result buffer as an `UINT64` array, and if you encounter a null entry, then it means there is no other result.

### Remarks

* You can search for as many bytes as you need in **byte**, **dword**, and **qword** formats; just add the multiple byte(s) values to the end of the command.

This command is guaranteed to keep debuggee in a halt state (in Debugger Mode); thus, nothing will change during its execution.

### Requirements

None

### Related

None


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.hyperdbg.org/commands/debugging-commands/s.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
