2

There is a null-terminated ASCII string existing in the address space of the target process under debugging. I want to write a WinDbg script to print out the length of this string. Assuming I know the address of the starting character of the string, how do I calculate its length?

Thomas Weller
  • 55,411
  • 20
  • 125
  • 222
X. Liu
  • 1,070
  • 11
  • 30

4 Answers4

3

well unwieldy windbg script language maybe
but certainly improviseable
put this in some foo.txt and save it somewhere like 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

and execute like you would execute any normal script

an example of zero termination check

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
blabb
  • 8,674
  • 1
  • 18
  • 27
2

My variant of pykd script:

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")
ussrhero
  • 161
  • 1
  • 3
1

IMHO it's not convenient in WinDbg and I tried finding a solution involving s, .foreach and .if for more than 15 minutes but the result was frustrating. In such a case I use a real programming language like Python with PyKD.

Save the following into a file 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))

Then run it with the address as argument:

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....$.

Note that PyKd does not automatically convert named symbols to addresses (e.g. you can't pass ntdll as an address)

Thomas Weller
  • 55,411
  • 20
  • 125
  • 222
1

WinDbg preview 14951 ships with a built-in JavaScript Extension[1], so now this task can also be done with 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");
}

Then call strlen.js in WinDbg:

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] Its APIs are documented at: JavaScript Debugger Scripting

X. Liu
  • 1,070
  • 11
  • 30