.call(调用函数)

.call 命令会导致目标进程执行函数。

.call [/v] Function( Arguments ) 
.call /s Prototype Function( Arguments ) 
.call /c 
.call /C 

参数

/V
将显示有关调用及其参数的详细信息。

/s原型
允许调用 Function 指定的函数,即使没有正确的符号也是如此。 在这种情况下,必须具有另一个函数的符号,该函数的调用原型与你尝试调用的函数具有相同。 Prototype 参数是此原型函数的名称。

功能
指定要调用的函数。 这可以是函数的名称 (最好是用模块名称) 限定,也可以是计算结果为函数地址的任何其他表达式。 如果需要调用构造函数或析构函数,则必须提供地址 ,或者使用 C++ 表达式来计算运算符的命名语法 (请参阅 数值表达式语法 ,了解) 的详细信息。

参数
指定传递给函数的参数。 如果要调用方法,则第一个参数必须是 此方法,所有其他参数都紧随其后。 参数应用逗号分隔,并且应与常用的参数语法匹配。 支持可变长度参数列表。 参数中的表达式由 C++ 表达式计算器分析;有关详细信息,请参阅 C++ 数字和运算符 。 不能输入文本字符串作为参数,但可以使用指向字符串的指针或目标进程可访问的任何其他内存。

/C
清除当前线程上的任何现有调用。

/C
清除当前线程上的任何现有调用,并将当前线程的上下文重置为未完成调用存储的上下文。

环境

模式

仅限用户模式

目标

仅实时调试

平台

仅 x86 和 x64

注解

指定的函数由当前进程的当前线程调用。

仅支持 cdeclstdcallfastcallthiscall 调用约定。 此命令无法调用托管代码。

使用 .call 后,调试器将更新堆栈,将指令指针更改为指向被调用函数的开头,然后停止。 使用 g (Go) 可恢复执行,或 使用 ~. g 仅执行发出调用的线程。

当函数返回时,将发生中断,调试器显示函数的返回值。 返回值也存储在 $callret 伪寄存器中,后者获取返回值的类型。

如果已使用 CTRL+C 或 CTRL+BREAK 进入目标,则当前线程是为处理中断而创建的其他线程。 如果此时发出 .call 命令,则额外的线程将用于被调用的函数。

如果已到达预定义的断点,则没有额外的断点线程。 如果在用户模式下的断点处使用 .call ,则可以使用 g 执行整个进程,或使用 ~. g 仅执行当前线程。 使用 g 可能会扭曲程序的行为,因为你已采用一个线程并将其转移到此新函数。 另一方面,此线程仍将具有其锁和其他属性,因此 ~. g 可能会有死锁的风险。

使用 .call 的最安全方法是在代码中设置一个可以安全调用某个函数的位置的断点。 命中该断点时,如果需要运行该函数,可以使用 .call 。 如果在通常无法调用此函数的位置使用 .call ,则可能会导致死锁或目标损坏。

将未由现有代码调用但旨在由调试器调用的额外函数添加到源代码中可能很有用。 例如,可以添加用于调查代码及其环境的当前状态的函数,并将有关状态的信息存储在已知内存位置。 请确保不要优化代码,否则编译器可能会删除这些函数。 仅将此技术用作最后的手段,因为如果应用程序崩溃,则 .调用 在调试转储文件时将不可用。

仅当尝试使用 .call 失败,或者在输入 g 命令之前改变了主意时,才应使用 .call /c 和 .call /C 命令。 不应随意使用它们,因为放弃未完成的调用可能会导致目标状态损坏。

下面的代码示例演示如何使用 .call /s 命令。

.call /s KnownFunction UnknownFunction( 1 )

在此示例中, 有 KnownFunction 的私有符号,该符号采用整数作为其唯一参数,并返回(例如指向数组的指针)。 你没有符号,或者可能只有 UnknownFunction 的公共符号,但你知道它采用整数作为其唯一参数,并返回指向数组的指针。 通过使用 /s 选项,可以指定 UnknownFunction 的工作方式与 KnownFunction 的工作方式相同。 因此,可以成功生成对 UnknownFunction 的调用。