如何确定 WinDbg 中以空字符结尾的字符串的长度
How to determine length of null-terminated string in WinDbg
正在调试的目标进程的地址space中存在一个空终止的ASCII字符串。我想写一个 WinDbg 脚本来打印出这个字符串的长度。假设我知道字符串的起始字符地址,如何计算它的长度?
恕我直言,这在 WinDbg 中并不方便,我尝试寻找涉及 s
、.foreach
和 .if
的解决方案超过 15 分钟,但结果令人沮丧。在这种情况下,我使用真正的编程语言,如 Python 和 PyKD。
将以下内容保存到文件中 strlen.py
:
from pykd import *
import sys
addr = int(sys.argv[1], 16)
length = 0
while(0 != loadBytes(addr+length, 1)[0]):
length += 1
dprintln(str(length))
然后 运行 它以地址作为参数:
0:022> !py c:\tmp\strlen.py 773a004e
43
0:022> db 773a004e L0n44
773a004e 54 68 69 73 20 70 72 6f-67 72 61 6d 20 63 61 6e This program can
773a005e 6e 6f 74 20 62 65 20 72-75 6e 20 69 6e 20 44 4f not be run in DO
773a006e 53 20 6d 6f 64 65 2e 0d-0d 0a 24 00 S mode....$.
请注意,PyKd 不会自动将命名符号转换为地址(例如,您不能将 ntdll
作为地址传递)
我的 pykd 脚本变体:
import sys
import pykd
addr = pykd.expr( sys.argv[1] ) # we can use any expression as a parameter
try:
pykd.dprintln("string length is % d" % pykd.loadCStr( addr ) )
except pykd.MemoryException:
pykd.dprintln("memory error")
也许是笨拙的 windbg 脚本语言
但当然可以即兴创作
把它放在一些 foo.txt 中并将它保存在像 e:\blah\foo.txt
这样的地方
r $t0 = ${$arg1};
r $t1 = @$t0;
.while( @@c++(*(BYTE *) @$t0) != 0) {r $t0 = @$t0+1}
.printf "Len( \"%ma\" ) = 0n%08d\n" , @$t1 ,@$t0-@$t1
并像执行任何普通脚本一样执行
零终止检查示例
0:000> .foreach (place {s -[1]sa ntdll L400} ) { $$>a< e:\xxx\strlen.txt place }
Len( "!This program cannot be run in DOS mode. $" ) = 0n00000044
Len( "gA=é/né/né/nà~½nè/nà~ºn¨/nà~«nÛ/nà~¬nÜ /nà~»nè/nà~¾nè/nRiché/n" ) = 0n00000071
Len( "/nRiché/n" ) = 0n00000010
Len( ".text" ) = 0n00000005
Len( "`RT" ) = 0n00000003
Len( "`.data" ) = 0n00000006
Len( ".rsrc" ) = 0n00000005
Len( "@.reloc" ) = 0n00000007
WinDbg 预览版 14951 附带内置 JavaScript 扩展 [1],因此现在也可以使用 JavaScript:
完成此任务
strlen.js:
function invokeScript()
{
var addr = 0x00c9004e; // address of the string
var str = host.memory.readString(addr);
host.diagnostics.debugLog("String=", str, "\n");
host.diagnostics.debugLog("Length=", str.length, "\n");
}
然后在WinDbg中调用strlen.js:
0:000> .load jsprovider.dll
0:000> .scriptrun "c:\windbg\strlen.js"
JavaScript script successfully loaded from 'C:\windbg\strlen.js'
String=This program cannot be run in DOS mode.
$
Length=43
[1] https://blogs.msdn.microsoft.com/windbg/2016/10/27/new-insider-sdk-and-javascript-extensibility/
[2] 其 API 记录在:JavaScript Debugger Scripting
正在调试的目标进程的地址space中存在一个空终止的ASCII字符串。我想写一个 WinDbg 脚本来打印出这个字符串的长度。假设我知道字符串的起始字符地址,如何计算它的长度?
恕我直言,这在 WinDbg 中并不方便,我尝试寻找涉及 s
、.foreach
和 .if
的解决方案超过 15 分钟,但结果令人沮丧。在这种情况下,我使用真正的编程语言,如 Python 和 PyKD。
将以下内容保存到文件中 strlen.py
:
from pykd import *
import sys
addr = int(sys.argv[1], 16)
length = 0
while(0 != loadBytes(addr+length, 1)[0]):
length += 1
dprintln(str(length))
然后 运行 它以地址作为参数:
0:022> !py c:\tmp\strlen.py 773a004e
43
0:022> db 773a004e L0n44
773a004e 54 68 69 73 20 70 72 6f-67 72 61 6d 20 63 61 6e This program can
773a005e 6e 6f 74 20 62 65 20 72-75 6e 20 69 6e 20 44 4f not be run in DO
773a006e 53 20 6d 6f 64 65 2e 0d-0d 0a 24 00 S mode....$.
请注意,PyKd 不会自动将命名符号转换为地址(例如,您不能将 ntdll
作为地址传递)
我的 pykd 脚本变体:
import sys
import pykd
addr = pykd.expr( sys.argv[1] ) # we can use any expression as a parameter
try:
pykd.dprintln("string length is % d" % pykd.loadCStr( addr ) )
except pykd.MemoryException:
pykd.dprintln("memory error")
也许是笨拙的 windbg 脚本语言
但当然可以即兴创作
把它放在一些 foo.txt 中并将它保存在像 e:\blah\foo.txt
r $t0 = ${$arg1};
r $t1 = @$t0;
.while( @@c++(*(BYTE *) @$t0) != 0) {r $t0 = @$t0+1}
.printf "Len( \"%ma\" ) = 0n%08d\n" , @$t1 ,@$t0-@$t1
并像执行任何普通脚本一样执行
零终止检查示例
0:000> .foreach (place {s -[1]sa ntdll L400} ) { $$>a< e:\xxx\strlen.txt place }
Len( "!This program cannot be run in DOS mode. $" ) = 0n00000044
Len( "gA=é/né/né/nà~½nè/nà~ºn¨/nà~«nÛ/nà~¬nÜ /nà~»nè/nà~¾nè/nRiché/n" ) = 0n00000071
Len( "/nRiché/n" ) = 0n00000010
Len( ".text" ) = 0n00000005
Len( "`RT" ) = 0n00000003
Len( "`.data" ) = 0n00000006
Len( ".rsrc" ) = 0n00000005
Len( "@.reloc" ) = 0n00000007
WinDbg 预览版 14951 附带内置 JavaScript 扩展 [1],因此现在也可以使用 JavaScript:
完成此任务strlen.js:
function invokeScript()
{
var addr = 0x00c9004e; // address of the string
var str = host.memory.readString(addr);
host.diagnostics.debugLog("String=", str, "\n");
host.diagnostics.debugLog("Length=", str.length, "\n");
}
然后在WinDbg中调用strlen.js:
0:000> .load jsprovider.dll
0:000> .scriptrun "c:\windbg\strlen.js"
JavaScript script successfully loaded from 'C:\windbg\strlen.js'
String=This program cannot be run in DOS mode.
$
Length=43
[1] https://blogs.msdn.microsoft.com/windbg/2016/10/27/new-insider-sdk-and-javascript-extensibility/
[2] 其 API 记录在:JavaScript Debugger Scripting