Найдите адрес статического члена класса C++ с помощью WinDbg.

Вопрос или проблема

Найдите адрес статического члена класса C++ с помощью WinDbg.

Я не имею опыта работы с WinDbg и пытаюсь установить точку прерывания данных (ba) на статической переменной-члене в приложении C++ Win32, чтобы увидеть, когда она повреждается из-за непреднамеренных записей. Назовем ее MyClass::m_StaticData. Я понимаю, что сначала мне нужно найти адрес памяти MyClass::m_StaticData. Однако я не уверен, как найти адрес статической переменной-члена. Я нашел команды для локальных переменных (dv) и экземпляров классов (dt), но ничего не нашел для статических переменных.

Рассмотрим следующий код на C++:

class Box {
   public:
      static int objectCount;
      Box(double l = 2.0, double b = 2.0, double h = 2.0) {
         length = l;
         breadth = b;
         height = h;
         objectCount++;
      }
      double Volume() {
         return length * breadth * height;
      }
      static int getCount() {
         return objectCount;
      }

   private:
      double length;     
      double breadth;    
      double height;     
};

int Box::objectCount = 0;

int main(void) {
   Box Box1(3.3, 1.2, 1.5);    
   return 0;
}

Некоторые компиляторы ведут себя по-разному, но MSVC скомпилирует приведенный выше код и сохранит статические переменные вашего класса внутри сегмента .data бинарного файла PE32, вы можете увидеть, каким образом они ссылаются, и мы можем подтвердить, где они хранятся.

Дизассемблирование в IDA

Сегмент .data

Вам нужно будет искать перекрестные ссылки в скомпилированной версии вашего кода, чтобы получить относительный адрес, где переменная выделяется при инициализации. Я не знаю, что это можно легко сделать только с помощью WinDbg, поэтому, взглянув на самый первый смещение кода, которое ссылается на вашу статическую переменную, вы получите RVA вашей переменной, а затем сможете установить там точку прерывания доступа к данным.

Ответ или решение

Для того чтобы найти адрес статического члена класса (в данном случае MyClass::m_StaticData) и установить на него точку останова данных (data breakpoint) с помощью WinDbg, необходимо выполнить несколько шагов. Рассмотрим это на примере кода, который был предоставлен:

class Box {
   public:
      static int objectCount;
      Box(double l = 2.0, double b = 2.0, double h = 2.0) {
         length = l;
         breadth = b;
         height = h;
         objectCount++;
      }
      double Volume() {
         return length * breadth * height;
      }
      static int getCount() {
         return objectCount;
      }

   private:
      double length;     
      double breadth;    
      double height;     
};

int Box::objectCount = 0;

int main(void) {
   Box Box1(3.3, 1.2, 1.5);    
   return 0;
}

Шаги для нахождения адреса статического члена и установки точки останова:

  1. Скомпилируйте проект в режиме отладки: Убедитесь, что ваш проект скомпилирован с включенными отладочными символами (например, используйте флаг /Zi в MSVC).

  2. Запустите ваш приложение в WinDbg: Откройте WinDbg и подключитесь к вашему работающему приложению.

  3. Загрузите символы: Убедитесь, что символы загружены корректно. Используйте команду !sym noisy, чтобы отладчик выводил дополнительные сообщения о загрузке символов. Затем выполните команду .reload для перезагрузки символов.

  4. Определите адрес статического члена:

    1. Вам нужно будет узнать, где именно в памяти находится статический член objectCount. Используйте команду x для поиска:
      x Box::objectCount
    2. Если все сделано правильно, WinDbg выведет информацию о вашем статическом члене в формате, например:
      01234ABC Box::objectCount

      Здесь 01234ABC будет адресом objectCount.

  5. Установка точки останова данных: Как только вы узнали адрес статического члена, вы можете установить точку останова данных. Используйте команду ba:

    ba w4 01234ABC

    Здесь w4 указывает на то, что вы хотите установить точку останова на запись 4-байтного значения.

  6. Запуск и диагностика: Запустите ваше приложение, и как только произойдет запись в objectCount, выполнение программы остановится, и вы сможете исследовать стек вызовов и текущее состояние программы для диагностики проблемы.

Дополнительные советы:

  • Используйте команду !address для отображения информации о памяти, если вам нужно больше информации о том, как работает память в вашем приложении.
  • Опционально, вы можете использовать команду .data для получения доступа к сегментам данных, если потребуется больше информации о других статических и глобальных переменных.

Таким образом, следуя вышеизложенным шагам, вы сможете найти адрес статического члена класса и установить на него точку останова в WinDbg для дальнейшего анализа.

Оцените материал
Добавить комментарий

Капча загружается...