> For the complete documentation index, see [llms.txt](https://yutewiyof.gitbook.io/intro-rev-ida-pro/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://yutewiyof.gitbook.io/intro-rev-ida-pro/chast-53.md).

# Часть 53

Деталь, про которую я хотел рассказать в этом туториале, которую в предыдущей части мы не рассматривали, так как определение структуры **IRP** не было для нас полным...

Если я вернусь к отладке и когда остановлюсь, я буду использовать командную строку **WINDBG**, чтобы увидеть содержимое структуры. Мы знаем, что команда **DT** показывает нам содержимое структуру. В этом случае это содержимое структуры **\_IRP**.

![](/files/-LjrT41M9kjcrr1axS5c)

**IDA** не показывает нам поле по смещению **0x60**, которое является тем, которое читается и находится внутри структуры **TAIL**. Но здесь есть трюк, который помогает прояснить немного больше вещей.

![](/files/-LjtuZxwjvBmxuOXmeFL)

Существует несколько модификаторов для команды **DT**. Первый модификатор - это **-V**, который переводит команду в подробный режим. Другой модификатор - это **-R**, который задаёт глубину подструктур, чтобы показать нам её же. Давайте посмотрим, что произойдет, если мы введем такую команду.

![](/files/-LjtuZyPApxVvH3bs_dr)

![](/files/-LjtuZynQHuF0GbgCBV2)

Теперь **IRP** выглядит намного лучше. Нам даже показывается содержимое подструктуры **TAIL**

![](/files/-LjtuZz2MUky2F2iOGyz)

Мы видим, что подструктура **TAIL** начинается по смещению **0x40** основной структуры, а по смещению **0x20** подструктуры **TAIL** чуть ниже находится указатель **CURRENTSTACKLOCATION**, который тоже будет структурой. Она находится по смещению **0x60**

Мы поищем структуру **CURRENTSTACKLOCATION** в **WDK**, если он конечно установлен

![](/files/-LjrT41y3dgOeEQqTgEo)

**WINCMD** находит нам указатель **CURRENTSTACKLOCATION**, который является структурой типа **\_IO\_STACK\_LOCATION**. Давайте посмотрим, покажет ли нам **WINDBG** содержимое структуры.

![](/files/-LjrT423HaVBeOe_bGME)

Мы получили то что нужно. Но все же нам не показывается поле **0X0C**, которое находящееся внутри структуры **PARAMETERS**. Также мы увидели, что нам показывается структура у которой есть подструктуры. Поэтому мы будем использовать модификаторы снова.

![](/files/-LjtuZzyFlZoo4MGquTo)

![](/files/-Ljtu_-CyiRNbiGucyhN)

Мы видим, что поля, начинающиеся со смещения **0x004**. Имена изменяются в соответствии с действием, которое они выполняют. Для каждого действия существует другое определение этих полей.

Поскольку в нашем случае, мы ищем код **IOCTL**, который используется только во второй раз, когда мы вызываем **DEVICEIOCONTROL**, поэтому мы можем посмотреть здесь и увидеть, что поле **0x8** внутри **PARAMETERS**, для этого случая это **IOCTL**. Если мы посмотрим с начала структуры **\_IO\_STACK\_LOCATION** это будет полем по смещению **0xC**, так как перед **PARAMETERS** было **0x4** байт.

Если мы поищем в **WDK** определение структуры.

![](/files/-Ljtu_-WhG52lI3CdWy1)

Мы видим, что так же как и в **WINDBG**, мы получаем, что первая часть является фиксированной, но затем, когда она идет слово, **UNION** это означает, что следующая часть является переменной частью и зависит от кода, с которым мы работаем. Существуют разные значения в зависимости от того, что и как вы вызываете функции **CREATEFILE**, **READFILE** и т.д., Что же важно для нас, это то, что когда драйвер вызывается из **DEVICEIOCONTROL**, так как это **API**, который используется для передачи кода **IOCTL**.

![](/files/-Ljtu_-pODoTwCeOsHYB)

Ahí esta asi que como el tipo **ULONG** es de **4** bytes de largo. Vemos entonces que si lo completamos.

![](/files/-Ljtu_06RWq4n_kaeI_B)

Первые четыре переменные являются типа **UCHAR**, т.е. байт. Сумма всех полей означает, что структура **PARAMETERS** начинается по смещению **0x4**. Вот что на это сказал нам **WINDBG**.

![](/files/-Ljtu_0Pe8bsO-sHN5aX)

И затем здесь по смещению **0x4** от начала структуры **\_IO\_STACK\_LOCATION** будет первое поле **OUTPUTBUFFERLENGHT** структуры. По смещению **0x8** будет поле **INPUTBUFFERLENGHT**, а по смещению **0xC** будет **IOCTL** или поле **IOCONTROLCODE**.

Это совпадает с нашим реверсингом, поскольку, если по смещению **IRP**+**0x60** начинается структура **\_IO\_STACK\_LOCATION**, то она читается здесь.

![](/files/-Ljtu_0flp9O8tTszbHP)

Это означает, что в регистр **EBX** помещается адрес структуры **\_IO\_STACK\_LOCATION**. Поэтому поскольку она существует в **LOCAL TYPES** в **IDA**, мы синхронизируем её с кодом. И в регистре **EBX** мы нажимаем **T** и выбираем её.

![](/files/-LjrT43NRH0Y3WDTk7Er)

Здесь драйвер читает в регистр **EAX** значение **MAJORFUNCTION**. Так как он читает только один байт, то это будет это поле.

![](/files/-LjrT43Vvp73mf76imZ6)

Давайте вспомним, что это было значение, которое мы взяли из таблицы

![](/files/-LjrT43bfoW1Eu347n3b)

![](/files/-MX3mK93KxY9KSnvgkON)

В первый раз, когда я вызываю функции **CREATEFILE**, будет передавать код **0x0**. Во второй раз, когда я использую функцию **DEVICEIOCONTROL**, будет передавать код **0xE**. И в третий раз, когда я вызываю функцию **CLOSEHANDLE**, будет передавать код **0x02**.

Конечно, поскольку это первый вызов, когда отладчик останавливается и когда драйвер вызывает функцию **CREATEFILE**, регистр **EAX** будет равен нулю.

![](/files/-LjrT43o-jpP3RQs0TvC)

Я буду продолжать, пока не остановлюсь снова на том же адресе.

Сейчас, если **MAJORFUNCION** равно **0xE**.

![](/files/-Ljtu_2N_H9bFBfOwGBa)

Мы видим, что мы находимся на инструкции, где по смещению **0xC**, будет сохраняться **IOCTL**. Если я нажму **T**.

![](/files/-Ljtu_2YE6oJ1GhtF62e)

И мне показывается список опций. Я вижу, что есть для поля для **CREATE**, **READ** и т.д. Я ищу функцию **DEVICEIOCONTROL** и поле **IOCONTROLCODE**.

Y ahora si me queda perfectamente reverseado y coincide ya que solo pasara por alli cuando sea el **MAJORFUNCTION 0xE**, y como en los otros valores de **MAJORFUNCION** no pasa por acá, no habrá ningún error.

![](/files/-LjrT44DxBfQa7AOKxr5)

Если в другой части программы драйвер прочитает это же самое поле **0xC**, когда он использует другую функцию **MAJORFUNCTION**, в этом случае, нажав **T**, мы выберем соответствующее поле.

Автор оригинального текста — Рикардо Нарваха.

Перевод и адаптация на русский язык — Яша Яшечкин.

Перевод специально для форума системного и низкоуровневого программирования - WASM.IN

25.10.2018

[**Источник: ricardonarvaja.info**](http://ricardonarvaja.info/WEB/IDA%20DESDE%20CERO/CURSO%20DE%20IDA%20TUTES/53-INTRODUCCION%20AL%20REVERSING%20CON%20IDA%20PRO%20DESDE%20CERO.docx)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## 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, and the optional `goal` query parameter:

```
GET https://yutewiyof.gitbook.io/intro-rev-ida-pro/chast-53.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
