Вопрос или проблема
У меня есть ошибка в коде, где rdx = 0x1111111111111111, и это значение разыменовывается, что приводит к нарушению доступа к памяти. Я могу поймать это с помощью исключения первого шанса.
Address=00000000C0000005
Module/Label/Exception=EXCEPTION_ACCESS_VIOLATION
State=Enabled
Hits=1
Summary=firstchance()
Я хочу выяснить, когда этот регистр впервые устанавливается в это значение, чтобы определить коренную причину (возможно, есть и лучший способ). Мой язык интерпретируемый (vba, внедрение ассемблерного кода, хотя ошибка не происходит в моей внедренной функции), поэтому стек вызовов перед исключением не очень полезен.
Я пытался использовать “watchdog” в x64dbg, но он, похоже, срабатывает на той же инструкции, где происходит чтение rdx, а не на той, которая устанавливает rdx.
00007FFB10751E5A | 48:8B52 08 | mov rdx,qword ptr ds:[rdx+8] |
Watchdog Watch 6 (expression "rdx==0x1111111111111111") is triggered at 00007FFB10751E5A ! Original value: 0000000000000000, New value: 0000000000000001
Exception Breakpoint EXCEPTION_ACCESS_VIOLATION (00000000C0000005) at 00007FFB10751E5A!
Watchdog Watch 6 (expression "rdx==0x1111111111111111") is triggered at 00007FFB10751E5A ! Original value: 0000000000000001, New value: 0000000000000001
Я не могу понять, как установить точку остановки, срабатывающую при изменениях в rdx, которые имеют определенное значение.
Name=Watch 6
Expression=rdx==0x1111111111111111
Value=0000000000000001
Type=UINT
Watchdog Mode=Is true
ID=6
Ответ или решение
Описанная вами проблема с регистром RDX и доступом к памяти действительно может быть решена с помощью установления определённого типа прерываний в x64dbg. Основная цель — отследить, когда именно регистр RDX принимает значение 0x1111111111111111
, чтобы выяснить, что приводит к нарушению доступа в вашей программе на VBA.
Для этого вам стоит использовать механизм "Breakpoint on Memory Write", поскольку вам потребуется отследить запись в регистр RDX, а не его чтение. Работая с x64dbg, вы можете воспользоваться следующими шагами:
-
Устанавливаем Breakpoint:
- Перейдите в окно
CPU View
в x64dbg. - Установите обычный прерывание (Breakpoint) на инструкции, которые записывают значение в регистры (например,
mov
инструкции). Например, после нескольких шагов исполняемого кода вы можете установить прерывание на адрес, где вы подозреваете, что RDX может изменяться.
- Перейдите в окно
-
Используйте Условный Breakpoint:
- Когда вы устанавливаете прерывание, вы можете добавить условие, чтобы прерывание срабатывало только тогда, когда RDX становится равным
0x1111111111111111
. - Для этого выполните команду
bp rdx
или введите в командную строку:bp (адрес инструкции) "rdx==0x1111111111111111"
- Это позволит остановиться не просто на инструкции, а именно тогда, когда значение RDX совпадает с искомым.
- Когда вы устанавливаете прерывание, вы можете добавить условие, чтобы прерывание срабатывало только тогда, когда RDX становится равным
-
Используйте "Watch" для отладки:
- В меню
Debug
перейдите вWatch
, добавьте выражение с условием:rdx == 0x1111111111111111
- Это позволит вам видеть, когда регистр принимает нужное значение, даже если вы находитесь в режиме пошаговой отладки.
- В меню
-
Отслеживайте Прерывание на Исключение:
- Убедитесь, что у вас настроено правильное перехватывание исключений. Вы можете воспользоваться режимом исключений в x64dbg, чтобы не только отслеживать доступ к памяти, но и учитывать порядок изменений в регистрах.
- Анализируйте стек вызовов:
- Когда прерывание произойдет, проверьте стек вызовов, даже если он может не быть полон из-за особенностей интерпретируемого языка (VBA). Это поможет понять порядок вызовов, который мог привести к проблеме.
Эти методы должны помочь вам выяснить, когда именно и как зарегистрируется нужное значение в RDX, что и приведёт к нарушению доступа к памяти. Подходя к проблеме с разных сторон, вы сможете установить источник ошибки и, надеюсь, исправить её.