Можно ли вызвать Win32 API из окна Visual Studio Immediate? - PullRequest
11 голосов
/ 21 августа 2009

Я отлаживаю приложение C32 для Win32 и хотел бы вызвать произвольный API Win32 из контекста этого процесса, как если бы программа выполняла следующую строку кода:

DestroyWindow(0x00021c0e);

Но если ввести это в окно «Немедленно», то получится:

CXX0017: Error: symbol "DestroyWindow" not found

Редактировать: Используя полное имя функции, {,,user32.dll}_NtUserDestroyWindow@4, я могу получить немедленное окно, чтобы понять, какую функцию я имею в виду, и отобразить адрес функции:

{,,user32.dll}_NtUserDestroyWindow@4
0x76600454 _NtUserDestroyWindow@4

но когда я пытаюсь позвонить, это происходит:

{,,user32.dll}_NtUserDestroyWindow@4(0x00021c0e);
CXX0004: Error: syntax error

Можно ли даже вызвать функцию C из окна Immediate, как это, или я лаю не на том дереве?

Ответы [ 3 ]

5 голосов
/ 22 августа 2009

Получив адрес функции (как вы сделали в обновленном вопросе), вы можете попробовать привести его к указателю на функцию и вызвать его:

(*(BOOL (*)(HWND))0x76600454)((HWND)0x00021c0e)

Первая часть этого адреса приводит к адресу BOOL (*)(HWND), который является указателем на функцию, принимающую параметр HWND и возвращающую BOOL. Затем указатель на функцию разыменовывается и вызывается. Убедитесь в правильности параметров, иначе произойдут плохие вещи. В 64-битных системах HWND может быть 64-битным, поэтому вы не сможете избежать передачи параметра как int.

Редактировать: См. Комментарии к полной истории.

2 голосов
/ 21 августа 2009

Я считаю, что проблема в том, что в C ++ EE возникают проблемы с разрешением контекста DestroyWindow. Попробуйте следующее

{,,user32}DestroyWindow(0x00021c0e);

Я не уверен, поддерживает ли синтаксис вызова метода этот стиль квалификации (он использовался только для приведения в прошлом). Но оно того стоит.

РЕДАКТИРОВАТЬ Вы можете добавить или не добавлять! после закрытия}. Прошло некоторое время с тех пор, как я использовал этот синтаксис, и я часто путаю его с эквивалентным синтаксисом.

1 голос
/ 21 августа 2009

Я нашел обходной путь, но все равно предпочел бы, чтобы Немедленное Окно заработало.

Обходной путь:

  • получить адрес функции, как показано в вопросе
  • используйте окно Разборка, чтобы перейти по этому адресу, и установите точку останова
  • сделать что-нибудь с приложением, чтобы оно вызвало DestroyWindow
  • шаг назад до стека вызовов до вызывающего DestroyWindow, который выглядит следующим образом:

    6D096A9D push ecx
    6D096A9E вызов dword ptr ds: [6D0BB4B8h]

  • установите точку останова в инструкции push ecx и очистите ее в DestroyWindow

  • нажмите Продолжить и снова сделайте что-нибудь с приложением, чтобы оно вызывало этот код
  • записать значение ecx
  • измените значение ecx в отладчике на нужное значение и перешагните через push/call
  • восстановить значение ecx и использовать Set Next Statement, чтобы вернуться к push, затем продолжить

Это долго, но работает. Предполагается, что вы можете заставить приложение вызывать соответствующий API по желанию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...