更改局部堆栈变量值
使用 Windbg/SOS,可以更改堆栈上局部变量的值吗?如果是这样怎么办?
Using Windbg/SOS, it possible to change value of a local varible on stack? If so how?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
使用 Windbg/SOS,可以更改堆栈上局部变量的值吗?如果是这样怎么办?
Using Windbg/SOS, it possible to change value of a local varible on stack? If so how?
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
接受
或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
发布评论
评论(1)
简短的回答是:这取决于。
默认情况下,本地值类型存储在堆栈中,但由于优化,它们通常仅根据需要存储在寄存器中。引用类型存储在堆上,并引用堆栈上(或寄存器中)的实例。
我假设您正在寻求更改本地值类型。让我们看一个简单的例子。
假设我们在
Method
上设置断点并运行直到遇到断点,堆栈看起来像这样:注意,本地
x
被列为 ,但它并没有告诉我们我们注册的。我们可以查看寄存器并找到值为 2 的寄存器,但也可能不止一个。相反,让我们看看该方法的 JIT 编译代码。查看代码,我们发现唯一的
add
指令使用了esi
寄存器,因此我们的值在计算之前存储在这里。不幸的是,此时esi
没有保存正确的值,但向后看我们发现mov esi,ecx
。即该值最初存储在ecx
中。要更改 ecx 的值,请使用 r 命令。例如,要将值设置为 0x15,请执行以下操作:
该方法的输出现在为:
请记住,上面的示例只是许多可能的情况之一。根据调试/发布版本以及 32/64 位,本地变量的处理方式有所不同。此外,对于复杂的方法,跟踪值的确切位置可能会有点困难。
要更改实例的状态,您必须在堆栈上找到引用(例如使用
!clrstack
或!dso
)。找到后,您可以使用偏移量来查找保存数据的内存,并使用e*
命令根据需要更改值。如果您也想要一个例子,请告诉我。The short answer is: It depends.
Per default local value types are stored on the stack but due to optimization they will often be stored only in registers as needed. Reference types are stored on the heap, with a reference to the instance on the stack (or in a register).
I am going to assume that you're looking to change a local value type. Let's look at a simple example.
Assuming we set a breakpoint on
Method
and run until the breakpoint is hit, the stack looks like this:Notice that the local
x
is listed as , but it doesn't tell us which register. We could look at the registers and find the one with the value 2, but there could be more than one. Instead let's look at the JIT compiled code for the method.Looking at the code, we see that the only
add
instruction uses theesi
register, so our value is stored here prior to the calculation. Unfortunately,esi
doesn't hold the correct value at this point, but looking backwards we findmov esi,ecx
. I.e. the value is initially stored inecx
.To change the value of
ecx
use ther
command. E.g. to set the value to 0x15 do the following:The output of the method is now:
Please keep in mind that the example above is only one of many possible scenarios. Locals are handled differently depending on debug/release build as well as 32/64 bit. Also, for complex methods it may be a bit harder tracking the exact location of the value.
To change the state of an instance, you have to locate the reference on the stack (e.g. using
!clrstack
or!dso
). Once located you can use the offsets to find the memory, that holds the data and use thee*
commands to change the values as needed. Let me know if you want an example for that as well.