我可以从Visual Studio即时窗口调用Win32 API吗?[英] Can I call a Win32 API from the Visual Studio Immediate Window?

本文是小编为大家收集整理的关于我可以从Visual Studio即时窗口调用Win32 API吗?的处理/解决方法,可以参考本文帮助大家快速定位并解决问题,中文翻译不准确的可切换到English标签页查看源文。

问题描述

我正在调试C ++ Win32应用程序,我想从该过程的上下文中调用任意Win32 API,好像该程序已运行了此行:

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函数,还是我吠叫错误的树?

推荐答案

拥有功能地址后(就像更新的问题中所做的那样),您可以尝试将其施放到函数指针中并调用:

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

其第一部分将地址投放为BOOL (*)(HWND),这是指向HWND参数和返回BOOL的函数的指针.然后,函数指针被删除并调用.确保使参数正确,否则坏事将会发生.在64位系统上,HWND可能是64位,因此您可能无法将参数作为int.

传递给.

编辑:请参阅完整故事的评论.

其他推荐答案

我相信问题是C ++ EE正在遇到问题,可以解决DestroyWindow的背景.尝试以下

{,,user32}DestroyWindow(0x00021c0e);

我不确定方法调用语法是否支持这种资格风格(过去仅用于铸造).但这值得一试.

编辑您可能需要或不需要添加一个!结束后.自从我使用了这种语法以来已经有一段时间了,我经常将其与等效的windbg混淆.

其他推荐答案

我想出了一个解决方法,但我仍然更喜欢立即开始工作.

解决方法是:

  • 获得该功能的地址,如问题所示
  • 使用拆卸窗口转到该地址,然后放置一个断点
  • 对申请做点什么以使其致电DestroyWindow
  • 返回呼叫堆栈到DestroyWindow的呼叫者,看起来像这样:

    6D096A9D推动ECX
    6D096A9E调用DWORD PTR DS:[6D0BB4B8H]

  • 在push ecx指令上放一个断点,然后在DestroyWindow

  • 上清除一个断点
  • 命中继续,然后再次对应用程序做些事情,以使其调用该代码
  • 记下ecx
  • 的值
  • 将调试器中ecx的值更改为所需值,然后逐步push/call
  • 还原ecx的值并使用设置下一个语句以返回push,然后继续

它很愉快,但起作用.它假设您可以随意使申请调用适当的API.

本文地址:https://www.itbaoku.cn/post/1875811.html

问题描述

I'm debugging a C++ Win32 application and I'd like to call an arbitrary Win32 API from the context of that process, as though the program had run this line of code:

DestroyWindow(0x00021c0e);

But entering that into the Immediate Window gives:

CXX0017: Error: symbol "DestroyWindow" not found

Edit: Using the full name of the function, {,,user32.dll}_NtUserDestroyWindow@4, I can get the Immediate Window to understand which function I mean and display the function's address:

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

but when I try to call it, this happens:

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

Is it even possible to call a C function from the Immediate Window like this, or am I barking up the wrong tree?

推荐答案

Once you have the function address (as you've done in the updated question), you can try casting it to a function pointer and calling it:

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

The first part of that casts the address to BOOL (*)(HWND), which is a pointer to a function taking an HWND parameter and returning BOOL. Then, the function pointer is dereferenced and called. Make sure to get the parameters correct, otherwise bad things will happen. On 64-bit systems, and HWND might be 64 bits, so you might not be able to get away with passing the parameter as an int.

Edit: See the comments for the full story.

其他推荐答案

I believe the problem is that the C++ EE is having problems resolving the context of DestroyWindow. Try the following

{,,user32}DestroyWindow(0x00021c0e);

I'm not sure if the method invocation syntax supports this style of qualification (only used it for casting in the past). But it's worth a shot.

EDIT You may or may not need to add a ! after the closing }. It's been awhile since I've used this syntax and I often confuse it with the equivalent windbg one.

其他推荐答案

I figured out a workaround, but I'd still prefer to get the Immediate Window to work.

The workaround is:

  • get the address of the function, as shown in the question
  • use the Disassembly window to go to that address, and put a breakpoint there
  • do something to the application to make it call DestroyWindow
  • step back up the call stack to the caller of DestroyWindow, which looks like this:

    6D096A9D push ecx
    6D096A9E call dword ptr ds:[6D0BB4B8h]

  • put a breakpoint on the push ecx instruction, and clear the one on DestroyWindow

  • hit Continue, and again do something to the application to make it call that code
  • note down the value of ecx
  • change the value of ecx in the debugger to the desired value and step over the push/call
  • restore the value of ecx and use Set Next Statement to go back to the push, then Continue

It's longwinded, but it works. It assumes you can make the application call the appropriate API at will.