在windbg和WinDbg和SoS中调试.Net字符串值,如何打印/转储大字符串?显示将字符串转储到本地文件的脚本:
$$ Dumps the managed strings to a file
$$ Platform x86
$$ Usage $$>a<"c:\temp\dumpstringtofolder.txt" 6544f9ac 5000 c:\temp\stringtest
$$ First argument is the string method table pointer
$$ Second argument is the Min size of the string that needs to be used filter the strings
$$ Third is the path of the file
.foreach ($string {!dumpheap -short -mt ${$arg1} -min ${$arg2}})
{
$$ MT Field Offset Type VT Attr Value Name
$$ 65452978 40000ed 4 System.Int32 1 instance 71117 m_stringLength
$$ 65451dc8 40000ee 8 System.Char 1 instance 3c m_firstChar
$$ 6544f9ac 40000ef 8 System.String 0 shared static Empty
$$ start of string is stored in the 8th offset, which can be inferred from above
$$ Size of the string which is stored in the 4th offset
r@$t0= poi(${$string}+4)*2
.writemem ${$arg3}${$string}.txt ${$string}+8 ${$string}+8+@$t0
}
Run Code Online (Sandbox Code Playgroud)
这个脚本在x86上.我修改代码并尝试.net 4.0,x64系统.
唯一的区别是偏移量不同.例如:
$$ .net 4.0 , the offset is different
$$ MT Field Offset Type VT Attr Value Name
$$ 000007fee4abc7e8 4000103 8 System.Int32 1 instance 460 m_stringLength
$$ 000007fee4abb328 4000104 c System.Char 1 instance 26 m_firstChar
$$ 000007fee4ab6900 4000105 10 System.String 0 shared static Empty
Run Code Online (Sandbox Code Playgroud)
所以,我将我的代码更改为:
r@$t0= poi(${$string}+8)*2
.writemem ${$arg3}${$string}.txt ${$string}+c ${$string}+c+@$t0
Run Code Online (Sandbox Code Playgroud)
在这里,我想知道函数poi,
1.为什么这里需要'*2'?
我找到一个字符串地址,运行!do,像这样:
0:000> !do 0x00000000ffad0de0
Name: System.String
MethodTable: 000007fef5da6738
EEClass: 000007fef592ed68
Size: 794(0x31a) bytes
File: C:\Windows\Microsoft.Net\assembly\GAC_64\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll
String: jv15Rr2HXPn3....
Fields:
MT Field Offset Type VT Attr Value Name
000007fef5dac620 4000103 8 System.Int32 1 instance 384 m_stringLength
000007fef5dab160 4000104 c System.Char 1 instance 6a m_firstChar
000007fef5da6738 4000105 10 System.String 0 shared static Empty
Run Code Online (Sandbox Code Playgroud)
我跑
0:000> ? poi(0x00000000ffad0de0)+8
Evaluate expression: 8791627818816 = 000007fe`f5da6740
Run Code Online (Sandbox Code Playgroud)
获取长度值384,但输出值错误(显示为8791627818816).怎么了?
感谢你们对我的帮助!
更新1):我试过:
0:000> r@$t0= poi(0x00000000ffad0de0+8)
0:000> r@$t0
$t0=0076006a00000180
Run Code Online (Sandbox Code Playgroud)
结果似乎不正确.
更新2):我试图调试脚本:
.echo ${$str}
r@$t0= poi(${$str}+8)*2
.printf "@$t0 is %d\n", @$t0
.echo ${$arg3}${$str}.txt
.printf "${$str}+c: %p\n", ${$str}+c
.printf "${$str}+c+@$t0: %p\n", ${$str}+c+@$t0
$$.writemem ${$arg3}${$str}.txt ${$str}+c ${$str}+c+@$t0
Run Code Online (Sandbox Code Playgroud)
然后我得到了输出:
0x00000000ffad4550
@$t0 is 640
c:\stringtest\0x00000000ffad4550.txt
0x00000000ffad4550+c: 00000000ffad455c
0x00000000ffad4550+c+@$t0: 00ec00d4ffad47dc
Run Code Online (Sandbox Code Playgroud)
然后我运行.writemem作为输出地址:
0:000> .writemem c:\stringtest\ss.txt 00000000ffad455c L0n640
Writing 280 bytes.
Run Code Online (Sandbox Code Playgroud)
我得到了正确的字符串,就像这样:
/txrqcf...........j7ULyzqxSmB3bpu
Run Code Online (Sandbox Code Playgroud)
我运行命令:
0:000> .writemem c:\stringtest\ss.txt 00000000ffad455c 00ec00d4ffad47dc
^ Range error
Run Code Online (Sandbox Code Playgroud)
我收到错误范围错误,我检查链接以找出结果,但我不知道.
poi($ {$ string} +8)是以字符为单位的字符串长度.
*2是必需的,因为C#中的字符串是Unicode,而对于写入内存,我们需要字节,而不是字符.
+ c是64位的char []的偏移量.这是写作的起始地址.
? poi(0x00000000ffad0de0)+8
Run Code Online (Sandbox Code Playgroud)
这是不正确的,因为poi(0x00000000ffad0de0)为您提供.NET对象的方法表的值,即000007fef5da6738,然后添加8,即7FEF5DA6740.
你想做的是
? poi(0x00000000ffad0de0+8)
Run Code Online (Sandbox Code Playgroud)
在牙箍里面.
要绕过范围错误,请使用L?语法改为范围开始和范围结束:
.writemem ${$arg3}${$str}.txt ${$str}+c L? @$t0
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
4013 次 |
最近记录: |