使用Windbg/SOS,可以更改堆棧上本地變量的值?如果是這樣如何?更改本地堆棧變量值
1
A
回答
1
簡短的回答是:這取決於。
默認本地值類型存儲在堆棧中,但由於優化,它們通常只會根據需要存儲在寄存器中。引用類型存儲在堆上,引用堆棧上的實例(或寄存器中)。
我打算假設您正在更改本地值類型。我們來看一個簡單的例子。
[MethodImpl(MethodImplOptions.NoInlining)] // avoid inlining of short method
public static void Method(int x) {
Console.WriteLine("The answer is {0}", x + x);
}
假設我們設置一個斷點上Method
和運行,直到遇到斷點,堆棧看起來是這樣的:
0:000> !clrstack -a
OS Thread Id: 0x1abc (0)
Child SP IP Call Site
0035f290 003600e0 TestBench2010.Program.Method(Int32)*** WARNING: Unable to verify checksum for C:\workspaces\TestBench2010\TestBench2010\bin\Release\TestBench2010.exe
[C:\workspaces\TestBench2010\TestBench2010\Program.cs @ 17]
PARAMETERS:
x (<CLR reg>) = 0x00000002
0035f294 003600a2 TestBench2010.Program.Main(System.String[]) [C:\workspaces\TestBench2010\TestBench2010\Program.cs @ 24]
PARAMETERS:
args = <no data>
0035f4c0 636221bb [GCFrame: 0035f4c0]
注意當地x
被列爲,但它並沒有告訴我們註冊。我們可以查看寄存器並找到值爲2的寄存器,但可能有多個寄存器。相反,我們來看看該方法的JIT編譯代碼。
0:000> !u 001c37f0
Normal JIT generated code
TestBench2010.Program.Method(Int32)
Begin 003600e0, size 32
C:\workspaces\TestBench2010\TestBench2010\Program.cs @ 17:
003600e0 55 push ebp
003600e1 8bec mov ebp,esp
003600e3 56 push esi
003600e4 8bf1 mov esi,ecx
*** WARNING: Unable to verify checksum for C:\windows\assembly\NativeImages_v4.0.30319_32\mscorlib\658bbc023e2f4f4e802be9483e988373\mscorlib.ni.dll
003600e6 b9302be004 mov ecx,offset mscorlib_ni+0x322b30 (04e02b30) (MT: System.Int32)
003600eb e8301fe5ff call 001b2020 (JitHelp: CORINFO_HELP_NEWSFAST)
003600f0 8bd0 mov edx,eax
003600f2 03f6 add esi,esi <==== This is x + x
003600f4 897204 mov dword ptr [edx+4],esi
003600f7 8bf2 mov esi,edx
003600f9 e882709d04 call mscorlib_ni+0x257180 (04d37180)(System.Console.get_Out(), mdToken: 060008cd)
003600fe 56 push esi
003600ff 8bc8 mov ecx,eax
00360101 8b1534204c03 mov edx,dword ptr ds:[34C2034h] ("The answer is {0}")
00360107 8b01 mov eax,dword ptr [ecx]
00360109 8b403c mov eax,dword ptr [eax+3Ch]
0036010c ff5018 call dword ptr [eax+18h]
C:\workspaces\TestBench2010\TestBench2010\Program.cs @ 18:
0036010f 5e pop esi
00360110 5d pop ebp
00360111 c3 ret
看代碼,我們看到的唯一add
指令使用esi
寄存器,所以我們的價值之前存儲在這裏的計算。不幸的是,esi
在這一點上沒有保持正確的值,但向後看,我們發現mov esi,ecx
。即該值最初存儲在ecx
中。
要更改ecx
的值,請使用r
命令。例如。該值設置爲0×15做到以下幾點:
0:000> r ecx=15
方法的輸出,現在是:
答案是42
請記住,上面的例子是隻有許多可能的情況之一。根據調試/發佈版本以及32/64位,本地處理方式不同。另外,對於複雜的方法,可能會更難以跟蹤值的確切位置。
要更改實例的狀態,您必須在堆棧中找到參考(例如使用!clrstack
或!dso
)。一旦找到,您就可以使用偏移量來查找存儲數據的存儲器,並使用e*
命令根據需要更改值。讓我知道你是否也想要一個例子。
相關問題
- 1. 爲什麼本地變量不改變堆棧指針?
- 2. 堆棧變量
- 3. C++本地變量值發生更改
- 4. JVM堆棧變量
- 5. 堆棧計算器改變變量的值
- 6. 堆棧跟蹤和變量值
- 7. 溢出與巨大的本地變量的堆棧?
- 8. 是否有可能std ::移動本地堆棧變量?
- 9. C++本地變量在動態,在堆棧上?
- 10. 安全風險? $ _REQUEST變量... $$本地堆棧
- 11. 在java中使用範圍以外的本地堆棧變量
- 12. 當C'取消分配'本地堆棧變量?
- 13. 何時爲本地變量分配堆棧空間?
- 14. 這會損壞堆棧使用本地變量?
- 15. 從JVM上的堆棧幀獲取本地變量
- 16. 通過創建本地變量減少堆棧指針
- 17. 堆棧變量在走?
- 18. 有條件堆棧變量
- 19. 返回堆棧變量?
- 20. c堆棧變量損壞
- 21. 如何更改本地類變量IBAction
- 22. C代碼堆棧損壞改變變量
- 23. IL無堆棧變量的堆棧項的頂部複製
- 24. 在堆棧展開期間打印堆棧變量
- 25. 使用本地Stata來更改變量的值
- 26. 矢量,堆棧與堆棧(C++)
- 27. 如何將本地變量更改爲實例變量?
- 28. 如何將PayPal發佈的變量更改爲本地變量?
- 29. 修改堆棧上的返回地址
- 30. Sharpdevelop修改本地變量
您是否正在尋找在託管代碼或非託管內部執行此操作的方式? – 2011-04-18 06:26:05
@Seva:由於問題被標記爲SOS,因此它很可能是託管代碼。 – 2011-04-18 07:05:16
@Seva:@Brain是正確的,它的託管代碼 – 2011-04-18 13:09:46