代码之家  ›  专栏  ›  技术社区  ›  RichieHindle

我可以从Visual Studio即时窗口调用Win32 API吗?

  •  11
  • RichieHindle  · 技术社区  · 15 年前

    我正在调试一个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函数,或者我调用了错误的树?

    3 回复  |  直到 15 年前
        1
  •  5
  •   RichieHindle    15 年前

    一旦您有了函数地址(正如您在更新的问题中所做的那样),就可以尝试将其转换为函数指针并调用它:

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

    第一部分将地址强制转换为 BOOL (*)(HWND) ,它是一个指针,指向一个函数 HWND 参数和返回 BOOL . 然后,函数指针被取消引用并被调用。确保参数正确,否则会发生不好的事情。在64位系统上,以及 HWND 可能是64位,因此您可能无法将参数作为 int .

    编辑: 请参阅完整故事的注释。

        2
  •  2
  •   JaredPar    15 年前

    我认为问题是C++EE在解决破译窗口的上下文方面存在问题。尝试以下操作

    {,,user32}DestroyWindow(0x00021c0e);
    

    我不确定方法调用语法是否支持这种类型的限定(在过去只用于强制转换)。但值得一试。

    编辑 您可能需要或可能不需要添加!结束后。我用了这个语法已经有一段时间了,我经常把它与等效的windbg语法混淆。

        3
  •  1
  •   RichieHindle    15 年前

    我想出了一个解决办法,但我还是宁愿让直接窗口工作。

    解决方法是:

    • 获取函数的地址,如问题中所示
    • 使用反汇编窗口转到那个地址,并在那里放置一个断点
    • 对应用程序执行某些操作以使其调用 DestroyWindow
    • 将调用堆栈备份到的调用方 窗口销毁 ,如下所示:

      6D096A9D推ECX
      6D096A9E调用dword ptr ds:[6D0BB4B8H]

    • 在上放置断点 push ecx 指示,并清除 窗口销毁

    • 单击“继续”,然后再次对应用程序执行一些操作,使其调用该代码
    • 记下 ecx
    • 更改的值 ECX 在调试器中转到所需的值并单步执行 push/call
    • 恢复的值 ECX 并使用set next语句返回 push 然后继续

    很长时间了,但它起作用了。它假定您可以让应用程序随意调用适当的API。