WinDbg Javascript extensibility and scripting

Hey everyone,

I wanted to drop an email to this list about a big addition to WinDbg that just came out as part of the SDK Insider preview, JavaScript scriptability and extensibility. We posted a blog post at https://blogs.msdn.microsoft.com/windbg/2016/10/27/new-insider-sdk-and-javascript-extensibility/

As well as a set of MSDN docs:
JavaScript Debugger Scripting ? https://msdn.microsoft.com/library/windows/hardware/3442E2C4-4054-4698-B7FB-8FE19D26C171.aspx
JavaScript Debugger Example Scripts ? https://msdn.microsoft.com/library/windows/hardware/F477430B-10C7-4039-9C5F-25556C306643.aspx
Native Debugger Objects in JavaScript Extensions ? https://msdn.microsoft.com/library/windows/hardware/A8E12564-D083-43A7-920E-22C4D627FEE8.aspx

Myself and a few of our devs will be lurking around for the next week or so to answer and questions or comments!

-Andy Luhrs
@aluhrs13

will this extension work in win 7 ? i just grabbed the standalone
debugging tools and it seems there is no jsprovider.dll in the package
didn’t check in a winX machine and didn’t go look for the insider too

just downloaded the sdksetup.exe and installed only debugging tools
from it to test

though i see the new Scripts option in Debugger.State

i cant seem to load the jsprovider.dll

and .scriptproviders displays only natvis and no js

kd> dx Debugger.State
Debugger.State
DebuggerVariables
PseudoRegisters
Scripts
UserVariables
kd> dx -r1 Debugger.State.@“Scripts”
Debugger.State.@“Scripts”
kd> dx -r1 Debugger.State.@“Scripts”
Debugger.State.@“Scripts”

kd> .scriptproviders
Available Script Providers:
NatVis (extension ‘.NatVis’)

kd> .shell -ci “version” grep -i version

Windows 7 Kernel Version 7601 (Service Pack 1) UP Free x86 compatible

Microsoft (R) Windows Debugger Version 10.0.14321.1024 X86 <------
this version

DIA version: 40116
.shell: Process exited

kd> .load jsprovider.dll
The call to LoadLibrary(jsprovider.dll) failed, Win32 error 0n2
“The system cannot find the file specified.”
Please check your debugger configuration and/or network access.

kd> .shell -ci “.echo foo” dir /s j*

Directory of E:\windjs\wdbg\Debuggers\x86\winext

07/28/2016 08:01 AM 50,368 jscript9diagdump.dll
1 File(s) 50,368 bytes

Total Files Listed:
1 File(s) 50,368 bytes

On 10/28/16, xxxxx@microsoft.com wrote:
> Hey everyone,
>
> I wanted to drop an email to this list about a big addition to WinDbg that
> just came out as part of the SDK Insider preview, JavaScript scriptability
> and extensibility. We posted a blog post at
> https://blogs.msdn.microsoft.com/windbg/2016/10/27/new-insider-sdk-and-javascript-extensibility/
>
> As well as a set of MSDN docs:
> JavaScript Debugger Scripting ?
> https://msdn.microsoft.com/library/windows/hardware/3442E2C4-4054-4698-B7FB-8FE19D26C171.aspx
> JavaScript Debugger Example Scripts ?
> https://msdn.microsoft.com/library/windows/hardware/F477430B-10C7-4039-9C5F-25556C306643.aspx
> Native Debugger Objects in JavaScript Extensions ?
> https://msdn.microsoft.com/library/windows/hardware/A8E12564-D083-43A7-920E-22C4D627FEE8.aspx
>
> Myself and a few of our devs will be lurking around for the next week or so
> to answer and questions or comments!
>
> -Andy Luhrs
> @aluhrs13
>
> —
> WINDBG is sponsored by OSR
>
> OSR is hiring!! Info at http://www.osr.com/careers
>
>
> MONTHLY seminars on crash dump analysis, WDF, Windows internals and software
> drivers!
> Details at http:
>
> To unsubscribe, visit the List Server section of OSR Online at
> http:
></http:></http:>

ok followup it seems to work nicely with the insider version

it only sucks to download 800 odd mbs to install 300 odd mbs to use
0.5 mb executable

dx @$foo = Debugger.Utility.Control.ExecuteCommand(“lm vm windbg”)

kd> dx @$foo[3]
@$foo[3] : Image path: E:\windjs\wdbg\Debuggers\x86\windbg.exe
Length : 0x37
kd> dx @$foo[8]
@$foo[8] : ImageSize: 00091000
Length : 0x1e

kd> dx @$foo = Debugger.Utility.Control.ExecuteCommand(“.chain”)[3]
@$foo = Debugger.Utility.Control.ExecuteCommand(“.chain”)[3] :
jsprovider.dll: image 10.0.14951.1001, API 0.0.0, built Sat Oct 15
17:50:07 2016

kd> .shell -ci “version” grep -i version
Windows 7 Kernel Version 7601 (Service Pack 1) UP Free x86 compatible
Microsoft (R) Windows Debugger Version 10.0.14951.1001 X86
DIA version: 23917
.shell: Process exited
kd> .load jsprovider.dll
kd> .scriptproviders
Available Script Providers:
NatVis (extension ‘.NatVis’)
JavaScript (extension ‘.js’)
kd> dx Debugger.State.Scripts
Debugger.State.Scripts
kd> dx Debugger.Utility.Control.ExecuteCommand(“u”)
Debugger.Utility.Control.ExecuteCommand(“u”)
[0x0] : LiveKdD+0x7508:
[0x1] : acf1a508 85c0 test eax,eax
[0x2] : acf1a50a 7420 je LiveKdD+0x752c
(acf1a52c)
[0x3] : acf1a50c 51 push ecx
[0x4] : acf1a50d ff7524 push dword ptr [ebp+24h]
[0x5] : acf1a510 ff7520 push dword ptr [ebp+20h]
[0x6] : acf1a513 ff751c push dword ptr [ebp+1Ch]
[0x7] : acf1a516 ff7518 push dword ptr [ebp+18h]
[0x8] : acf1a519 ff7514 push dword ptr [ebp+14h]

On 11/6/16, raj r wrote:
> will this extension work in win 7 ? i just grabbed the standalone
> debugging tools and it seems there is no jsprovider.dll in the package
> didn’t check in a winX machine and didn’t go look for the insider too
>
> just downloaded the sdksetup.exe and installed only debugging tools
> from it to test
>
> though i see the new Scripts option in Debugger.State
>
> i cant seem to load the jsprovider.dll
>
> and .scriptproviders displays only natvis and no js
>
> kd> dx Debugger.State
> Debugger.State
> DebuggerVariables
> PseudoRegisters
> Scripts
> UserVariables
> kd> dx -r1 Debugger.State.@“Scripts”
> Debugger.State.@“Scripts”
> kd> dx -r1 Debugger.State.@“Scripts”
> Debugger.State.@“Scripts”
>
>
> kd> .scriptproviders
> Available Script Providers:
> NatVis (extension ‘.NatVis’)
>
>
> kd> .shell -ci “version” grep -i version
>
> Windows 7 Kernel Version 7601 (Service Pack 1) UP Free x86 compatible
>
> Microsoft (R) Windows Debugger Version 10.0.14321.1024 X86 <------
> this version
>
> DIA version: 40116
> .shell: Process exited
>
> kd> .load jsprovider.dll
> The call to LoadLibrary(jsprovider.dll) failed, Win32 error 0n2
> “The system cannot find the file specified.”
> Please check your debugger configuration and/or network access.
>
>
> kd> .shell -ci “.echo foo” dir /s j*
>
> Directory of E:\windjs\wdbg\Debuggers\x86\winext
>
> 07/28/2016 08:01 AM 50,368 jscript9diagdump.dll
> 1 File(s) 50,368 bytes
>
> Total Files Listed:
> 1 File(s) 50,368 bytes
>
>
> On 10/28/16, xxxxx@microsoft.com wrote:
>> Hey everyone,
>>
>> I wanted to drop an email to this list about a big addition to WinDbg
>> that
>> just came out as part of the SDK Insider preview, JavaScript
>> scriptability
>> and extensibility. We posted a blog post at
>> https://blogs.msdn.microsoft.com/windbg/2016/10/27/new-insider-sdk-and-javascript-extensibility/
>>
>> As well as a set of MSDN docs:
>> JavaScript Debugger Scripting ?
>> https://msdn.microsoft.com/library/windows/hardware/3442E2C4-4054-4698-B7FB-8FE19D26C171.aspx
>> JavaScript Debugger Example Scripts ?
>> https://msdn.microsoft.com/library/windows/hardware/F477430B-10C7-4039-9C5F-25556C306643.aspx
>> Native Debugger Objects in JavaScript Extensions ?
>> https://msdn.microsoft.com/library/windows/hardware/A8E12564-D083-43A7-920E-22C4D627FEE8.aspx
>>
>> Myself and a few of our devs will be lurking around for the next week or
>> so
>> to answer and questions or comments!
>>
>> -Andy Luhrs
>> @aluhrs13
>>
>> —
>> WINDBG is sponsored by OSR
>>
>> OSR is hiring!! Info at http://www.osr.com/careers
>>
>>
>> MONTHLY seminars on crash dump analysis, WDF, Windows internals and
>> software
>> drivers!
>> Details at http:
>>
>> To unsubscribe, visit the List Server section of OSR Online at
>> http:
>>
></http:></http:>

following up again

this still seems to lack assignability

can i assign and use the output into some thing else or is it just
another display only thingie

for example how could i theoratically do this bizzare thing

kd> dx @$foo[8]

@$foo[8] : ImageSize: 00091000
Length : 0x1e

kd> $$ i want to multiply the size of module by pi() and make an invention

kd> ?? @$foo[8] * 3.1415

Bad register error at ‘@$foo[8] * 3.1415’

kd> ?? @foo[8] * 3.1415

Bad register error at ‘@foo[8] * 3.1415’

kd> ?? dx @foo[8] * 3.1415

i mean something like this

kd> dx @$foo[8].Substring(25)
@$foo[8].Substring(25) : 91000
Length : 0x5

kd> $$ maybe strtoul( dx magic incantation here , , 0y0) [fifth bit]
== pae enabled ? “eureaka” : “rucraka”

On 11/6/16, raj r wrote:
> ok followup it seems to work nicely with the insider version
>
> it only sucks to download 800 odd mbs to install 300 odd mbs to use
> 0.5 mb executable
>
> dx @$foo = Debugger.Utility.Control.ExecuteCommand(“lm vm windbg”)
>
> kd> dx @$foo[3]
> @$foo[3] : Image path: E:\windjs\wdbg\Debuggers\x86\windbg.exe
> Length : 0x37
> kd> dx @$foo[8]
> @$foo[8] : ImageSize: 00091000
> Length : 0x1e
>
>
> kd> dx @$foo = Debugger.Utility.Control.ExecuteCommand(“.chain”)[3]
> @$foo = Debugger.Utility.Control.ExecuteCommand(“.chain”)[3] :
> jsprovider.dll: image 10.0.14951.1001, API 0.0.0, built Sat Oct 15
> 17:50:07 2016
>
>
>
>
> kd> .shell -ci “version” grep -i version
> Windows 7 Kernel Version 7601 (Service Pack 1) UP Free x86 compatible
> Microsoft (R) Windows Debugger Version 10.0.14951.1001 X86
> DIA version: 23917
> .shell: Process exited
> kd> .load jsprovider.dll
> kd> .scriptproviders
> Available Script Providers:
> NatVis (extension ‘.NatVis’)
> JavaScript (extension ‘.js’)
> kd> dx Debugger.State.Scripts
> Debugger.State.Scripts
> kd> dx Debugger.Utility.Control.ExecuteCommand(“u”)
> Debugger.Utility.Control.ExecuteCommand(“u”)
> [0x0] : LiveKdD+0x7508:
> [0x1] : acf1a508 85c0 test eax,eax
> [0x2] : acf1a50a 7420 je LiveKdD+0x752c
> (acf1a52c)
> [0x3] : acf1a50c 51 push ecx
> [0x4] : acf1a50d ff7524 push dword ptr [ebp+24h]
> [0x5] : acf1a510 ff7520 push dword ptr [ebp+20h]
> [0x6] : acf1a513 ff751c push dword ptr [ebp+1Ch]
> [0x7] : acf1a516 ff7518 push dword ptr [ebp+18h]
> [0x8] : acf1a519 ff7514 push dword ptr [ebp+14h]
>
>
> On 11/6/16, raj r wrote:
>> will this extension work in win 7 ? i just grabbed the standalone
>> debugging tools and it seems there is no jsprovider.dll in the package
>> didn’t check in a winX machine and didn’t go look for the insider too
>>
>> just downloaded the sdksetup.exe and installed only debugging tools
>> from it to test
>>
>> though i see the new Scripts option in Debugger.State
>>
>> i cant seem to load the jsprovider.dll
>>
>> and .scriptproviders displays only natvis and no js
>>
>> kd> dx Debugger.State
>> Debugger.State
>> DebuggerVariables
>> PseudoRegisters
>> Scripts
>> UserVariables
>> kd> dx -r1 Debugger.State.@“Scripts”
>> Debugger.State.@“Scripts”
>> kd> dx -r1 Debugger.State.@“Scripts”
>> Debugger.State.@“Scripts”
>>
>>
>> kd> .scriptproviders
>> Available Script Providers:
>> NatVis (extension ‘.NatVis’)
>>
>>
>> kd> .shell -ci “version” grep -i version
>>
>> Windows 7 Kernel Version 7601 (Service Pack 1) UP Free x86 compatible
>>
>> Microsoft (R) Windows Debugger Version 10.0.14321.1024 X86 <------
>> this version
>>
>> DIA version: 40116
>> .shell: Process exited
>>
>> kd> .load jsprovider.dll
>> The call to LoadLibrary(jsprovider.dll) failed, Win32 error 0n2
>> “The system cannot find the file specified.”
>> Please check your debugger configuration and/or network access.
>>
>>
>> kd> .shell -ci “.echo foo” dir /s j*
>>
>> Directory of E:\windjs\wdbg\Debuggers\x86\winext
>>
>> 07/28/2016 08:01 AM 50,368 jscript9diagdump.dll
>> 1 File(s) 50,368 bytes
>>
>> Total Files Listed:
>> 1 File(s) 50,368 bytes
>>
>>
>> On 10/28/16, xxxxx@microsoft.com wrote:
>>> Hey everyone,
>>>
>>> I wanted to drop an email to this list about a big addition to WinDbg
>>> that
>>> just came out as part of the SDK Insider preview, JavaScript
>>> scriptability
>>> and extensibility. We posted a blog post at
>>> https://blogs.msdn.microsoft.com/windbg/2016/10/27/new-insider-sdk-and-javascript-extensibility/
>>>
>>> As well as a set of MSDN docs:
>>> JavaScript Debugger Scripting ?
>>> https://msdn.microsoft.com/library/windows/hardware/3442E2C4-4054-4698-B7FB-8FE19D26C171.aspx
>>> JavaScript Debugger Example Scripts ?
>>> https://msdn.microsoft.com/library/windows/hardware/F477430B-10C7-4039-9C5F-25556C306643.aspx
>>> Native Debugger Objects in JavaScript Extensions ?
>>> https://msdn.microsoft.com/library/windows/hardware/A8E12564-D083-43A7-920E-22C4D627FEE8.aspx
>>>
>>> Myself and a few of our devs will be lurking around for the next week or
>>> so
>>> to answer and questions or comments!
>>>
>>> -Andy Luhrs
>>> @aluhrs13
>>>
>>> —
>>> WINDBG is sponsored by OSR
>>>
>>> OSR is hiring!! Info at http://www.osr.com/careers
>>>
>>>
>>> MONTHLY seminars on crash dump analysis, WDF, Windows internals and
>>> software
>>> drivers!
>>> Details at http:
>>>
>>> To unsubscribe, visit the List Server section of OSR Online at
>>> http:
>>>
>>
></http:></http:>

First, the JavaScript and other functionality is only available in the new expression evaluator (this means ‘dx’). Yes – the variable aliases we let you create (e.g.: @$foo below) are only usable in ‘dx’. You can alias the old EE ‘??’ to ‘dx’ through a setting(.settings set Input.UseExtensionEvaluatorForCpp=true). This is why all of the ‘??’ you have fail.

The output absolutely can be used somewhere else (that uses the new EE – most of the commands in the debugger still rely on the old EE). Your@$foo below is a string. That string can be utilized in a DX expression, passed to a JavaScript function, etc… There isn’t an intrinsic wcstoul function in the new EE. Only the following intrinsics exist

  • strlen / wcslen
  • strnlen / wcsnlen
  • strcmp / wcscmp
  • stricmp / wcsicmp
  • strncmp / wcsncmp
  • strnicmp / wcsnicmp
  • strchr / wcschr
  • strstr / wcsstr
  • stricmp / wcsicmp
  • strcmpi
  • WindowsGetStringLen
  • WindowsGetStringRawBuffer
  • __log2
  • __iserror
  • memcmp / wmemcmp
  • memicmp
  • memchr / wmemchr
  • __findnonnull

You can write a conversion in JavaScript and access it in the EE very quickly:

function fromHex(str)
{
return host.parseInt64(str, 16);
}

.scriptload that… and you can do something like the following example:

0:000> dx @$foo=“ImageSize: 00091000”
@$foo=“ImageSize: 00091000” : ImageSize: 00091000
Length : 0x1a
0:000> .load jsprovider.dll
0:000> .scriptload g:\junk\conv.js
JavaScript script successfully loaded from ‘g:\junk\conv.js’
0:000> dx @$foo.Substring(18)
@$foo.Substring(18) : 00091000
Length : 0x8
0:000> dx @$scriptContents.fromHex(@$foo.Substring(18))
@$scriptContents.fromHex(@$foo.Substring(18)) : 0x91000 0:000> dx @$scriptContents.fromHex(@$foo.Substring(18))*3.1415
@$scriptContents.fromHex(@$foo.Substring(18))*3.1415 : 1865799.680000

Thank You Andy Luhrs ,

That Was a Wonderful reply explaining exactly with details and demo of
what was asked for

thanks for multiplying module size by pi()

yeah it works great too as explained

but is the multiplied result assignable to a pseudo register

say i need to do something like this (the #defs are literally
substiuted in windbg cmdwindow)

#define pint64 = “@$scriptContents.host.parseInt64”
#define argum =
“@$scriptContents.host.namespace.Debugger.Utility.Control.ExecuteCommand(“lm
vm windbg*”)[9].Substring(18),16”
0:000> ?? pint64(argum) * 3.1415
pint64(argum) * 3.1415 : 1865799.680000

0:000> .settings set Input.UseExtensionEvaluatorForCpp = false
Debugger.Settings.Input.UseExtensionEvaluatorForCpp = false : false

0:000> ?? pint64(argum) * 3.1415
Bad register error at 'pint64(argum) * 3.1415 ’

0:000> dx pint64(argum) * 3.1415
pint64(argum) * 3.1415 : 1865799.680000

0:000> r $t0 = pint64(argum) * 3.1415
Bad register error at 'pint64(argum) * 3.1415

0:000> r? $t0 = pint64(argum) * 3.1415
Bad register error at 'pint64(argum) * 3.1415 ’

0:000> .settings set Input.UseExtensionEvaluatorForCpp = true
Debugger.Settings.Input.UseExtensionEvaluatorForCpp = true : true

0:000> r $t0 = pint64(argum) * 3.1415
Bad register error at 'pint64(argum) * 3.1415 ’

0:000> r? $t0 = pint64(argum) * 3.1415
Bad register error at 'pint64(argum) * 3.1415 ’

well it seems i can do another level of dxing like

dx @$blah = @$scriptContents.host.parseInt64(@$scriptContents.host.namespace.Debugger.Utility.Control.ExecuteCommand(“lm
vm windbg*”)[9].Substring(18) , 16 ) * 3.1415

0:000> ?? @$blah
@$blah : 1865799.680000
0:000> ?? @$blah.ToDisplayString()
@$blah.ToDisplayString() : 1865799.680000
Length : 0xe
0:000> ?? @$blah / 0x91000
@$blah / 0x91000 : 3.141500

is this how this must be done by making another uservariable ?

well that sounds good actually i can have descriptive variables
instead of @$t1 and isnt limited to 19 vars atmost then

now i thought instead of Fromhex() i could try using the
host.ParseInt64() directly ( that is without writing a foo.js and
.scriptloading it

didnt find out how to do that

so i loaded an emply foo.js thinking if
Debugger.State.Script.foo.host will magically become visible but boom
windbg crashes

no symbol file exists in the symbol server

*** ERROR: Symbol file could not be found. Defaulted to export
symbols for E:\windjs\wdbg\Debuggers\x86\dbgeng.dll -

so here is a symbol less stack trace of the crash

0:001> kb

ChildEBP RetAddr Args to Child

WARNING: Frame IP not in any known module. Following frames may be wrong.
00 0146e1d0 60bb9205 02a340c8 00000000 6e2ff13a 0x0
01 0146e1e4 60d0f766 6e2ff4be 00164da8 0146e5ec dbgeng+0x139205
02 0146e460 60c02799 0146e5ec 00000000 00000000 dbgeng!Ordinal327+0x145396
03 0146e47c 60c08fe0 60ec924c 00164da8 00000009 dbgeng!Ordinal327+0x383c9
04 0146e49c 60c7f7db 6e2ff5fa 00000000 00000000 dbgeng!Ordinal327+0x3ec10
05 0146e524 60c8037f 6e2ff5a2 00164da8 00000001 dbgeng!Ordinal327+0xb540b
06 0146e57c 60bd317a 00000000 6e2ff93a 00000000 dbgeng!Ordinal327+0xb5faf
07 0146e9e4 60bd3338 0000000a 00000000 6e2ffaf6 dbgeng!Ordinal327+0x8daa
08 0146ea28 011743ba 00164db0 00000001 0146ee08 dbgeng!Ordinal327+0x8f68
09 0146ede4 01174841 00000000 00000008 0146fd00 windbg+0x243ba
0a 0146fe00 01176a60 6e24bc92 00000000 00000000 windbg+0x24841
0b 0146fe4c 76ac3c45 00000000 0146fe98 772937f5 windbg+0x26a60
0c 0146fe58 772937f5 00000000 77be04d4 00000000 kernel32!BaseThreadInitThunk+0xe
0d 0146fe98 772937c8 011764f0 00000000 00000000 ntdll!__RtlUserThreadStart+0x70
0e 0146feb0 00000000 011764f0 00000000 00000000 ntdll!_RtlUserThreadStart+0x1b

EXCEPTION_RECORD: (.exr -1)
ExceptionAddress: 00000000
ExceptionCode: c0000005 (Access violation)
ExceptionFlags: 00000000
NumberParameters: 2
Parameter[0]: 00000008
Parameter[1]: 00000000
Attempt to execute non-executable address 00000000

FOLLOWUP_IP:
dbgeng+139205
60bb9205 5e pop esi

FAILED_INSTRUCTION_ADDRESS:
+0
00000000 ?? ???

BUGCHECK_STR: SOFTWARE_NX_FAULT_NULL

LAST_CONTROL_TRANSFER: from 60bb9205 to 00000000

the debugee printed successfully loaded foo.js so the crash happens
after the Out() somewhere

the disassembly is from a second crash so Rvas will match not base address

0:001> ub @$ra
dbgeng+0x1391f1:
60c091f1 832100 and dword ptr [ecx],0
60c091f4 8b02 mov eax,dword ptr [edx]
60c091f6 56 push esi
60c091f7 52 push edx
60c091f8 8b7008 mov esi,dword ptr [eax+8]
60c091fb 8bce mov ecx,esi
60c091fd ff157866f660 call dword ptr [dbgeng!Ordinal327+0x34c2a8
(60f66678)]
60c09203 ffd6 call esi

0:001> u @$ra l3
dbgeng+0x139205:
60c09205 5e pop esi
60c09206 8b4dfc mov ecx,dword ptr [ebp-4]
60c09209 33cd xor ecx,ebp

0:001> ?? (bool)@@masm(poi(@edx) == @eax)
bool true

registers & disasm match some vtable is null it seems

0:001> dd @eax l4
02996a90 001f00c4 0261c588 00000000 00000000

0:001> r
eax=02996a90 ebx=00000000 ecx=00000000 edx=0261c588 esi=00000000 edi=029c9944
eip=00000000 esp=0216dbc4 ebp=0216dbd4 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010246
00000000 ?? ???

0:001> uf poi(60f66678)
dbgeng+0x11fcd0:
60befcd0 c3 ret

0:001> lm a 60c09203
Browse full module list
start end module name
60ad0000 60fbe000 dbgeng (export symbols)
E:\windjs\wdbg\Debuggers\x86\dbgeng.dll

On 11/8/16, xxxxx@microsoft.com wrote:
> First, the JavaScript and other functionality is only available in the new
> expression evaluator (this means ‘dx’). Yes – the variable aliases we let
> you create (e.g.: @$foo below) are only usable in ‘dx’. You can alias the
> old EE ‘??’ to ‘dx’ through a setting(.settings set
> Input.UseExtensionEvaluatorForCpp=true). This is why all of the ‘??’ you
> have fail.
>
> The output absolutely can be used somewhere else (that uses the new EE –
> most of the commands in the debugger still rely on the old EE). Your@$foo
> below is a string. That string can be utilized in a DX expression, passed
> to a JavaScript function, etc… There isn’t an intrinsic wcstoul function
> in the new EE. Only the following intrinsics exist
>
> - strlen / wcslen
> - strnlen / wcsnlen
> - strcmp / wcscmp
> - stricmp / wcsicmp
> - strncmp / wcsncmp
> - strnicmp / wcsnicmp
> - strchr / wcschr
> - strstr / wcsstr
> - stricmp / wcsicmp
> - strcmpi
> - WindowsGetStringLen
> - WindowsGetStringRawBuffer
> - log2
> -
iserror
> - memcmp / wmemcmp
> - memicmp
> - memchr / wmemchr
> - __findnonnull
>
> You can write a conversion in JavaScript and access it in the EE very
> quickly:
>
> function fromHex(str)
> {
> return host.parseInt64(str, 16);
> }
>
> .scriptload that… and you can do something like the following example:
>
> 0:000> dx @$foo=“ImageSize: 00091000”
> @$foo=“ImageSize: 00091000” : ImageSize: 00091000
> Length : 0x1a
> 0:000> .load jsprovider.dll
> 0:000> .scriptload g:\junk\conv.js
> JavaScript script successfully loaded from ‘g:\junk\conv.js’
> 0:000> dx @$foo.Substring(18)
> @$foo.Substring(18) : 00091000
> Length : 0x8
> 0:000> dx @$scriptContents.fromHex(@$foo.Substring(18))
> @$scriptContents.fromHex(@$foo.Substring(18)) : 0x91000 0:000> dx
> @$scriptContents.fromHex(@$foo.Substring(18))*3.1415
> @$scriptContents.fromHex(@$foo.Substring(18))*3.1415 : 1865799.680000
>
>
> —
> WINDBG is sponsored by OSR
>
> OSR is hiring!! Info at http://www.osr.com/careers
>
>
> MONTHLY seminars on crash dump analysis, WDF, Windows internals and software
> drivers!
> Details at http:
>
> To unsubscribe, visit the List Server section of OSR Online at
> http:
></http:></http:>

i re read the post and it seems i missed this point while editing the post

i actually was trying to assign the multiplied value to a pseudo
Register using this
prior to trying uservariable post failure of r @$t0 tests

0:000> dx Debugger.State.PseudoRegisters.Temporaries.t0 =
@$scriptContents.host.parseInt64(@$scriptContents.host.namespace.Debugger.Utility.Control.ExecuteCommand(“lm
vm windbg*”)[9].Substring(18) , 16 ) * 3.1415

Error: Not implemented (0x80004001) <-------------------

and i got it assigned to an uservar afterwards

On 11/8/16, raj r wrote:
> Thank You Andy Luhrs ,
>
> That Was a Wonderful reply explaining exactly with details and demo of
> what was asked for
>
> thanks for multiplying module size by pi()
>
> yeah it works great too as explained
>
> but is the multiplied result assignable to a pseudo register
>
> say i need to do something like this (the #defs are literally
> substiuted in windbg cmdwindow)
>
> #define pint64 = “@$scriptContents.host.parseInt64”
> #define argum =
> “@$scriptContents.host.namespace.Debugger.Utility.Control.ExecuteCommand(“lm
> vm windbg*”)[9].Substring(18),16”
> 0:000> ?? pint64(argum) * 3.1415
> pint64(argum) * 3.1415 : 1865799.680000
>
> 0:000> .settings set Input.UseExtensionEvaluatorForCpp = false
> Debugger.Settings.Input.UseExtensionEvaluatorForCpp = false : false
>
> 0:000> ?? pint64(argum) * 3.1415
> Bad register error at 'pint64(argum) * 3.1415 '
>
> 0:000> dx pint64(argum) * 3.1415
> pint64(argum) * 3.1415 : 1865799.680000
>
> 0:000> r $t0 = pint64(argum) * 3.1415
> Bad register error at 'pint64(argum) * 3.1415
> '
> 0:000> r? $t0 = pint64(argum) * 3.1415
> Bad register error at 'pint64(argum) * 3.1415 '
>
> 0:000> .settings set Input.UseExtensionEvaluatorForCpp = true
> Debugger.Settings.Input.UseExtensionEvaluatorForCpp = true : true
>
> 0:000> r $t0 = pint64(argum) * 3.1415
> Bad register error at 'pint64(argum) * 3.1415 '
>
> 0:000> r? $t0 = pint64(argum) * 3.1415
> Bad register error at 'pint64(argum) * 3.1415 '
>
>
> well it seems i can do another level of dxing like
>
> dx @$blah =
> @$scriptContents.host.parseInt64(@$scriptContents.host.namespace.Debugger.Utility.Control.ExecuteCommand(“lm
> vm windbg*”)[9].Substring(18) , 16 ) * 3.1415
>
>
> 0:000> ?? @$blah
> @$blah : 1865799.680000
> 0:000> ?? @$blah.ToDisplayString()
> @$blah.ToDisplayString() : 1865799.680000
> Length : 0xe
> 0:000> ?? @$blah / 0x91000
> @$blah / 0x91000 : 3.141500
>
>
> is this how this must be done by making another uservariable ?
>
> well that sounds good actually i can have descriptive variables
> instead of @$t1 and isnt limited to 19 vars atmost then
>
>
>
>
>
> now i thought instead of Fromhex() i could try using the
> host.ParseInt64() directly ( that is without writing a foo.js and
> .scriptloading it
>
> didnt find out how to do that
>
> so i loaded an emply foo.js thinking if
> Debugger.State.Script.foo.host will magically become visible but boom
> windbg crashes
>
> no symbol file exists in the symbol server
>
> *** ERROR: Symbol file could not be found. Defaulted to export
> symbols for E:\windjs\wdbg\Debuggers\x86\dbgeng.dll -
>
>
> so here is a symbol less stack trace of the crash
>
> 0:001> kb
> # ChildEBP RetAddr Args to Child
> WARNING: Frame IP not in any known module. Following frames may be wrong.
> 00 0146e1d0 60bb9205 02a340c8 00000000 6e2ff13a 0x0
> 01 0146e1e4 60d0f766 6e2ff4be 00164da8 0146e5ec dbgeng+0x139205
> 02 0146e460 60c02799 0146e5ec 00000000 00000000 dbgeng!Ordinal327+0x145396
> 03 0146e47c 60c08fe0 60ec924c 00164da8 00000009 dbgeng!Ordinal327+0x383c9
> 04 0146e49c 60c7f7db 6e2ff5fa 00000000 00000000 dbgeng!Ordinal327+0x3ec10
> 05 0146e524 60c8037f 6e2ff5a2 00164da8 00000001 dbgeng!Ordinal327+0xb540b
> 06 0146e57c 60bd317a 00000000 6e2ff93a 00000000 dbgeng!Ordinal327+0xb5faf
> 07 0146e9e4 60bd3338 0000000a 00000000 6e2ffaf6 dbgeng!Ordinal327+0x8daa
> 08 0146ea28 011743ba 00164db0 00000001 0146ee08 dbgeng!Ordinal327+0x8f68
> 09 0146ede4 01174841 00000000 00000008 0146fd00 windbg+0x243ba
> 0a 0146fe00 01176a60 6e24bc92 00000000 00000000 windbg+0x24841
> 0b 0146fe4c 76ac3c45 00000000 0146fe98 772937f5 windbg+0x26a60
> 0c 0146fe58 772937f5 00000000 77be04d4 00000000
> kernel32!BaseThreadInitThunk+0xe
> 0d 0146fe98 772937c8 011764f0 00000000 00000000
> ntdll!__RtlUserThreadStart+0x70
> 0e 0146feb0 00000000 011764f0 00000000 00000000
> ntdll!_RtlUserThreadStart+0x1b
>
>
>
> EXCEPTION_RECORD: (.exr -1)
> ExceptionAddress: 00000000
> ExceptionCode: c0000005 (Access violation)
> ExceptionFlags: 00000000
> NumberParameters: 2
> Parameter[0]: 00000008
> Parameter[1]: 00000000
> Attempt to execute non-executable address 00000000
>
>
> FOLLOWUP_IP:
> dbgeng+139205
> 60bb9205 5e pop esi
>
> FAILED_INSTRUCTION_ADDRESS:
> +0
> 00000000 ?? ???
>
> BUGCHECK_STR: SOFTWARE_NX_FAULT_NULL
>
>
> LAST_CONTROL_TRANSFER: from 60bb9205 to 00000000
>
> the debugee printed successfully loaded foo.js so the crash happens
> after the Out() somewhere
>
> the disassembly is from a second crash so Rvas will match not base address
>
>
> 0:001> ub @$ra
> dbgeng+0x1391f1:
> 60c091f1 832100 and dword ptr [ecx],0
> 60c091f4 8b02 mov eax,dword ptr [edx]
> 60c091f6 56 push esi
> 60c091f7 52 push edx
> 60c091f8 8b7008 mov esi,dword ptr [eax+8]
> 60c091fb 8bce mov ecx,esi
> 60c091fd ff157866f660 call dword ptr [dbgeng!Ordinal327+0x34c2a8
> (60f66678)]
> 60c09203 ffd6 call esi
>
>
> 0:001> u @$ra l3
> dbgeng+0x139205:
> 60c09205 5e pop esi
> 60c09206 8b4dfc mov ecx,dword ptr [ebp-4]
> 60c09209 33cd xor ecx,ebp
>
>
> 0:001> ?? (bool)@@masm(poi(@edx) == @eax)
> bool true
>
> registers & disasm match some vtable is null it seems
>
> 0:001> dd @eax l4
> 02996a90 001f00c4 0261c588 00000000 00000000
>
> 0:001> r
> eax=02996a90 ebx=00000000 ecx=00000000 edx=0261c588 esi=00000000
> edi=029c9944
> eip=00000000 esp=0216dbc4 ebp=0216dbd4 iopl=0 nv up ei pl zr na pe
> nc
> cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000
> efl=00010246
> 00000000 ?? ???
>
>
> 0:001> uf poi(60f66678)
> dbgeng+0x11fcd0:
> 60befcd0 c3 ret
>
>
> 0:001> lm a 60c09203
> Browse full module list
> start end module name
> 60ad0000 60fbe000 dbgeng (export symbols)
> E:\windjs\wdbg\Debuggers\x86\dbgeng.dll
>
>
>
>
> On 11/8/16, xxxxx@microsoft.com wrote:
>> First, the JavaScript and other functionality is only available in the
>> new
>> expression evaluator (this means ‘dx’). Yes – the variable aliases we
>> let
>> you create (e.g.: @$foo below) are only usable in ‘dx’. You can alias
>> the
>> old EE ‘??’ to ‘dx’ through a setting(.settings set
>> Input.UseExtensionEvaluatorForCpp=true). This is why all of the ‘??’ you
>> have fail.
>>
>> The output absolutely can be used somewhere else (that uses the new EE –
>> most of the commands in the debugger still rely on the old EE).
>> Your@$foo
>> below is a string. That string can be utilized in a DX expression,
>> passed
>> to a JavaScript function, etc… There isn’t an intrinsic wcstoul
>> function
>> in the new EE. Only the following intrinsics exist
>>
>> - strlen / wcslen
>> - strnlen / wcsnlen
>> - strcmp / wcscmp
>> - stricmp / wcsicmp
>> - strncmp / wcsncmp
>> - strnicmp / wcsnicmp
>> - strchr / wcschr
>> - strstr / wcsstr
>> - stricmp / wcsicmp
>> - strcmpi
>> - WindowsGetStringLen
>> - WindowsGetStringRawBuffer
>> -__log2
>> - iserror
>> - memcmp / wmemcmp
>> - memicmp
>> - memchr / wmemchr
>> -
findnonnull
>>
>> You can write a conversion in JavaScript and access it in the EE very
>> quickly:
>>
>> function fromHex(str)
>> {
>> return host.parseInt64(str, 16);
>> }
>>
>> .scriptload that… and you can do something like the following example:
>>
>> 0:000> dx @$foo=“ImageSize: 00091000”
>> @$foo=“ImageSize: 00091000” : ImageSize: 00091000
>> Length : 0x1a
>> 0:000> .load jsprovider.dll
>> 0:000> .scriptload g:\junk\conv.js
>> JavaScript script successfully loaded from ‘g:\junk\conv.js’
>> 0:000> dx @$foo.Substring(18)
>> @$foo.Substring(18) : 00091000
>> Length : 0x8
>> 0:000> dx @$scriptContents.fromHex(@$foo.Substring(18))
>> @$scriptContents.fromHex(@$foo.Substring(18)) : 0x91000 0:000> dx
>> @$scriptContents.fromHex(@$foo.Substring(18))*3.1415
>> @$scriptContents.fromHex(@$foo.Substring(18))*3.1415 : 1865799.680000
>>
>>
>> —
>> WINDBG is sponsored by OSR
>>
>> OSR is hiring!! Info at http://www.osr.com/careers
>>
>>
>> MONTHLY seminars on crash dump analysis, WDF, Windows internals and
>> software
>> drivers!
>> Details at http:
>>
>> To unsubscribe, visit the List Server section of OSR Online at
>> http:
>>
></http:></http:>

Some please unsubscibe me please
On 8 Nov 2016 06:07, “raj r” wrote:

> i re read the post and it seems i missed this point while editing the post
>
> i actually was trying to assign the multiplied value to a pseudo
> Register using this
> prior to trying uservariable post failure of r @$t0 tests
>
>
> 0:000> dx Debugger.State.PseudoRegisters.Temporaries.t0 =
> @$scriptContents.host.parseInt64(@$scriptContents.host.namespace.Debugger.
> Utility.Control.ExecuteCommand(“lm
> vm windbg*”)[9].Substring(18) , 16 ) * 3.1415
>
> Error: Not implemented (0x80004001) <-------------------
>
> and i got it assigned to an uservar afterwards
>
>
>
> On 11/8/16, raj r wrote:
> > Thank You Andy Luhrs ,
> >
> > That Was a Wonderful reply explaining exactly with details and demo of
> > what was asked for
> >
> > thanks for multiplying module size by pi()
> >
> > yeah it works great too as explained
> >
> > but is the multiplied result assignable to a pseudo register
> >
> > say i need to do something like this (the #defs are literally
> > substiuted in windbg cmdwindow)
> >
> > #define pint64 = “@$scriptContents.host.parseInt64”
> > #define argum =
> > “@$scriptContents.host.namespace.Debugger.Utility.
> Control.ExecuteCommand(“lm
> > vm windbg*”)[9].Substring(18),16”
> > 0:000> ?? pint64(argum) * 3.1415
> > pint64(argum) * 3.1415 : 1865799.680000
> >
> > 0:000> .settings set Input.UseExtensionEvaluatorForCpp = false
> > Debugger.Settings.Input.UseExtensionEvaluatorForCpp = false : false
> >
> > 0:000> ?? pint64(argum) * 3.1415
> > Bad register error at 'pint64(argum) * 3.1415 '
> >
> > 0:000> dx pint64(argum) * 3.1415
> > pint64(argum) * 3.1415 : 1865799.680000
> >
> > 0:000> r $t0 = pint64(argum) * 3.1415
> > Bad register error at 'pint64(argum) * 3.1415
> > '
> > 0:000> r? $t0 = pint64(argum) * 3.1415
> > Bad register error at 'pint64(argum) * 3.1415 '
> >
> > 0:000> .settings set Input.UseExtensionEvaluatorForCpp = true
> > Debugger.Settings.Input.UseExtensionEvaluatorForCpp = true : true
> >
> > 0:000> r $t0 = pint64(argum) * 3.1415
> > Bad register error at 'pint64(argum) * 3.1415 '
> >
> > 0:000> r? $t0 = pint64(argum) * 3.1415
> > Bad register error at 'pint64(argum) * 3.1415 '
> >
> >
> > well it seems i can do another level of dxing like
> >
> > dx @$blah =
> > @$scriptContents.host.parseInt64(@$scriptContents.
> host.namespace.Debugger.Utility.Control.ExecuteCommand(“lm
> > vm windbg*”)[9].Substring(18) , 16 ) * 3.1415
> >
> >
> > 0:000> ?? @$blah
> > @$blah : 1865799.680000
> > 0:000> ?? @$blah.ToDisplayString()
> > @$blah.ToDisplayString() : 1865799.680000
> > Length : 0xe
> > 0:000> ?? @$blah / 0x91000
> > @$blah / 0x91000 : 3.141500
> >
> >
> > is this how this must be done by making another uservariable ?
> >
> > well that sounds good actually i can have descriptive variables
> > instead of @$t1 and isnt limited to 19 vars atmost then
> >
> >
> >
> >
> >
> > now i thought instead of Fromhex() i could try using the
> > host.ParseInt64() directly ( that is without writing a foo.js and
> > .scriptloading it
> >
> > didnt find out how to do that
> >
> > so i loaded an emply foo.js thinking if
> > Debugger.State.Script.foo.host will magically become visible but boom
> > windbg crashes
> >
> > no symbol file exists in the symbol server
> >
> > *** ERROR: Symbol file could not be found. Defaulted to export
> > symbols for E:\windjs\wdbg\Debuggers\x86\dbgeng.dll -
> >
> >
> > so here is a symbol less stack trace of the crash
> >
> > 0:001> kb
> > # ChildEBP RetAddr Args to Child
> > WARNING: Frame IP not in any known module. Following frames may be wrong.
> > 00 0146e1d0 60bb9205 02a340c8 00000000 6e2ff13a 0x0
> > 01 0146e1e4 60d0f766 6e2ff4be 00164da8 0146e5ec dbgeng+0x139205
> > 02 0146e460 60c02799 0146e5ec 00000000 00000000
> dbgeng!Ordinal327+0x145396
> > 03 0146e47c 60c08fe0 60ec924c 00164da8 00000009 dbgeng!Ordinal327+0x383c9
> > 04 0146e49c 60c7f7db 6e2ff5fa 00000000 00000000 dbgeng!Ordinal327+0x3ec10
> > 05 0146e524 60c8037f 6e2ff5a2 00164da8 00000001 dbgeng!Ordinal327+0xb540b
> > 06 0146e57c 60bd317a 00000000 6e2ff93a 00000000 dbgeng!Ordinal327+0xb5faf
> > 07 0146e9e4 60bd3338 0000000a 00000000 6e2ffaf6 dbgeng!Ordinal327+0x8daa
> > 08 0146ea28 011743ba 00164db0 00000001 0146ee08 dbgeng!Ordinal327+0x8f68
> > 09 0146ede4 01174841 00000000 00000008 0146fd00 windbg+0x243ba
> > 0a 0146fe00 01176a60 6e24bc92 00000000 00000000 windbg+0x24841
> > 0b 0146fe4c 76ac3c45 00000000 0146fe98 772937f5 windbg+0x26a60
> > 0c 0146fe58 772937f5 00000000 77be04d4 00000000
> > kernel32!BaseThreadInitThunk+0xe
> > 0d 0146fe98 772937c8 011764f0 00000000 00000000
> > ntdll!__RtlUserThreadStart+0x70
> > 0e 0146feb0 00000000 011764f0 00000000 00000000
> > ntdll!_RtlUserThreadStart+0x1b
> >
> >
> >
> > EXCEPTION_RECORD: (.exr -1)
> > ExceptionAddress: 00000000
> > ExceptionCode: c0000005 (Access violation)
> > ExceptionFlags: 00000000
> > NumberParameters: 2
> > Parameter[0]: 00000008
> > Parameter[1]: 00000000
> > Attempt to execute non-executable address 00000000
> >
> >
> > FOLLOWUP_IP:
> > dbgeng+139205
> > 60bb9205 5e pop esi
> >
> > FAILED_INSTRUCTION_ADDRESS:
> > +0
> > 00000000 ?? ???
> >
> > BUGCHECK_STR: SOFTWARE_NX_FAULT_NULL
> >
> >
> > LAST_CONTROL_TRANSFER: from 60bb9205 to 00000000
> >
> > the debugee printed successfully loaded foo.js so the crash happens
> > after the Out() somewhere
> >
> > the disassembly is from a second crash so Rvas will match not base
> address
> >
> >
> > 0:001> ub @$ra
> > dbgeng+0x1391f1:
> > 60c091f1 832100 and dword ptr [ecx],0
> > 60c091f4 8b02 mov eax,dword ptr [edx]
> > 60c091f6 56 push esi
> > 60c091f7 52 push edx
> > 60c091f8 8b7008 mov esi,dword ptr [eax+8]
> > 60c091fb 8bce mov ecx,esi
> > 60c091fd ff157866f660 call dword ptr [dbgeng!Ordinal327+0x34c2a8
> > (60f66678)]
> > 60c09203 ffd6 call esi
> >
> >
> > 0:001> u @$ra l3
> > dbgeng+0x139205:
> > 60c09205 5e pop esi
> > 60c09206 8b4dfc mov ecx,dword ptr [ebp-4]
> > 60c09209 33cd xor ecx,ebp
> >
> >
> > 0:001> ?? (bool)@@masm(poi(@edx) == @eax)
> > bool true
> >
> > registers & disasm match some vtable is null it seems
> >
> > 0:001> dd @eax l4
> > 02996a90 001f00c4 0261c588 00000000 00000000
> >
> > 0:001> r
> > eax=02996a90 ebx=00000000 ecx=00000000 edx=0261c588 esi=00000000
> > edi=029c9944
> > eip=00000000 esp=0216dbc4 ebp=0216dbd4 iopl=0 nv up ei pl zr na
> pe
> > nc
> > cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000
> > efl=00010246
> > 00000000 ?? ???
> >
> >
> > 0:001> uf poi(60f66678)
> > dbgeng+0x11fcd0:
> > 60befcd0 c3 ret
> >
> >
> > 0:001> lm a 60c09203
> > Browse full module list
> > start end module name
> > 60ad0000 60fbe000 dbgeng (export symbols)
> > E:\windjs\wdbg\Debuggers\x86\dbgeng.dll
> >
> >
> >
> >
> > On 11/8/16, xxxxx@microsoft.com wrote:
> >> First, the JavaScript and other functionality is only available in the
> >> new
> >> expression evaluator (this means ‘dx’). Yes – the variable aliases we
> >> let
> >> you create (e.g.: @$foo below) are only usable in ‘dx’. You can alias
> >> the
> >> old EE ‘??’ to ‘dx’ through a setting(.settings set
> >> Input.UseExtensionEvaluatorForCpp=true). This is why all of the ‘??’
> you
> >> have fail.
> >>
> >> The output absolutely can be used somewhere else (that uses the new EE
> –
> >> most of the commands in the debugger still rely on the old EE).
> >> Your@$foo
> >> below is a string. That string can be utilized in a DX expression,
> >> passed
> >> to a JavaScript function, etc… There isn’t an intrinsic wcstoul
> >> function
> >> in the new EE. Only the following intrinsics exist
> >>
> >> - strlen / wcslen
> >> - strnlen / wcsnlen
> >> - strcmp / wcscmp
> >> - stricmp / wcsicmp
> >> - strncmp / wcsncmp
> >> - strnicmp / wcsnicmp
> >> - strchr / wcschr
> >> - strstr / wcsstr
> >> - stricmp / wcsicmp
> >> - strcmpi
> >> - WindowsGetStringLen
> >> - WindowsGetStringRawBuffer
> >> -__log2
> >> - iserror
> >> - memcmp / wmemcmp
> >> - memicmp
> >> - memchr / wmemchr
> >> -
findnonnull
> >>
> >> You can write a conversion in JavaScript and access it in the EE very
> >> quickly:
> >>
> >> function fromHex(str)
> >> {
> >> return host.parseInt64(str, 16);
> >> }
> >>
> >> .scriptload that… and you can do something like the following
> example:
> >>
> >> 0:000> dx @$foo=“ImageSize: 00091000”
> >> @$foo=“ImageSize: 00091000” : ImageSize: 00091000
> >> Length : 0x1a
> >> 0:000> .load jsprovider.dll
> >> 0:000> .scriptload g:\junk\conv.js
> >> JavaScript script successfully loaded from ‘g:\junk\conv.js’
> >> 0:000> dx @$foo.Substring(18)
> >> @$foo.Substring(18) : 00091000
> >> Length : 0x8
> >> 0:000> dx @$scriptContents.fromHex(@$foo.Substring(18))
> >> @$scriptContents.fromHex(@$foo.Substring(18)) : 0x91000 0:000> dx
> >> @$scriptContents.fromHex(@$foo.Substring(18))*3.1415
> >> @$scriptContents.fromHex(@$foo.Substring(18))*3.1415 : 1865799.680000
> >>
> >>
> >> —
> >> WINDBG is sponsored by OSR
> >>
> >> OSR is hiring!! Info at http://www.osr.com/careers
> >>
> >>
> >> MONTHLY seminars on crash dump analysis, WDF, Windows internals and
> >> software
> >> drivers!
> >> Details at http:
> >>
> >> To unsubscribe, visit the List Server section of OSR Online at
> >> http:
> >>
> >
>
> —
> WINDBG is sponsored by OSR
>
> OSR is hiring!! Info at http://www.osr.com/careers
>
>
> MONTHLY seminars on crash dump analysis, WDF, Windows internals and
> software drivers!
> Details at http:
>
> To unsubscribe, visit the List Server section of OSR Online at <
> http://www.osronline.com/page.cfm?name=ListServer&gt;
></http:></http:></http:>

is this supposed to work like this or am i doing something wrong ?

i type this in windbg command window

0:000> dx Debugger.Utility.Control.ExecuteCommand(“.fnent
@$ip”).Where(b=>b.Contains(“Off”) == true)

and i get a correct result

Debugger.Utility.Control.ExecuteCommand(“.fnent
@$ip”).Where(b=>b.Contains(“Off”) == true)
[0x0] : OffStart: 000a04ca

so i put this in a foo.js like this load it and execute and it seems
the script cannot retrieve the
same info

0:000> $$ i put this in function trysomething() {
0:000> $$ return
host.namespace.Debugger.Utility.Control.ExecuteCommand(a).Where(b=>b.Contains(“Off”)
== true);
0:000> $$ }

0:000> .scriptlist
Command Loaded Scripts:


0:000> .scriptload foo.js
Loaded foo.js from function initializeScript()
JavaScript script successfully loaded from ‘E:\windjs\wdbg\Debuggers\x86\foo.js’

0:000> dx @$scriptContents.trysomething(“.fnent @$ip”)

the result is not what i was expecting
how can go about this

@$scriptContents.trysomething(“.fnent @$ip”)
[0x0] : Object doesn’t support property or method ‘Contains’
[0x1] : Object doesn’t support property or method ‘Contains’
[0x2] : Object doesn’t support property or method ‘Contains’
[0x3] : Object doesn’t support property or method ‘Contains’
[0x4] : Object doesn’t support property or method ‘Contains’
[0x5] : Object doesn’t support property or method ‘Contains’
[0x6] : Object doesn’t support property or method ‘Contains’
[0x7] : Object doesn’t support property or method ‘Contains’
[0x8] : Object doesn’t support property or method ‘Contains’

if i dont use the filter expression inside the js i can get results like this

i added two more functions in the js as below

host.diagnostics.debugLog(“Loaded foo.js from function initializeScript()\n”);

function trysomething (a) {
return host.namespace.Debugger.Utility.Control.ExecuteCommand(a).Where(b=>b.Contains(“Off”)
== true);
}

function trysomeotherthing (a) {
return host.namespace.Debugger.Utility.Control.ExecuteCommand(a);
}

function trysomeotherthing1 (a) {
return new host.namespace.Debugger.Utility.Control.ExecuteCommand(a);
}

and executed both it appears i can filter here

0:000> .scriptunload foo.js
JavaScript script unloaded from ‘E:\windjs\wdbg\Debuggers\x86\foo.js’

0:000> .scriptlist
Command Loaded Scripts:


0:000> .scriptload foo.js
Loaded foo.js from function initializeScript()
JavaScript script successfully loaded from ‘E:\windjs\wdbg\Debuggers\x86\foo.js’

0:000> dx @$scriptContents.trysomeotherthing(“.fnent @$ip”)
@$scriptContents.trysomeotherthing(“.fnent @$ip”)
[0x0] : Debugger function entry 029311a8 for:
[0x1] : (779104ca) ntdll!LdrpDoDebuggerBreak+0x2c |
(77910515) ntdll!LdrpInitializeApplicationVerifierPackage
[0x2]
[0x3] : OffStart: 000a04ca
[0x4] : ProcSize: 0x46
[0x5] : Prologue: 0xc
[0x6] : Params: 0n0 (0x0 bytes)
[0x7] : Locals: 0n7 (0x1c bytes)
[0x8] : Non-FPO

0:000> dx @$scriptContents.trysomeotherthing1(“.fnent @$ip”)
@$scriptContents.trysomeotherthing1(“.fnent @$ip”)
[0x0] : Debugger function entry 029311a8 for:
[0x1] : (779104ca) ntdll!LdrpDoDebuggerBreak+0x2c |
(77910515) ntdll!LdrpInitializeApplicationVerifierPackage
[0x2]
[0x3] : OffStart: 000a04ca
[0x4] : ProcSize: 0x46
[0x5] : Prologue: 0xc
[0x6] : Params: 0n0 (0x0 bytes)
[0x7] : Locals: 0n7 (0x1c bytes)
[0x8] : Non-FPO

0:000> dx @$scriptContents.trysomeotherthing1(“.fnent
@$ip”).Where(f=>f.Contains(“Off”)==true)
@$scriptContents.trysomeotherthing1(“.fnent
@$ip”).Where(f=>f.Contains(“Off”)==true)
[0x0] : OffStart: 000a04ca

0:000> dx @$scriptContents.trysomeotherthing(“.fnent
@$ip”).Where(f=>f.Contains(“Off”)==true)
@$scriptContents.trysomeotherthing(“.fnent
@$ip”).Where(f=>f.Contains(“Off”)==true)
[0x0] : OffStart: 000a04ca

On 11/8/16, Devendra Baghel wrote:
> Some please unsubscibe me please
> On 8 Nov 2016 06:07, “raj r” wrote:
>
>> i re read the post and it seems i missed this point while editing the
>> post
>>
>> i actually was trying to assign the multiplied value to a pseudo
>> Register using this
>> prior to trying uservariable post failure of r @$t0 tests
>>
>>
>> 0:000> dx Debugger.State.PseudoRegisters.Temporaries.t0 =
>> @$scriptContents.host.parseInt64(@$scriptContents.host.namespace.Debugger.
>> Utility.Control.ExecuteCommand(“lm
>> vm windbg*”)[9].Substring(18) , 16 ) * 3.1415
>>
>> Error: Not implemented (0x80004001) <-------------------
>>
>> and i got it assigned to an uservar afterwards
>>
>>
>>
>> On 11/8/16, raj r wrote:
>> > Thank You Andy Luhrs ,
>> >
>> > That Was a Wonderful reply explaining exactly with details and demo of
>> > what was asked for
>> >
>> > thanks for multiplying module size by pi()
>> >
>> > yeah it works great too as explained
>> >
>> > but is the multiplied result assignable to a pseudo register
>> >
>> > say i need to do something like this (the #defs are literally
>> > substiuted in windbg cmdwindow)
>> >
>> > #define pint64 = “@$scriptContents.host.parseInt64”
>> > #define argum =
>> > “@$scriptContents.host.namespace.Debugger.Utility.
>> Control.ExecuteCommand(“lm
>> > vm windbg*”)[9].Substring(18),16”
>> > 0:000> ?? pint64(argum) * 3.1415
>> > pint64(argum) * 3.1415 : 1865799.680000
>> >
>> > 0:000> .settings set Input.UseExtensionEvaluatorForCpp = false
>> > Debugger.Settings.Input.UseExtensionEvaluatorForCpp = false : false
>> >
>> > 0:000> ?? pint64(argum) * 3.1415
>> > Bad register error at 'pint64(argum) * 3.1415 '
>> >
>> > 0:000> dx pint64(argum) * 3.1415
>> > pint64(argum) * 3.1415 : 1865799.680000
>> >
>> > 0:000> r $t0 = pint64(argum) * 3.1415
>> > Bad register error at 'pint64(argum) * 3.1415
>> > '
>> > 0:000> r? $t0 = pint64(argum) * 3.1415
>> > Bad register error at 'pint64(argum) * 3.1415 '
>> >
>> > 0:000> .settings set Input.UseExtensionEvaluatorForCpp = true
>> > Debugger.Settings.Input.UseExtensionEvaluatorForCpp = true : true
>> >
>> > 0:000> r $t0 = pint64(argum) * 3.1415
>> > Bad register error at 'pint64(argum) * 3.1415 '
>> >
>> > 0:000> r? $t0 = pint64(argum) * 3.1415
>> > Bad register error at 'pint64(argum) * 3.1415 '
>> >
>> >
>> > well it seems i can do another level of dxing like
>> >
>> > dx @$blah =
>> > @$scriptContents.host.parseInt64(@$scriptContents.
>> host.namespace.Debugger.Utility.Control.ExecuteCommand(“lm
>> > vm windbg*”)[9].Substring(18) , 16 ) * 3.1415
>> >
>> >
>> > 0:000> ?? @$blah
>> > @$blah : 1865799.680000
>> > 0:000> ?? @$blah.ToDisplayString()
>> > @$blah.ToDisplayString() : 1865799.680000
>> > Length : 0xe
>> > 0:000> ?? @$blah / 0x91000
>> > @$blah / 0x91000 : 3.141500
>> >
>> >
>> > is this how this must be done by making another uservariable ?
>> >
>> > well that sounds good actually i can have descriptive variables
>> > instead of @$t1 and isnt limited to 19 vars atmost then
>> >
>> >
>> >
>> >
>> >
>> > now i thought instead of Fromhex() i could try using the
>> > host.ParseInt64() directly ( that is without writing a foo.js and
>> > .scriptloading it
>> >
>> > didnt find out how to do that
>> >
>> > so i loaded an emply foo.js thinking if
>> > Debugger.State.Script.foo.host will magically become visible but boom
>> > windbg crashes
>> >
>> > no symbol file exists in the symbol server
>> >
>> > *** ERROR: Symbol file could not be found. Defaulted to export
>> > symbols for E:\windjs\wdbg\Debuggers\x86\dbgeng.dll -
>> >
>> >
>> > so here is a symbol less stack trace of the crash
>> >
>> > 0:001> kb
>> > # ChildEBP RetAddr Args to Child
>> > WARNING: Frame IP not in any known module. Following frames may be
>> > wrong.
>> > 00 0146e1d0 60bb9205 02a340c8 00000000 6e2ff13a 0x0
>> > 01 0146e1e4 60d0f766 6e2ff4be 00164da8 0146e5ec dbgeng+0x139205
>> > 02 0146e460 60c02799 0146e5ec 00000000 00000000
>> dbgeng!Ordinal327+0x145396
>> > 03 0146e47c 60c08fe0 60ec924c 00164da8 00000009
>> > dbgeng!Ordinal327+0x383c9
>> > 04 0146e49c 60c7f7db 6e2ff5fa 00000000 00000000
>> > dbgeng!Ordinal327+0x3ec10
>> > 05 0146e524 60c8037f 6e2ff5a2 00164da8 00000001
>> > dbgeng!Ordinal327+0xb540b
>> > 06 0146e57c 60bd317a 00000000 6e2ff93a 00000000
>> > dbgeng!Ordinal327+0xb5faf
>> > 07 0146e9e4 60bd3338 0000000a 00000000 6e2ffaf6
>> > dbgeng!Ordinal327+0x8daa
>> > 08 0146ea28 011743ba 00164db0 00000001 0146ee08
>> > dbgeng!Ordinal327+0x8f68
>> > 09 0146ede4 01174841 00000000 00000008 0146fd00 windbg+0x243ba
>> > 0a 0146fe00 01176a60 6e24bc92 00000000 00000000 windbg+0x24841
>> > 0b 0146fe4c 76ac3c45 00000000 0146fe98 772937f5 windbg+0x26a60
>> > 0c 0146fe58 772937f5 00000000 77be04d4 00000000
>> > kernel32!BaseThreadInitThunk+0xe
>> > 0d 0146fe98 772937c8 011764f0 00000000 00000000
>> > ntdll!__RtlUserThreadStart+0x70
>> > 0e 0146feb0 00000000 011764f0 00000000 00000000
>> > ntdll!_RtlUserThreadStart+0x1b
>> >
>> >
>> >
>> > EXCEPTION_RECORD: (.exr -1)
>> > ExceptionAddress: 00000000
>> > ExceptionCode: c0000005 (Access violation)
>> > ExceptionFlags: 00000000
>> > NumberParameters: 2
>> > Parameter[0]: 00000008
>> > Parameter[1]: 00000000
>> > Attempt to execute non-executable address 00000000
>> >
>> >
>> > FOLLOWUP_IP:
>> > dbgeng+139205
>> > 60bb9205 5e pop esi
>> >
>> > FAILED_INSTRUCTION_ADDRESS:
>> > +0
>> > 00000000 ?? ???
>> >
>> > BUGCHECK_STR: SOFTWARE_NX_FAULT_NULL
>> >
>> >
>> > LAST_CONTROL_TRANSFER: from 60bb9205 to 00000000
>> >
>> > the debugee printed successfully loaded foo.js so the crash happens
>> > after the Out() somewhere
>> >
>> > the disassembly is from a second crash so Rvas will match not base
>> address
>> >
>> >
>> > 0:001> ub @$ra
>> > dbgeng+0x1391f1:
>> > 60c091f1 832100 and dword ptr [ecx],0
>> > 60c091f4 8b02 mov eax,dword ptr [edx]
>> > 60c091f6 56 push esi
>> > 60c091f7 52 push edx
>> > 60c091f8 8b7008 mov esi,dword ptr [eax+8]
>> > 60c091fb 8bce mov ecx,esi
>> > 60c091fd ff157866f660 call dword ptr [dbgeng!Ordinal327+0x34c2a8
>> > (60f66678)]
>> > 60c09203 ffd6 call esi
>> >
>> >
>> > 0:001> u @$ra l3
>> > dbgeng+0x139205:
>> > 60c09205 5e pop esi
>> > 60c09206 8b4dfc mov ecx,dword ptr [ebp-4]
>> > 60c09209 33cd xor ecx,ebp
>> >
>> >
>> > 0:001> ?? (bool)@@masm(poi(@edx) == @eax)
>> > bool true
>> >
>> > registers & disasm match some vtable is null it seems
>> >
>> > 0:001> dd @eax l4
>> > 02996a90 001f00c4 0261c588 00000000 00000000
>> >
>> > 0:001> r
>> > eax=02996a90 ebx=00000000 ecx=00000000 edx=0261c588 esi=00000000
>> > edi=029c9944
>> > eip=00000000 esp=0216dbc4 ebp=0216dbd4 iopl=0 nv up ei pl zr na
>> pe
>> > nc
>> > cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000
>> > efl=00010246
>> > 00000000 ?? ???
>> >
>> >
>> > 0:001> uf poi(60f66678)
>> > dbgeng+0x11fcd0:
>> > 60befcd0 c3 ret
>> >
>> >
>> > 0:001> lm a 60c09203
>> > Browse full module list
>> > start end module name
>> > 60ad0000 60fbe000 dbgeng (export symbols)
>> > E:\windjs\wdbg\Debuggers\x86\dbgeng.dll
>> >
>> >
>> >
>> >
>> > On 11/8/16, xxxxx@microsoft.com wrote:
>> >> First, the JavaScript and other functionality is only available in the
>> >> new
>> >> expression evaluator (this means ‘dx’). Yes – the variable aliases
>> >> we
>> >> let
>> >> you create (e.g.: @$foo below) are only usable in ‘dx’. You can alias
>> >> the
>> >> old EE ‘??’ to ‘dx’ through a setting(.settings set
>> >> Input.UseExtensionEvaluatorForCpp=true). This is why all of the ‘??’
>> you
>> >> have fail.
>> >>
>> >> The output absolutely can be used somewhere else (that uses the new EE
>> –
>> >> most of the commands in the debugger still rely on the old EE).
>> >> Your@$foo
>> >> below is a string. That string can be utilized in a DX expression,
>> >> passed
>> >> to a JavaScript function, etc… There isn’t an intrinsic wcstoul
>> >> function
>> >> in the new EE. Only the following intrinsics exist
>> >>
>> >> - strlen / wcslen
>> >> - strnlen / wcsnlen
>> >> - strcmp / wcscmp
>> >> - stricmp / wcsicmp
>> >> - strncmp / wcsncmp
>> >> - strnicmp / wcsnicmp
>> >> - strchr / wcschr
>> >> - strstr / wcsstr
>> >> - stricmp / wcsicmp
>> >> - strcmpi
>> >> - WindowsGetStringLen
>> >> - WindowsGetStringRawBuffer
>> >> -__log2
>> >> - iserror
>> >> - memcmp / wmemcmp
>> >> - memicmp
>> >> - memchr / wmemchr
>> >> -
findnonnull
>> >>
>> >> You can write a conversion in JavaScript and access it in the EE very
>> >> quickly:
>> >>
>> >> function fromHex(str)
>> >> {
>> >> return host.parseInt64(str, 16);
>> >> }
>> >>
>> >> .scriptload that… and you can do something like the following
>> example:
>> >>
>> >> 0:000> dx @$foo=“ImageSize: 00091000”
>> >> @$foo=“ImageSize: 00091000” : ImageSize: 00091000
>> >> Length : 0x1a
>> >> 0:000> .load jsprovider.dll
>> >> 0:000> .scriptload g:\junk\conv.js
>> >> JavaScript script successfully loaded from ‘g:\junk\conv.js’
>> >> 0:000> dx @$foo.Substring(18)
>> >> @$foo.Substring(18) : 00091000
>> >> Length : 0x8
>> >> 0:000> dx @$scriptContents.fromHex(@$foo.Substring(18))
>> >> @$scriptContents.fromHex(@$foo.Substring(18)) : 0x91000 0:000> dx
>> >> @$scriptContents.fromHex(@$foo.Substring(18))*3.1415
>> >> @$scriptContents.fromHex(@$foo.Substring(18))*3.1415 : 1865799.680000
>> >>
>> >>
>> >> —
>> >> WINDBG is sponsored by OSR
>> >>
>> >> OSR is hiring!! Info at http://www.osr.com/careers
>> >>
>> >>
>> >> MONTHLY seminars on crash dump analysis, WDF, Windows internals and
>> >> software
>> >> drivers!
>> >> Details at http:
>> >>
>> >> To unsubscribe, visit the List Server section of OSR Online at
>> >> http:
>> >>
>> >
>>
>> —
>> WINDBG is sponsored by OSR
>>
>> OSR is hiring!! Info at http://www.osr.com/careers
>>
>>
>> MONTHLY seminars on crash dump analysis, WDF, Windows internals and
>> software drivers!
>> Details at http:
>>
>> To unsubscribe, visit the List Server section of OSR Online at <
>> http://www.osronline.com/page.cfm?name=ListServer&gt;
>>
>
> —
> WINDBG is sponsored by OSR
>
> OSR is hiring!! Info at http://www.osr.com/careers
>
>
> MONTHLY seminars on crash dump analysis, WDF, Windows internals and software
> drivers!
> Details at http:
>
> To unsubscribe, visit the List Server section of OSR Online at
> http:</http:></http:></http:></http:></http:>

The crash you describe when running .scriptload on an empty file:

0:001> kb

ChildEBP RetAddr Args to Child

WARNING: Frame IP not in any known module. Following frames may be wrong.
00 0146e1d0 60bb9205 02a340c8 00000000 6e2ff13a 0x0
01 0146e1e4 60d0f766 6e2ff4be 00164da8 0146e5ec dbgeng+0x139205
02 0146e460 60c02799 0146e5ec 00000000 00000000 dbgeng!Ordinal327+0x145396

is a bug that will be fixed in a future build. It will only affect script files which are either (nearly) empty or already UTF-16.

The current build(s) also do not permit the ‘dx’ expression evaluator to assign back to the older @$t0 - @$t19 temporaries. It’s likely that this will be addressed in some fashion in a future build as well. This is why you get the:

Error: Not implemented (0x80004001)

on an attempted assignment to …PseudoRegisters.Temporaries.t0 (or @$t0). You can, however, create a variable in ‘dx’ by assignment to a (non-reserved) $@. Such variables can contain anything that you can use in a ‘dx’ expression:

0:000> dx @$myMethod = (x, y) => x + y
@$myMethod = (x, y) => x + y

0:000> dx @$myMethod(5, 7)
@$myMethod(5, 7) : 12

They are, however, only currently usable in a context where the new expression evaluator is used (e.g.: dx).

When you pass a string from the debugger into JavaScript, it becomes a standard JavaScript string. The debugger’s new evaluator has a number of methods on its strings which mirror a number of the .NET methods/properties (e.g.: .Length, .Contains, .StartsWith, .EndsWith, etc…). JavaScript strings have similar methods, but they aren’t named the same thing (e.g.: .startsWith, .endsWith, .includes, .substr, etc…). The scripting provider for JavaScript doesn’t make any attempt to add the debugger’s methods onto standard JavaScript strings.

If you modify your method to use the JavaScript names, it should work:

function trysomething(a)
{
return host.namespace.Debugger.Utility.Control.ExecuteCommand(a).Where(b => b.includes(“hello”));
}

0:000> .load jsprovider.dll
0:000> .scriptload g:\junk\jsContains1.js
JavaScript script successfully loaded from ‘g:\junk\jsContains1.js’

0:000> dx @$scriptContents.trysomething(“.echo hello;.echo world;.echo hello world”)
@$scriptContents.trysomething(“.echo hello;.echo world;.echo hello world”)
[0x0] : hello
[0x1] : hello world

@wmessmer Thanks for responding back

Thanks for acknowledging that the Crash is a bug and a commitment to
close it in a future build
Thanks for explaining that assignment to pseudo-vars may be addressed
in a future build

using includes() instead of Contains() provides correct result

the modified script and result as follows

host.diagnostics.debugLog(“Loaded foo.js This Message is From Root
Execution of foo.js\n”);

function trysomething (a,b) {
var runme = host.namespace.Debugger.Utility.Control.ExecuteCommand;
var logme = host.diagnostics.debugLog;
var res = runme(a).Where(x=>x.includes(b) == true);

if( res.Count() > 1 )
{
logme(“more than 1 result provide better filter\n”);
return res;
}
else
{
host.namespace.Debugger.Utility.Control.ExecuteCommand(“lma @$ip”);
return host.parseInt64(res.First().substr(11),16);
}
}

result

0:000> .scriptunload foo.js
JavaScript script unloaded from ‘E:\windjs\wdbg\Debuggers\x86\foo.js’

0:000> .scriptload foo.js
Loaded foo.js This Message is From Root Execution of foo.js
JavaScript script successfully loaded from ‘E:\windjs\wdbg\Debuggers\x86\foo.js’

0:000> dx @$scriptContents.trysomething(“.fnent @$ip” , “Pr”)
more than 1 result provide better filter
@$scriptContents.trysomething(“.fnent @$ip” , “Pr”)
[0x0] : ProcSize: 0x46
[0x1] : Prologue: 0xc

0:000> dx @$scriptContents.trysomething(“.fnent @$ip” , “Off”)
@$scriptContents.trysomething(“.fnent @$ip” , “Off”) : 0xa04ca

btw is it possible to eliminate the unload and reload or have a
.scriptreload command that unloads an old script with same
name/path/whateverunique and reloads it ?

new question
now i need to find the Module That Contains the Address of Current
Instruction pointer
viz (lma @$ip) parsing the ExecuteCommand(“lma @$ip”) is going to be
messy route
or if i need to find the nearest symbol wrt @$ip viz (ln @$ip) again
parsing and parseint64() would probably be a messy route it appears

how can i go about it will i be getting some commands
like @$isiplistexact() @$ipmod etc etc in the utility section or root

I am trying to confirm if the current instruction is at start of a
function in a module
whose public pdb contains Debugger Function Entry For The Specific
Address and if it was
and i am on break would like to dump the parameters in thier respective type

( i have a working extension that works almost fine for 32 bit but
doesnt work properly for x64 because .fnent in x64 doesnt provide me
number of arguments in its output due to FPO differences , unwind info
differnces )

see like

0:000> r
eax=000af8e8 ebx=7ffd3000 ecx=7791050f edx=778b70b4 esi=ffffffff edi=00000000
eip=778b6048 esp=000af7e4 ebp=000af954 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
ntdll!ZwQueryInformationProcess:
778b6048 b8ea000000 mov eax,0EAh
0:000> !fnproto
no of entries = 2 778b6048

[CSP + 00] [NtQueryInformationProcess(Num Args = 05) Returns to] = 778d60e8
[ESP + 04] [__in HANDLE ProcessHandle] = ffffffff
[ESP + 08] [__in PROCESSINFOCLASS ProcessInformationCla] = 00000022
[ESP + 0c] [__out_bcount_opt(ProcessInformationLength)] = 000af8e8
[ESP + 10] [__in ULONG ProcessInformationLength] = 00000004
[ESP + 14] [__out_opt PULONG ReturnLength )] = 00000000

both {CSP+00] and 778d60e8 are clickable dml

and on clicking i can get

0:000> dpp @$csp l?6;
000af7e4 778d60e8 0b7cc085
000af7e8 ffffffff
000af7ec 00000022
000af7f0 000af8e8 00000000
000af7f4 00000004
000af7f8 00000000

0:000> ub poi(@$csp);u poi(@$csp);
ntdll!LdrpInitializeProcess+0x11b3:
778d60d7 7530 jne ntdll!LdrpInitializeProcess+0x11e6 (778d6109)
778d60d9 57 push edi
778d60da 6a04 push 4
778d60dc 8d4594 lea eax,[ebp-6Ch]
778d60df 50 push eax
778d60e0 6a22 push 22h
778d60e2 56 push esi
778d60e3 e860fffdff call ntdll!ZwQueryInformationProcess (778b6048)

ntdll!LdrpInitializeProcess+0x11c4:
778d60e8 85c0 test eax,eax
778d60ea 7c0b jl ntdll!LdrpInitializeProcess+0x11d4 (778d60f7)
778d60ec 8b4594 mov eax,dword ptr [ebp-6Ch]
778d60ef a808 test al,8
778d60f1 0f85ceac0100 jne ntdll!LdrpInitializeProcess+0x11cf (778f0dc5)
778d60f7 a1f002fe7f mov eax,dword ptr [SharedUserData+0x2f0 (7ffe02f0)]
778d60fc c1e806 shr eax,6
778d60ff f7d0 not eax

the basic logic to this extension is

m_Symbols3->GetSymbolEntriesByOffset ( FunctionOffset , 0, &Ids ,
&Displacements, 1,&Entries);
Out(“no of entries = %x %I64x\n”,Entries,Displacements);
if (( Entries != 0 ) && ( (Displacements - FunctionOffset) == 0 ) )

{
m_Symbols3->GetSymbolEntryString (
&Ids,0,Buffer,sizeof(Buffer),&StringSize);
int numparams = printfninfo(Buffer,TagFilePath,ArgNamesBuff);

what follows printfninfo()

is an unreadable unmaintainable uneverythingable worse than obfuscated
perl hacks put together in a minfied codegolfed function

so i was kinda trying to reproduce it in a script and see if i can
read what i wrote

any ideas how i can go about it ??

On 11/10/16, xxxxx@microsoft.com wrote:
> When you pass a string from the debugger into JavaScript, it becomes a
> standard JavaScript string. The debugger’s new evaluator has a number of
> methods on its strings which mirror a number of the .NET methods/properties
> (e.g.: .Length, .Contains, .StartsWith, .EndsWith, etc…). JavaScript
> strings have similar methods, but they aren’t named the same thing (e.g.:
> .startsWith, .endsWith, .includes, .substr, etc…). The scripting provider
> for JavaScript doesn’t make any attempt to add the debugger’s methods onto
> standard JavaScript strings.
>
> If you modify your method to use the JavaScript names, it should work:
>
> function trysomething(a)
> {
> return host.namespace.Debugger.Utility.Control.ExecuteCommand(a).Where(b
> => b.includes(“hello”));
> }
>
> 0:000> .load jsprovider.dll
> 0:000> .scriptload g:\junk\jsContains1.js
> JavaScript script successfully loaded from ‘g:\junk\jsContains1.js’
>
> 0:000> dx @$scriptContents.trysomething(“.echo hello;.echo world;.echo hello
> world”)
> @$scriptContents.trysomething(“.echo hello;.echo world;.echo hello world”)
>
> [0x0] : hello
> [0x1] : hello world
>
> —
> WINDBG is sponsored by OSR
>
> OSR is hiring!! Info at http://www.osr.com/careers
>
>
> MONTHLY seminars on crash dump analysis, WDF, Windows internals and software
> drivers!
> Details at http:
>
> To unsubscribe, visit the List Server section of OSR Online at
> http:
></http:></http:>

following up when i have no scripts loaded what these lingering links
in dx @$scripts contain

(by clicking them i see they does not seem to contain anything more
than @“contents” so why they are lingering )

0:000> .scriptlist
Command Loaded Scripts:


0:000> dx @$scripts
@$scripts
foo_10
foo
foo_1
foo_2
foo_3

i have done more than 10 reloads so why only _1 to _3 and _10 are lingering ?
what happened to _4,_5 or for that matter _25
did the garbage van visit them and these are stilll lying in kitchen sink ?

has this been exposed yet ?

0:000> dx @$scriptContents.host.getNamedModel(“Debugger.Models.Parameters”)
@$scriptContents.host.getNamedModel(“Debugger.Models.Parameters”)

0:000> dx -r1 @$scriptContents.host.getNamedModel(“Debugger.Models.Parameters”)
@$scriptContents.host.getNamedModel(“Debugger.Models.Parameters”)

it appears some other models have been exposed

0:000> dx -r1 @$scriptContents.host.getNamedModel(“Debugger.Models.Process”)
@$scriptContents.host.getNamedModel(“Debugger.Models.Process”)

Name : Unexpected failure to dereference object
Id : Unexpected failure to dereference object
Threads : Unexpected failure to dereference object
Modules : Unexpected failure to dereference object
Environment

does this have any problems i happen to see in your nativeobjects
example msdn page
this being used

[quote]

gipAllocator = host.getModuleSymbol(“combase.dll”,
“GIPEntry::_palloc”, “CPageAllocator”, gipProcess)._pgalloc;
[/quote]

0:000> dx @$scriptContents.host.getModuleSymbol(“calc.exe” , “WinMain”)
Error: Invalid argument to method ‘getModuleSymbol’

i also happened to crash windbg here though by passing spurious arguments

crashed windbg stacktrace (cant do anything meaningful without symbols)

i was trying to do

0:001> .foreach (place { s -[1]u @esp L?800 “Models.Modules”}) { du /c
100 place }
00a8d67e “Models.Modules”)“>cmd=“dx -r1 -g @$scriptContents.host.getNamedModel(“Debugger.Models.Modules”)”/>@$scriptContents.host.getNamedModel(“Debugger.Models.Modules”)

00a8d770 “Models.Modules”)”/>@$scriptContents.host.getNamedModel(“Debugger.Models.Modules”)

00a8d806 “Models.Modules”) “
00a8e0d6 “Models.Modules”)”
0:001> kb
# ChildEBP RetAddr Args to Child
WARNING: Stack unwind information not available. Following frames may be wrong.
00 00a8d3c0 735537b1 02a56f08 00a8d3f8 00000000 dbgeng!Ordinal327+0x1468f9
01 00a8d40c 6cf2656b 02a36080 00a8d450 00000000
dbgmodel!CreateDataModelManager+0x102d1
02 00a8d484 6cf26d2b 00000000 00000000 00a8d4e0 dbgeng!Ordinal327+0x15c19b
03 00a8d4f4 6cf2752a 00a8d51c 19f6c9b8 7353eaf0 dbgeng!Ordinal327+0x15c95b
04 00a8d540 6ce7e197 029b9fb8 00000000 00000001 dbgeng!Ordinal327+0x15d15a
05 00a8da04 6ce7e29d 00000001 00000000 00000000 dbgeng!Ordinal327+0xb3dc7
06 00a8da64 6ce7e854 00000001 00000000 00000000 dbgeng!Ordinal327+0xb3ecd
07 00a8dad4 6ce76c87 19f6c3c4 00000062 00000064 dbgeng!Ordinal327+0xb4484
08 00a8df3c 6ce7f59e 19f6c33c 00000000 00000000 dbgeng!Ordinal327+0xac8b7
09 00a8dfc4 6ce8037f 19f6fce4 002b4d90 00000001 dbgeng!Ordinal327+0xb51ce
0a 00a8e01c 6cdd317a 00000000 19f6f87c 00000000 dbgeng!Ordinal327+0xb5faf
0b 00a8e484 6cdd3338 0000000a 00000000 19f6f830 dbgeng!Ordinal327+0x8daa
0c 00a8e4c8 010243ba 002b4d98 00000001 00a8e8a8 dbgeng!Ordinal327+0x8f68
0d 00a8e884 01024841 00000000 00000008 00a8f800 windbg+0x243ba
0e 00a8f8a4 01026a60 19e19555 00000000 00000000 windbg+0x24841
0f 00a8f8f0 77a13c45 00000000 00a8f93c 778d37f5 windbg+0x26a60
10 00a8f8fc 778d37f5 00000000 74cf7823 00000000 kernel32!BaseThreadInitThunk+0xe
11 00a8f93c 778d37c8 010264f0 00000000 00000000 ntdll!__RtlUserThreadStart+0x70
12 00a8f954 00000000 010264f0 00000000 00000000 ntdll!_RtlUserThreadStart+0x1b

0:001> ub @$ip
dbgeng!Ordinal327+0x1468e8:
6cf10cb8 85c0 test eax,eax
6cf10cba 7501 jne dbgeng!Ordinal327+0x1468ed (6cf10cbd)
6cf10cbc c3 ret
6cf10cbd 8b8024020000 mov eax,dword ptr [eax+224h]
6cf10cc3 c3 ret
6cf10cc4 8bff mov edi,edi
6cf10cc6 56 push esi
6cf10cc7 8bf1 mov esi,ecx
0:001> u @$ip l2
dbgeng!Ordinal327+0x1468f9:
6cf10cc9 8b460c mov eax,dword ptr [esi+0Ch]
6cf10ccc 83e003 and eax,3

0:001> $$ it appears a this pointer is empty here

the query that crashed windbg is

host.getnamedmodel(Debugger.Models.Modules); note the extra s just
plain module doesnt crash but modules sure crashes

a screenmovie from cdb providing some tidbits about a NON_COMMAND av

E:\windjs\wdbg\Debuggers\x86>.\cdb calc

Microsoft (R) Windows Debugger Version 10.0.14951.1001 X86

ntdll!LdrpDoDebuggerBreak+0x2c:
779104f6 cc int 3

0:000> .load jsprovider

0:000> .scriptload foo.js

Loaded foo.js This Message is From Root Execution of foo.js

JavaScript script successfully loaded from ‘E:\windjs\wdbg\Debuggers\x86\foo.js’

0:000> dx @$scriptContents.host.getNamedModel(“crap”)
@$scriptContents.host.getNamedModel(“crap”)

0:000> dx @$scriptContents.host.getNamedModel(“Debugger”)
@$scriptContents.host.getNamedModel(“Debugger”)

0:000> dx @$scriptContents.host.getNamedModel(“Debugger.Models”)
@$scriptContents.host.getNamedModel(“Debugger.Models”)

0:000> dx @$scriptContents.host.getNamedModel(“Debugger.Models.Module”)
@$scriptContents.host.getNamedModel(“Debugger.Models.Module”)
Name : Unexpected failure to dereference object
Size : Unexpected failure to dereference object

0:000> dx @$scriptContents.host.getNamedModel(“Debugger.Models.Modules”)
<----crash here
@$scriptContents.host.getNamedModel(“Debugger.Models.Modules”)
Non-command exception C0000005 at 6cf10cc9 in command filter <<<-----------
Non-command exception C0000005 at 6cf10cc9 in command filter

E:\windjs\wdbg\Debuggers\x86>

On 11/10/16, raj r wrote:
> @wmessmer Thanks for responding back
>
> Thanks for acknowledging that the Crash is a bug and a commitment to
> close it in a future build
> Thanks for explaining that assignment to pseudo-vars may be addressed
> in a future build
>
> using includes() instead of Contains() provides correct result
>
> the modified script and result as follows
>
> host.diagnostics.debugLog(“Loaded foo.js This Message is From Root
> Execution of foo.js\n”);
>
>
> function trysomething (a,b) {
> var runme = host.namespace.Debugger.Utility.Control.ExecuteCommand;
> var logme = host.diagnostics.debugLog;
> var res = runme(a).Where(x=>x.includes(b) == true);
>
> if( res.Count() > 1 )
> {
> logme(“more than 1 result provide better filter\n”);
> return res;
> }
> else
> {
> host.namespace.Debugger.Utility.Control.ExecuteCommand(“lma @$ip”);
> return host.parseInt64(res.First().substr(11),16);
> }
> }
>
> result
>
> 0:000> .scriptunload foo.js
> JavaScript script unloaded from ‘E:\windjs\wdbg\Debuggers\x86\foo.js’
>
> 0:000> .scriptload foo.js
> Loaded foo.js This Message is From Root Execution of foo.js
> JavaScript script successfully loaded from
> ‘E:\windjs\wdbg\Debuggers\x86\foo.js’
>
>
> 0:000> dx @$scriptContents.trysomething(”.fnent @$ip” , “Pr”)
> more than 1 result provide better filter
> @$scriptContents.trysomething(“.fnent @$ip” , “Pr”)
> [0x0] : ProcSize: 0x46
> [0x1] : Prologue: 0xc
>
>
> 0:000> dx @$scriptContents.trysomething(“.fnent @$ip” , “Off”)
> @$scriptContents.trysomething(“.fnent @$ip” , “Off”) : 0xa04ca
>
> btw is it possible to eliminate the unload and reload or have a
> .scriptreload command that unloads an old script with same
> name/path/whateverunique and reloads it ?
>
>
> new question
> now i need to find the Module That Contains the Address of Current
> Instruction pointer
> viz (lma @$ip) parsing the ExecuteCommand(“lma @$ip”) is going to be
> messy route
> or if i need to find the nearest symbol wrt @$ip viz (ln @$ip) again
> parsing and parseint64() would probably be a messy route it appears
>
> how can i go about it will i be getting some commands
> like @$isiplistexact() @$ipmod etc etc in the utility section or root
>
> I am trying to confirm if the current instruction is at start of a
> function in a module
> whose public pdb contains Debugger Function Entry For The Specific
> Address and if it was
> and i am on break would like to dump the parameters in thier respective
> type
>
>
> ( i have a working extension that works almost fine for 32 bit but
> doesnt work properly for x64 because .fnent in x64 doesnt provide me
> number of arguments in its output due to FPO differences , unwind info
> differnces )
>
>
> see like
>
> 0:000> r
> eax=000af8e8 ebx=7ffd3000 ecx=7791050f edx=778b70b4 esi=ffffffff
> edi=00000000
> eip=778b6048 esp=000af7e4 ebp=000af954 iopl=0 nv up ei pl zr na pe
> nc
> cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000
> efl=00000246
> ntdll!ZwQueryInformationProcess:
> 778b6048 b8ea000000 mov eax,0EAh
> 0:000> !fnproto
> no of entries = 2 778b6048
>
>
> [CSP + 00] [NtQueryInformationProcess(Num Args = 05) Returns to] =
> 778d60e8
> [ESP + 04] [__in HANDLE ProcessHandle] = ffffffff
> [ESP + 08] [__in PROCESSINFOCLASS ProcessInformationCla] = 00000022
> [ESP + 0c] [__out_bcount_opt(ProcessInformationLength)] = 000af8e8
> [ESP + 10] [__in ULONG ProcessInformationLength] = 00000004
> [ESP + 14] [__out_opt PULONG ReturnLength )] = 00000000
>
> both {CSP+00] and 778d60e8 are clickable dml
>
>
> and on clicking i can get
>
> 0:000> dpp @$csp l?6;
> 000af7e4 778d60e8 0b7cc085
> 000af7e8 ffffffff
> 000af7ec 00000022
> 000af7f0 000af8e8 00000000
> 000af7f4 00000004
> 000af7f8 00000000
>
> 0:000> ub poi(@$csp);u poi(@$csp);
> ntdll!LdrpInitializeProcess+0x11b3:
> 778d60d7 7530 jne ntdll!LdrpInitializeProcess+0x11e6
> (778d6109)
> 778d60d9 57 push edi
> 778d60da 6a04 push 4
> 778d60dc 8d4594 lea eax,[ebp-6Ch]
> 778d60df 50 push eax
> 778d60e0 6a22 push 22h
> 778d60e2 56 push esi
> 778d60e3 e860fffdff call ntdll!ZwQueryInformationProcess (778b6048)
>
> ntdll!LdrpInitializeProcess+0x11c4:
> 778d60e8 85c0 test eax,eax
> 778d60ea 7c0b jl ntdll!LdrpInitializeProcess+0x11d4
> (778d60f7)
> 778d60ec 8b4594 mov eax,dword ptr [ebp-6Ch]
> 778d60ef a808 test al,8
> 778d60f1 0f85ceac0100 jne ntdll!LdrpInitializeProcess+0x11cf
> (778f0dc5)
> 778d60f7 a1f002fe7f mov eax,dword ptr [SharedUserData+0x2f0
> (7ffe02f0)]
> 778d60fc c1e806 shr eax,6
> 778d60ff f7d0 not eax
>
>
>
> the basic logic to this extension is
>
> m_Symbols3->GetSymbolEntriesByOffset ( FunctionOffset , 0, &Ids ,
> &Displacements, 1,&Entries);
> Out(“no of entries = %x %I64x\n”,Entries,Displacements);
> if (( Entries != 0 ) && ( (Displacements - FunctionOffset) == 0 ) )
>
> {
> m_Symbols3->GetSymbolEntryString (
> &Ids,0,Buffer,sizeof(Buffer),&StringSize);
> int numparams = printfninfo(Buffer,TagFilePath,ArgNamesBuff);
>
> what follows printfninfo()
>
> is an unreadable unmaintainable uneverythingable worse than obfuscated
> perl hacks put together in a minfied codegolfed function
>
> so i was kinda trying to reproduce it in a script and see if i can
> read what i wrote
>
> any ideas how i can go about it ??
>
>
>
>
>
>
>
>
>
>
>
>
>
>
> On 11/10/16, xxxxx@microsoft.com wrote:
>> When you pass a string from the debugger into JavaScript, it becomes a
>> standard JavaScript string. The debugger’s new evaluator has a number of
>> methods on its strings which mirror a number of the .NET
>> methods/properties
>> (e.g.: .Length, .Contains, .StartsWith, .EndsWith, etc…). JavaScript
>> strings have similar methods, but they aren’t named the same thing (e.g.:
>> .startsWith, .endsWith, .includes, .substr, etc…). The scripting
>> provider
>> for JavaScript doesn’t make any attempt to add the debugger’s methods
>> onto
>> standard JavaScript strings.
>>
>> If you modify your method to use the JavaScript names, it should work:
>>
>> function trysomething(a)
>> {
>> return
>> host.namespace.Debugger.Utility.Control.ExecuteCommand(a).Where(b
>> => b.includes(“hello”));
>> }
>>
>> 0:000> .load jsprovider.dll
>> 0:000> .scriptload g:\junk\jsContains1.js
>> JavaScript script successfully loaded from ‘g:\junk\jsContains1.js’
>>
>> 0:000> dx @$scriptContents.trysomething(“.echo hello;.echo world;.echo
>> hello
>> world”)
>> @$scriptContents.trysomething(“.echo hello;.echo world;.echo hello
>> world”)
>>
>> [0x0] : hello
>> [0x1] : hello world
>>
>> —
>> WINDBG is sponsored by OSR
>>
>> OSR is hiring!! Info at http://www.osr.com/careers
>>
>>
>> MONTHLY seminars on crash dump analysis, WDF, Windows internals and
>> software
>> drivers!
>> Details at http:
>>
>> To unsubscribe, visit the List Server section of OSR Online at
>> http:
>>
></http:></http:>

follow up

this is regarding getmoduleSymbol()

i copy pasted the whole code asis from

https://msdn.microsoft.com/library/windows/hardware/A8E12564-D083-43A7-920E-22C4D627FEE8.aspx

and tried executing it and it seems it doesn’t work

0:000> .load jsprovider

0:000> dx @$curprocess
@$curprocess : windbg.exe
Name : windbg.exe
Id : 0x8d0
Threads
Modules
Environment

0:000> .scriptload blah.js
JavaScript script successfully loaded from
‘E:\windjs\wdbg\Debuggers\x86\blah.js’

0:000> dx @$curprocess
@$curprocess : windbg.exe
Name : windbg.exe
Id : 0x8d0
Threads
Modules
Environment
COM : [object Object]

0:000> dx -r1 @$curprocess.@“COM”
@$curprocess.@“COM” : [object Object]
GlobalObjects : Invalid argument to method ‘getModuleSymbol’

0:000> dx -r1 @$curprocess.@“COM”

@$curprocess.@“COM” : [object Object]
GlobalObjects : Invalid argument to method ‘getModuleSymbol’

On 11/10/16, raj r wrote:
> following up when i have no scripts loaded what these lingering links
> in dx @$scripts contain
>
> (by clicking them i see they does not seem to contain anything more
> than @“contents” so why they are lingering )
>
> 0:000> .scriptlist
> Command Loaded Scripts:
>
>
> 0:000> dx @$scripts
> @$scripts
> foo_10
> foo
> foo_1
> foo_2
> foo_3
>
> i have done more than 10 reloads so why only _1 to _3 and _10 are lingering
> ?
> what happened to _4,_5 or for that matter _25
> did the garbage van visit them and these are stilll lying in kitchen sink
> ?
>
>
>
>
> has this been exposed yet ?
>
> 0:000> dx @$scriptContents.host.getNamedModel(“Debugger.Models.Parameters”)
> @$scriptContents.host.getNamedModel(“Debugger.Models.Parameters”)
>
> 0:000> dx -r1
> @$scriptContents.host.getNamedModel(“Debugger.Models.Parameters”)
> @$scriptContents.host.getNamedModel(“Debugger.Models.Parameters”)
>
>
> it appears some other models have been exposed
>
> 0:000> dx -r1
> @$scriptContents.host.getNamedModel(“Debugger.Models.Process”)
> @$scriptContents.host.getNamedModel(“Debugger.Models.Process”)
>
> Name : Unexpected failure to dereference object
> Id : Unexpected failure to dereference object
> Threads : Unexpected failure to dereference object
> Modules : Unexpected failure to dereference object
> Environment
>
>
> does this have any problems i happen to see in your nativeobjects
> example msdn page
> this being used
>
> [quote]
>
> gipAllocator = host.getModuleSymbol(“combase.dll”,
> “GIPEntry::_palloc”, “CPageAllocator”, gipProcess)._pgalloc;
> [/quote]
>
> 0:000> dx @$scriptContents.host.getModuleSymbol(“calc.exe” , “WinMain”)
> Error: Invalid argument to method ‘getModuleSymbol’
>
> i also happened to crash windbg here though by passing spurious arguments
>
> crashed windbg stacktrace (cant do anything meaningful without symbols)
>
> i was trying to do
>
>
> 0:001> .foreach (place { s -[1]u @esp L?800 “Models.Modules”}) { du /c
> 100 place }
> 00a8d67e “Models.Modules”)“>> cmd=“dx -r1 -g
> @$scriptContents.host.getNamedModel(“Debugger.Models.Modules”)”/>@$scriptContents.host.getNamedModel(“Debugger.Models.Modules”)
> “
> 00a8d770
> “Models.Modules”)”/>@$scriptContents.host.getNamedModel(“Debugger.Models.Modules”)
> “
> 00a8d806 “Models.Modules”) “
> 00a8e0d6 “Models.Modules”)”
> 0:001> kb
> # ChildEBP RetAddr Args to Child
> WARNING: Stack unwind information not available. Following frames may be
> wrong.
> 00 00a8d3c0 735537b1 02a56f08 00a8d3f8 00000000 dbgeng!Ordinal327+0x1468f9
> 01 00a8d40c 6cf2656b 02a36080 00a8d450 00000000
> dbgmodel!CreateDataModelManager+0x102d1
> 02 00a8d484 6cf26d2b 00000000 00000000 00a8d4e0 dbgeng!Ordinal327+0x15c19b
> 03 00a8d4f4 6cf2752a 00a8d51c 19f6c9b8 7353eaf0 dbgeng!Ordinal327+0x15c95b
> 04 00a8d540 6ce7e197 029b9fb8 00000000 00000001 dbgeng!Ordinal327+0x15d15a
> 05 00a8da04 6ce7e29d 00000001 00000000 00000000 dbgeng!Ordinal327+0xb3dc7
> 06 00a8da64 6ce7e854 00000001 00000000 00000000 dbgeng!Ordinal327+0xb3ecd
> 07 00a8dad4 6ce76c87 19f6c3c4 00000062 00000064 dbgeng!Ordinal327+0xb4484
> 08 00a8df3c 6ce7f59e 19f6c33c 00000000 00000000 dbgeng!Ordinal327+0xac8b7
> 09 00a8dfc4 6ce8037f 19f6fce4 002b4d90 00000001 dbgeng!Ordinal327+0xb51ce
> 0a 00a8e01c 6cdd317a 00000000 19f6f87c 00000000 dbgeng!Ordinal327+0xb5faf
> 0b 00a8e484 6cdd3338 0000000a 00000000 19f6f830 dbgeng!Ordinal327+0x8daa
> 0c 00a8e4c8 010243ba 002b4d98 00000001 00a8e8a8 dbgeng!Ordinal327+0x8f68
> 0d 00a8e884 01024841 00000000 00000008 00a8f800 windbg+0x243ba
> 0e 00a8f8a4 01026a60 19e19555 00000000 00000000 windbg+0x24841
> 0f 00a8f8f0 77a13c45 00000000 00a8f93c 778d37f5 windbg+0x26a60
> 10 00a8f8fc 778d37f5 00000000 74cf7823 00000000
> kernel32!BaseThreadInitThunk+0xe
> 11 00a8f93c 778d37c8 010264f0 00000000 00000000
> ntdll!__RtlUserThreadStart+0x70
> 12 00a8f954 00000000 010264f0 00000000 00000000
> ntdll!_RtlUserThreadStart+0x1b
>
>
>
> 0:001> ub @$ip
> dbgeng!Ordinal327+0x1468e8:
> 6cf10cb8 85c0 test eax,eax
> 6cf10cba 7501 jne dbgeng!Ordinal327+0x1468ed (6cf10cbd)
> 6cf10cbc c3 ret
> 6cf10cbd 8b8024020000 mov eax,dword ptr [eax+224h]
> 6cf10cc3 c3 ret
> 6cf10cc4 8bff mov edi,edi
> 6cf10cc6 56 push esi
> 6cf10cc7 8bf1 mov esi,ecx
> 0:001> u @$ip l2
> dbgeng!Ordinal327+0x1468f9:
> 6cf10cc9 8b460c mov eax,dword ptr [esi+0Ch]
> 6cf10ccc 83e003 and eax,3
>
>
> 0:001> $$ it appears a this pointer is empty here
>
> the query that crashed windbg is
>
> host.getnamedmodel(Debugger.Models.Modules); note the extra s just
> plain module doesnt crash but modules sure crashes
>
>
> a screenmovie from cdb providing some tidbits about a NON_COMMAND av
>
> E:\windjs\wdbg\Debuggers\x86>.\cdb calc
>
> Microsoft (R) Windows Debugger Version 10.0.14951.1001 X86
>
> ntdll!LdrpDoDebuggerBreak+0x2c:
> 779104f6 cc int 3
>
> 0:000> .load jsprovider
>
> 0:000> .scriptload foo.js
>
> Loaded foo.js This Message is From Root Execution of foo.js
>
> JavaScript script successfully loaded from
> ‘E:\windjs\wdbg\Debuggers\x86\foo.js’
>
> 0:000> dx @$scriptContents.host.getNamedModel(“crap”)
> @$scriptContents.host.getNamedModel(“crap”)
>
> 0:000> dx @$scriptContents.host.getNamedModel(“Debugger”)
> @$scriptContents.host.getNamedModel(“Debugger”)
>
> 0:000> dx @$scriptContents.host.getNamedModel(“Debugger.Models”)
> @$scriptContents.host.getNamedModel(“Debugger.Models”)
>
> 0:000> dx @$scriptContents.host.getNamedModel(“Debugger.Models.Module”)
> @$scriptContents.host.getNamedModel(“Debugger.Models.Module”)
> Name : Unexpected failure to dereference object
> Size : Unexpected failure to dereference object
>
> 0:000> dx @$scriptContents.host.getNamedModel(“Debugger.Models.Modules”)
> <----crash here
> @$scriptContents.host.getNamedModel(“Debugger.Models.Modules”)
> Non-command exception C0000005 at 6cf10cc9 in command filter
> <<<-----------
> Non-command exception C0000005 at 6cf10cc9 in command filter
>
> E:\windjs\wdbg\Debuggers\x86>
>
>
>
>
>
>
>
>
>
>
> On 11/10/16, raj r wrote:
>> @wmessmer Thanks for responding back
>>
>> Thanks for acknowledging that the Crash is a bug and a commitment to
>> close it in a future build
>> Thanks for explaining that assignment to pseudo-vars may be addressed
>> in a future build
>>
>> using includes() instead of Contains() provides correct result
>>
>> the modified script and result as follows
>>
>> host.diagnostics.debugLog(“Loaded foo.js This Message is From Root
>> Execution of foo.js\n”);
>>
>>
>> function trysomething (a,b) {
>> var runme = host.namespace.Debugger.Utility.Control.ExecuteCommand;
>> var logme = host.diagnostics.debugLog;
>> var res = runme(a).Where(x=>x.includes(b) == true);
>>
>> if( res.Count() > 1 )
>> {
>> logme(“more than 1 result provide better filter\n”);
>> return res;
>> }
>> else
>> {
>> host.namespace.Debugger.Utility.Control.ExecuteCommand(“lma @$ip”);
>> return host.parseInt64(res.First().substr(11),16);
>> }
>> }
>>
>> result
>>
>> 0:000> .scriptunload foo.js
>> JavaScript script unloaded from ‘E:\windjs\wdbg\Debuggers\x86\foo.js’
>>
>> 0:000> .scriptload foo.js
>> Loaded foo.js This Message is From Root Execution of foo.js
>> JavaScript script successfully loaded from
>> ‘E:\windjs\wdbg\Debuggers\x86\foo.js’
>>
>>
>> 0:000> dx @$scriptContents.trysomething(”.fnent @$ip” , “Pr”)
>> more than 1 result provide better filter
>> @$scriptContents.trysomething(“.fnent @$ip” , “Pr”)
>> [0x0] : ProcSize: 0x46
>> [0x1] : Prologue: 0xc
>>
>>
>> 0:000> dx @$scriptContents.trysomething(“.fnent @$ip” , “Off”)
>> @$scriptContents.trysomething(“.fnent @$ip” , “Off”) : 0xa04ca
>>
>> btw is it possible to eliminate the unload and reload or have a
>> .scriptreload command that unloads an old script with same
>> name/path/whateverunique and reloads it ?
>>
>>
>> new question
>> now i need to find the Module That Contains the Address of Current
>> Instruction pointer
>> viz (lma @$ip) parsing the ExecuteCommand(“lma @$ip”) is going to be
>> messy route
>> or if i need to find the nearest symbol wrt @$ip viz (ln @$ip) again
>> parsing and parseint64() would probably be a messy route it appears
>>
>> how can i go about it will i be getting some commands
>> like @$isiplistexact() @$ipmod etc etc in the utility section or root
>>
>> I am trying to confirm if the current instruction is at start of a
>> function in a module
>> whose public pdb contains Debugger Function Entry For The Specific
>> Address and if it was
>> and i am on break would like to dump the parameters in thier respective
>> type
>>
>>
>> ( i have a working extension that works almost fine for 32 bit but
>> doesnt work properly for x64 because .fnent in x64 doesnt provide me
>> number of arguments in its output due to FPO differences , unwind info
>> differnces )
>>
>>
>> see like
>>
>> 0:000> r
>> eax=000af8e8 ebx=7ffd3000 ecx=7791050f edx=778b70b4 esi=ffffffff
>> edi=00000000
>> eip=778b6048 esp=000af7e4 ebp=000af954 iopl=0 nv up ei pl zr na
>> pe
>> nc
>> cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000
>> efl=00000246
>> ntdll!ZwQueryInformationProcess:
>> 778b6048 b8ea000000 mov eax,0EAh
>> 0:000> !fnproto
>> no of entries = 2 778b6048
>>
>>
>> [CSP + 00] [NtQueryInformationProcess(Num Args = 05) Returns to] =
>> 778d60e8
>> [ESP + 04] [__in HANDLE ProcessHandle] = ffffffff
>> [ESP + 08] [__in PROCESSINFOCLASS ProcessInformationCla] = 00000022
>> [ESP + 0c] [__out_bcount_opt(ProcessInformationLength)] = 000af8e8
>> [ESP + 10] [__in ULONG ProcessInformationLength] = 00000004
>> [ESP + 14] [__out_opt PULONG ReturnLength )] = 00000000
>>
>> both {CSP+00] and 778d60e8 are clickable dml
>>
>>
>> and on clicking i can get
>>
>> 0:000> dpp @$csp l?6;
>> 000af7e4 778d60e8 0b7cc085
>> 000af7e8 ffffffff
>> 000af7ec 00000022
>> 000af7f0 000af8e8 00000000
>> 000af7f4 00000004
>> 000af7f8 00000000
>>
>> 0:000> ub poi(@$csp);u poi(@$csp);
>> ntdll!LdrpInitializeProcess+0x11b3:
>> 778d60d7 7530 jne ntdll!LdrpInitializeProcess+0x11e6
>> (778d6109)
>> 778d60d9 57 push edi
>> 778d60da 6a04 push 4
>> 778d60dc 8d4594 lea eax,[ebp-6Ch]
>> 778d60df 50 push eax
>> 778d60e0 6a22 push 22h
>> 778d60e2 56 push esi
>> 778d60e3 e860fffdff call ntdll!ZwQueryInformationProcess
>> (778b6048)
>>
>> ntdll!LdrpInitializeProcess+0x11c4:
>> 778d60e8 85c0 test eax,eax
>> 778d60ea 7c0b jl ntdll!LdrpInitializeProcess+0x11d4
>> (778d60f7)
>> 778d60ec 8b4594 mov eax,dword ptr [ebp-6Ch]
>> 778d60ef a808 test al,8
>> 778d60f1 0f85ceac0100 jne ntdll!LdrpInitializeProcess+0x11cf
>> (778f0dc5)
>> 778d60f7 a1f002fe7f mov eax,dword ptr [SharedUserData+0x2f0
>> (7ffe02f0)]
>> 778d60fc c1e806 shr eax,6
>> 778d60ff f7d0 not eax
>>
>>
>>
>> the basic logic to this extension is
>>
>> m_Symbols3->GetSymbolEntriesByOffset ( FunctionOffset , 0, &Ids ,
>> &Displacements, 1,&Entries);
>> Out(“no of entries = %x %I64x\n”,Entries,Displacements);
>> if (( Entries != 0 ) && ( (Displacements - FunctionOffset) == 0 ) )
>>
>> {
>> m_Symbols3->GetSymbolEntryString (
>> &Ids,0,Buffer,sizeof(Buffer),&StringSize);
>> int numparams = printfninfo(Buffer,TagFilePath,ArgNamesBuff);
>>
>> what follows printfninfo()
>>
>> is an unreadable unmaintainable uneverythingable worse than obfuscated
>> perl hacks put together in a minfied codegolfed function
>>
>> so i was kinda trying to reproduce it in a script and see if i can
>> read what i wrote
>>
>> any ideas how i can go about it ??
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>> On 11/10/16, xxxxx@microsoft.com wrote:
>>> When you pass a string from the debugger into JavaScript, it becomes a
>>> standard JavaScript string. The debugger’s new evaluator has a number
>>> of
>>> methods on its strings which mirror a number of the .NET
>>> methods/properties
>>> (e.g.: .Length, .Contains, .StartsWith, .EndsWith, etc…). JavaScript
>>> strings have similar methods, but they aren’t named the same thing
>>> (e.g.:
>>> .startsWith, .endsWith, .includes, .substr, etc…). The scripting
>>> provider
>>> for JavaScript doesn’t make any attempt to add the debugger’s methods
>>> onto
>>> standard JavaScript strings.
>>>
>>> If you modify your method to use the JavaScript names, it should work:
>>>
>>> function trysomething(a)
>>> {
>>> return
>>> host.namespace.Debugger.Utility.Control.ExecuteCommand(a).Where(b
>>> => b.includes(“hello”));
>>> }
>>>
>>> 0:000> .load jsprovider.dll
>>> 0:000> .scriptload g:\junk\jsContains1.js
>>> JavaScript script successfully loaded from ‘g:\junk\jsContains1.js’
>>>
>>> 0:000> dx @$scriptContents.trysomething(“.echo hello;.echo world;.echo
>>> hello
>>> world”)
>>> @$scriptContents.trysomething(“.echo hello;.echo world;.echo hello
>>> world”)
>>>
>>> [0x0] : hello
>>> [0x1] : hello world
>>>
>>> —
>>> WINDBG is sponsored by OSR
>>>
>>> OSR is hiring!! Info at http://www.osr.com/careers
>>>
>>>
>>> MONTHLY seminars on crash dump analysis, WDF, Windows internals and
>>> software
>>> drivers!
>>> Details at http:
>>>
>>> To unsubscribe, visit the List Server section of OSR Online at
>>> http:
>>>
>>
></http:></http:>

I’ll try to go through these one by one. Please remember that this is a pre-release/preview of the scripting functionality. Thanks for taking the time to try this out and report the issues you’ve been having.

btw is it possible to eliminate the unload and reload or have a
.scriptreload command that unloads an old script with same
name/path/whateverunique and reloads it ?

At the moment, you do have to .scriptunload and .scriptload. There are better experiences around some of this coming at some point in the future.

now i need to find the Module That Contains the Address of Current
Instruction pointer

Remember that …ExecuteCommand(…) is intended to be an escape hatch for things which do not yet have an object model against them. It’s the intent that eventually for most data manipulation operations, you should not have to go back to parsing text from command output of the debugger. Modules do have an object model (the .Modules node off any process object). The below example will show this (albeit there is a problem with using ‘<’ and ‘>’ in this context). The 64-bit lib is missing a comparison function which will not go back to JavaScript number (that’ll get fixed):

function findModuleAtAddr(addr)
{
//
// The ‘<’ and ‘>’ comparisons are unsafe as they will convert to JS
// number which is 53 bit ordinal. If you need this before there’s an
// available method, you can always write a small comparator using
// .getHighPart() and .getLowPart()
//
return host.currentProcess.Modules.Where(m => addr >= m.BaseAddress && addr < m.BaseAddress.add(m.Size));
}

0:000> k1

Child-SP RetAddr Call Site

00 000000471cc7f880 00007ff6ac283d93 USER32!GetMessageW+0x26

0:000> dx -r2 @$scriptContents.findModuleAtAddr(@rip)
@$scriptContents.findModuleAtAddr(@rip)
[0x0] : C:\Windows\System32\USER32.dll
BaseAddress : 0x7ffbd1ca0000
Name : C:\Windows\System32\USER32.dll
Size : 0x165000

I am trying to confirm if the current instruction is at start of a
function in a module
whose public pdb contains Debugger Function Entry For The Specific
Address and if it was
and i am on break would like to dump the parameters in thier respective type

Yes – what you’re trying to do here will require escaping out to .ExecuteCommand(…) and parsing… or (eventually) writing some C++ code that adds new JavaScript accessible functionality. We are working on C/C++ APIs for a future SDK which would allow you to extend the model (and hence call from JavaScript).

Before I comment further on this, I wasn’t sure that I completely understood the scenario. Maybe with a bit of playing around, I do, but could you please confirm my assumption here:

Are you effectively trying to get ‘dv (/v)’ on public symbols for function parameters?

following up when i have no scripts loaded what these lingering links
in dx @$scripts contain

That *should* only happen when you have a reference into the script still lingering. For instance, if you utilize dx to assign a pseudo variable to a JavaScript object (dx @$myVar = @$scriptContents.someObject), the script cannot disappear out from underneath the variable. When you unload the script, you can no longer get to its contents through @$scriptContents, it’s object model modifications disappear, etc… but the script context doesn’t go away until there’s nothing holding onto it. That said, you should not be seeing this just loading and unloading the kinds of scripts you’ve been showing here.

I’ll look into this.

has this been exposed yet ?

0:000> dx @$scriptContents.host.getNamedModel(“Debugger.Models.Parameters”)
@$scriptContents.host.getNamedModel(“Debugger.Models.Parameters”)

it appears some other models have been exposed

0:000> dx -r1 @$scriptContents.host.getNamedModel(“Debugger.Models.Process”)
@$scriptContents.host.getNamedModel(“Debugger.Models.Process”)
Name : Unexpected failure to dereference object

Yes, “Debugger.Models.Parameters” is exposed. There’s no properties on the general notion of “Parameters” (hence you don’t see anything). You also get the “Unexpected failure to dereference object” because you’re looking at what’s effectively a “prototype object” for process. There’s no context object (‘this’ pointer) attached… and hence the ‘Name’ property fails when it sees what amounts to a null this. On ‘Parameters’, all the actual parameters for a given stack frame are on what amounts to the ‘this’ object. The prototype is empty. This matters less now than it will later.

The idea for most of these is that you extend them in JavaScript. Try loading the following script and then looking at the current process:

function initializeScript()
{
class myExtension
{
get NewProperty() { return “Hello World”; }
}

return [new host.namedModelParent(myExtension, “Debugger.Models.Process”)];
}

0:008> dx @$curprocess
@$curprocess : notepad.exe
Name : notepad.exe
Id : 0x4a28
Threads
Modules
Environment
0:008> .load jsprovider.dll
0:008> .scriptload g:\junk\js1\procExt.js
JavaScript script successfully loaded from ‘g:\junk\js1\procExt.js’
0:008> dx @$curprocess
@$curprocess : notepad.exe
Name : notepad.exe
Id : 0x4a28
Threads
Modules
Environment
NewProperty : Hello World

0:000> dx @$scriptContents.host.getNamedModel(“Debugger.Models.Modules”)
<----crash here
@$scriptContents.host.getNamedModel(“Debugger.Models.Modules”)
Non-command exception C0000005 at 6cf10cc9 in command filter <<<-----------

Thanks for reporting this! There’s a missing null check if you try to iterate some of the models without a context object (e.g.: ‘this’) attached. It’s not something you’d normally do. Regardless, this will get fixed in a future release.

0:000> dx -r1 @$curprocess.@“COM”
@$curprocess.@“COM” : [object Object]
GlobalObjects : Invalid argument to method ‘getModuleSymbol’

Are you running this on Win7? The sample only works on Win8+. A bunch of stuff was refactored out of OLE32 and into COMBASE. If you change the “combase.dll” to “ole32.dll” in the sample, things should probably work. I’ll make sure to get the sample updated to work on Win7+. Thanks!

0:000> dx @$scriptContents.host.getModuleSymbol(“calc.exe” , “WinMain”)
Error: Invalid argument to method ‘getModuleSymbol’

There’s two issues with this. First, getModuleSymbol() returns an object (which requires a type) and not just an address. Public symbols have a lot of type information stripped out. Even for types which remain in the symbols, the linkage between globals and what types they are is often still stripped. The general recommendation on anything that operates on publics is to manually specify the type with the optional type argument. That will override pulling it from the PDB and just trust what the caller says.

Second, getModuleSymbol(…) only works on data symbols (not function ones) at present. I’ll fix this in a future release.

Thanks for the feedback!

@Bill messmer Thanks for the response

[quote 1]
fine no problem just pointed out this seems to be an annoyance

[quote2]
well the Filter expression for lma seems to be
ok but it returns text

0:000> r
kernel32!GetCurrentDirectoryAStub:
779f733c 8bff mov edi,edi

0:000> dx -r2 @$curprocess.Modules.Where (a=> @eip >= a.BaseAddress &&
@eip < a.BaseAddress + a.Size)

@$curprocess.Modules.Where (a=> @eip >= a.BaseAddress && @eip <
a.BaseAddress + a.Size)

[0x0] : C:\Windows\system32\kernel32.dll
BaseAddress : 0x779c0000
Name : C:\Windows\system32\kernel32.dll
Size : 0xd4000

[quote 3] can you confirm my assumption are you trying to get dv /v
for public symbol

yes you can say so

for a function with private pdb when i am on function start doing dv /v gets me
this

0:000> .fnent @$ip
Debugger function entry 0247a8c8 for:
e:\test\structy\strumemb.cpp @ 11](013d1260) strumemb!dosomething
| (013d12e0) strumemb!main
Exact matches:
strumemb!dosomething (struct _MYSTRU *, struct _MYSTRU *, struct _MYSTRU *)

OffStart: 00001260
ProcSize: 0x7f
Prologue: 0x6
Params: 0n3 (0xc bytes)
Locals: 0n3 (0xc bytes)
Non-FPO
0:000> dv /v
0013f7ac i = 0x014158b8
0013f7b0 j = 0x014158b8
0013f7b4 k = 0x014158b8
0013f798 c = 0x0013f7c0
0013f7a0 b = 0x013d1462
0013f79c a = 0x0013f7c0

and my extension gives me

0:000> !fnproto
no of entries = 1 13d1260

[CSP + 00] [dosomething(Num Args = 03) Returns to] = 013d130b
[ESP + 04] [PMystru i] = 014158b8
[ESP + 08] [PMystru j] = 014158b8
[ESP + 0c] [PMystru k )] = 014158b8

so yes it almost matches but for a function in ntdll for which i have
only public symbols

i cannot get the argument names and my extension fulfills it

here is what my extension would print for RtlInitUnicodeString() in
ntdll or ntkrpamp

0:000> rM0
ntdll!RtlInitUnicodeString:
778a4168 57 push edi

0:000> kb2
# ChildEBP RetAddr Args to Child
00 001deda0 75c5346c 00000014 00000000 001deddc ntdll!RtlInitUnicodeString
01 001df02c 75c533c6 001df040 00000800 00000100
KERNELBASE!QueryRegDefaultSortingVersion+0x62

0:000> dd esp l4
001ded7c 75c4d239 001ded94 00000000 001df040

0:000> dv /v
Unable to enumerate locals, Win32 error 0n87
Private symbols (symbols.pri) are required for locals.
Type “.hh dbgerr005” for details.

0:000> !fnproto
no of entries = 1 778a4168

[CSP + 00] [RtlInitUnicodeString(Num Args = 02) Returns to] = 75c4d239
[ESP + 04] [__out PUNICODE_STRING DestinationString] = 001ded94
[ESP + 08] [__in_z_opt __drv_aliasesMem PCWSTR SourceSt] = 00000000


did you do any dx @$foo = @$scriptcontents.blah() and unload the script ??
may be yes i might have done that i did do a lot of dx @$foo =
something but dont remember if it were results from scripts so
probably that answers my question thanks

are you running this on win7

yes

i changed combase.dll to ole32.dll but it still appears to be not working

0:000> dx @$scriptContents.comProcessExtension.COM
@$scriptContents.comProcessExtension.COM : [object Object]
GlobalObjects : Invalid argument to method ‘getModuleSymbol’

0:000> .shell - cat blah.js | grep -i getmodulesymbol

Unknown option ’ '
<.shell waiting 1 second(s) for process>
gipAllocator = host.getModuleSymbol(“ole32.dll”,
“CGIPTable::_palloc”, “CPageAllocator”, gipProcess)._pgalloc;
gipAllocator = host.getModuleSymbol(“ole32.dll”,
“GIPEntry::_palloc”, “CPageAllocator”, gipProcess)._pgalloc;
.shell: Process exited
Press ENTER to continue
<.shell waiting 1 second(s) for process>
<.shell process may need input>

yeah i understood from doc that i need to provide an optional typeinfo

but when i tried it some variations like this i couldnt find any result

0:000> dx @$scriptContents.host.getModuleSymbol(“ntdll.dll” , “_PEB” , _PEB)
Error: Unspecified error (0x80004005)
0:000> dx @$scriptContents.host.getModuleSymbol(“ntdll.dll” , “_PEB” , “_PEB”)
Error: Invalid argument to method ‘getModuleSymbol’
0:000> dx @$scriptContents.host.getModuleSymbol(“ntdll.dll” , _PEB , “_PEB”)
Error: Unspecified error (0x80004005)
0:000> dx @$scriptContents.host.getModuleSymbol(“ntdll.dll” , _PEB , _PEB)
Error: Unspecified error (0x80004005)
0:000> dx @$scriptContents.host.getModuleSymbol(“ntdll.dll” , 0x7ffd8000 , _PEB)
Error: Unspecified error (0x80004005)
0:000> dx @$scriptContents.host.getModuleSymbol(“ntdll.dll” ,
0x7ffd8000 , “_PEB”)
@$scriptContents.host.getModuleSymbol(“ntdll.dll” , 0x7ffd8000 , “_PEB”)
0:000> dx @$scriptContents.host.getModuleSymbol(“ntdll.dll” ,
“0x7ffd8000” , “_PEB”)
Error: Invalid argument to method ‘getModuleSymbol’

and in case of “WinMain” what would be the Typename ?? “Function”

On 11/10/16, xxxxx@microsoft.com wrote:
> I’ll try to go through these one by one. Please remember that this is a
> pre-release/preview of the scripting functionality. Thanks for taking the
> time to try this out and report the issues you’ve been having.
>
>> btw is it possible to eliminate the unload and reload or have a
>> .scriptreload command that unloads an old script with same
>> name/path/whateverunique and reloads it ?
>
> At the moment, you do have to .scriptunload and .scriptload. There are
> better experiences around some of this coming at some point in the future.
>
>
>> now i need to find the Module That Contains the Address of Current
>> Instruction pointer
>
> Remember that …ExecuteCommand(…) is intended to be an escape hatch for
> things which do not yet have an object model against them. It’s the intent
> that eventually for most data manipulation operations, you should not have
> to go back to parsing text from command output of the debugger. Modules do
> have an object model (the .Modules node off any process object). The below
> example will show this (albeit there is a problem with using ‘<’ and ‘>’ in
> this context). The 64-bit lib is missing a comparison function which will
> not go back to JavaScript number (that’ll get fixed):
>
> function findModuleAtAddr(addr)
> {
> //
> // The ‘<’ and ‘>’ comparisons are unsafe as they will convert to JS
> // number which is 53 bit ordinal. If you need this before there’s an
> // available method, you can always write a small comparator using
> // .getHighPart() and .getLowPart()
> //
> return host.currentProcess.Modules.Where(m => addr >= m.BaseAddress &&
> addr < m.BaseAddress.add(m.Size));
> }
>
> 0:000> k1
> # Child-SP RetAddr Call Site
> 00 000000471cc7f880 00007ff6ac283d93 USER32!GetMessageW+0x26
>
> 0:000> dx -r2 @$scriptContents.findModuleAtAddr(@rip)
> @$scriptContents.findModuleAtAddr(@rip)
> [0x0] : C:\Windows\System32\USER32.dll
> BaseAddress : 0x7ffbd1ca0000
> Name : C:\Windows\System32\USER32.dll
> Size : 0x165000
>
>> I am trying to confirm if the current instruction is at start of a
>> function in a module
>> whose public pdb contains Debugger Function Entry For The Specific
>> Address and if it was
>> and i am on break would like to dump the parameters in thier respective
>> type
>
> Yes – what you’re trying to do here will require escaping out to
> .ExecuteCommand(…) and parsing… or (eventually) writing some C++ code
> that adds new JavaScript accessible functionality. We are working on C/C++
> APIs for a future SDK which would allow you to extend the model (and hence
> call from JavaScript).
>
> Before I comment further on this, I wasn’t sure that I completely understood
> the scenario. Maybe with a bit of playing around, I do, but could you
> please confirm my assumption here:
>
> Are you effectively trying to get ‘dv (/v)’ on public symbols for function
> parameters?
>
>> following up when i have no scripts loaded what these lingering links
>> in dx @$scripts contain
>
> That should only happen when you have a reference into the script still
> lingering. For instance, if you utilize dx to assign a pseudo variable to a
> JavaScript object (dx @$myVar = @$scriptContents.someObject), the script
> cannot disappear out from underneath the variable. When you unload the
> script, you can no longer get to its contents through @$scriptContents, it’s
> object model modifications disappear, etc… but the script context doesn’t
> go away until there’s nothing holding onto it. That said, you should not be
> seeing this just loading and unloading the kinds of scripts you’ve been
> showing here.
>
> I’ll look into this.
>
>> has this been exposed yet ?
>
>> 0:000> dx
>> @$scriptContents.host.getNamedModel(“Debugger.Models.Parameters”)
>> @$scriptContents.host.getNamedModel(“Debugger.Models.Parameters”)
>
>
>> it appears some other models have been exposed
>>
>> 0:000> dx -r1
>> @$scriptContents.host.getNamedModel(“Debugger.Models.Process”)
>> @$scriptContents.host.getNamedModel(“Debugger.Models.Process”)
>> Name : Unexpected failure to dereference object
>
> Yes, “Debugger.Models.Parameters” is exposed. There’s no properties on the
> general notion of “Parameters” (hence you don’t see anything). You also get
> the “Unexpected failure to dereference object” because you’re looking at
> what’s effectively a “prototype object” for process. There’s no context
> object (‘this’ pointer) attached… and hence the ‘Name’ property fails
> when it sees what amounts to a null this. On ‘Parameters’, all the actual
> parameters for a given stack frame are on what amounts to the ‘this’ object.
> The prototype is empty. This matters less now than it will later.
>
> The idea for most of these is that you extend them in JavaScript. Try
> loading the following script and then looking at the current process:
>
> function initializeScript()
> {
> class myExtension
> {
> get NewProperty() { return “Hello World”; }
> }
>
> return [new host.namedModelParent(myExtension,
> “Debugger.Models.Process”)];
> }
>
> 0:008> dx @$curprocess
> @$curprocess : notepad.exe
> Name : notepad.exe
> Id : 0x4a28
> Threads
> Modules
> Environment
> 0:008> .load jsprovider.dll
> 0:008> .scriptload g:\junk\js1\procExt.js
> JavaScript script successfully loaded from ‘g:\junk\js1\procExt.js’
> 0:008> dx @$curprocess
> @$curprocess : notepad.exe
> Name : notepad.exe
> Id : 0x4a28
> Threads
> Modules
> Environment
> NewProperty : Hello World
>
>> 0:000> dx @$scriptContents.host.getNamedModel(“Debugger.Models.Modules”)
>> <----crash here
>> @$scriptContents.host.getNamedModel(“Debugger.Models.Modules”)
>> Non-command exception C0000005 at 6cf10cc9 in command filter
>> <<<-----------
>
> Thanks for reporting this! There’s a missing null check if you try to
> iterate some of the models without a context object (e.g.: ‘this’) attached.
> It’s not something you’d normally do. Regardless, this will get fixed in a
> future release.
>
>> 0:000> dx -r1 @$curprocess.@“COM”
>> @$curprocess.@“COM” : [object Object]
>> GlobalObjects : Invalid argument to method ‘getModuleSymbol’
>
> Are you running this on Win7? The sample only works on Win8+. A bunch of
> stuff was refactored out of OLE32 and into COMBASE. If you change the
> “combase.dll” to “ole32.dll” in the sample, things should probably work.
> I’ll make sure to get the sample updated to work on Win7+. Thanks!
>
>> 0:000> dx @$scriptContents.host.getModuleSymbol(“calc.exe” , “WinMain”)
>> Error: Invalid argument to method ‘getModuleSymbol’
>
> There’s two issues with this. First, getModuleSymbol() returns an object
> (which requires a type) and not just an address. Public symbols have a lot
> of type information stripped out. Even for types which remain in the
> symbols, the linkage between globals and what types they are is often still
> stripped. The general recommendation on anything that operates on publics
> is to manually specify the type with the optional type argument. That will
> override pulling it from the PDB and just trust what the caller says.
>
> Second, getModuleSymbol(…) only works on data symbols (not function ones)
> at present. I’ll fix this in a future release.
>
> Thanks for the feedback!
>
> —
> WINDBG is sponsored by OSR
>
> OSR is hiring!! Info at http://www.osr.com/careers
>
>
> MONTHLY seminars on crash dump analysis, WDF, Windows internals and software
> drivers!
> Details at http:
>
> To unsubscribe, visit the List Server section of OSR Online at
> http:
></http:></http:>

> [quote2]

well the Filter expression for lma seems to be
> ok but it returns text

Not sure I understand what you mean by “ok but it returns text”. You can think of a ‘dx ’ as several steps:

1) evaluate the expression
2) create an object for the result of the expression (or every sub-result in the evaluator)
3) use something conceptually like reflection to display that object to console. For example:

0:000> gu
USER32!GetMessageW+0x26:
00007ffbd1cc4866 8b4b08 mov ecx,dword ptr [rbx+8] ds:00000040ddb0fbb8=00000200
0:000> dx @$matches = @$curprocess.Modules.Where (a=> @rip >= a.BaseAddress && @rip < a.BaseAddress + a.Size)
@$matches = @$curprocess.Modules.Where (a=> @rip >= a.BaseAddress && @rip < a.BaseAddress + a.Size)
[0x0] : C:\Windows\System32\USER32.dll
0:000> dx @$module = @$matches.First()
@$module = @$matches.First() : C:\Windows\System32\USER32.dll
BaseAddress : 0x7ffbd1ca0000
Name : C:\Windows\System32\USER32.dll
Size : 0x165000
0:000> dx @$baseAddr = @$module.BaseAddress
@$baseAddr = @$module.BaseAddress : 0x7ffbd1ca0000
0:000> dx @$baseAddr+1000
@$baseAddr+1000 : 0x7ffbd1ca03e8

In essence, everything evaluated (even sub-expressions) is an object. It only “turns to text” by ‘dx’ displaying it. Anything above can also be done directly in JavaScript:

function findModuleBase(addr)
{
var matches = host.currentProcess.Modules.Where(m => addr >= m.BaseAddress && addr < m.BaseAddress + m.Size);
var module = matches.First();
var baseAddr = module.BaseAddress;

//
// baseAddr is now a 64-bit library type. You can return this from the method and it will return to the dx EE as a 64-bit unsigned value.
//
return baseAddr;
}

0:000> .load jsprovider.dll
0:000> .scriptload g:\junk\js1\modBase.js
JavaScript script successfully loaded from ‘g:\junk\js1\modBase.js’
0:000> .scriptload g:\junk\js1\modBase.js
JavaScript script successfully loaded from ‘g:\junk\js1\modBase.js’
0:000> dx @$scriptContents.findModuleBase(@rip)
@$scriptContents.findModuleBase(@rip) : 0x7ffbd1ca0000
0:000> dx @$secondBase = @$scriptContents.findModuleBase(@rip)
@$secondBase = @$scriptContents.findModuleBase(@rip) : 0x7ffbd1ca0000
0:000> dx @$secondBase+0x1000
@$secondBase+0x1000 : 0x7ffbd1ca1000

> and my extension gives me
>
> 0:000> !fnproto
> no of entries = 1 13d1260

Out of curiousity, where is your !fnproto pulling the signature info from on the publics?

> are you running this on win7
>
> yes
>
> i changed combase.dll to ole32.dll but it still appears to be not working

There’s more than one occurrence of combase.dll in the script. When I change all of them to ole32, it works (at least superficially) on my Win7 machine. The invalid argument error happens becuase it cannot find either the module as named, the symbol as named, or the type as named. As I mentioned before, I’ll try to get the sample updated to work fully and properly on Win7 and not just 8+.

> yeah i understood from doc that i need to provide an optional typeinfo
>
> but when i tried it some variations like this i couldnt find any result
>
> 0:000> dx @$scriptContents.host.getModuleSymbol(“ntdll.dll” , “_PEB” , _PEB)
> Error: Unspecified error (0x80004005)

The arguments to getModule symbol are as follows getModuleSymbol(moduleName, symbolName, [typeName], [contextInheritor]):

The first three arguments are strings and it returns an object which represents that DATA symbol. Maybe getModuleObject(…) might have been better nomenclature. You can’t getModuleSymbol(…) on a type. It needs to be something which is “type + location” (e.g.: a global variable). As a few examples:

// Cast the thing at whatever the address of “CGIPTable::_palloc” in “ole32.dll” to “Ole32!CPageAllocator” and return the object
0:004> dx @$scriptContents.host.getModuleSymbol(“ole32.dll”, “CGIPTable::_palloc”, “CPageAllocator”)
@$scriptContents.host.getModuleSymbol(“ole32.dll”, “CGIPTable::_palloc”, “CPageAllocator”) [Type: CPageAllocator]
[+0x000] _pgalloc [Type: CInternalPageAllocator]
[+0x050] _hHeap : 0x0 [Type: void *]
[+0x058] _cbPerEntry : 0x0 [Type: unsigned __int64]
[+0x060] _lNumEntries : 0 [Type: long]

// Cast the thing at whatever the address of “CGIPTable::_palloc” in “ole32.dll” to “tagMSG” and return the object
0:004> dx @$scriptContents.host.getModuleSymbol(“ole32.dll”, “CGIPTable::palloc", “tagMSG”)
@$scriptContents.host.getModuleSymbol(“ole32.dll”, "CGIPTable::palloc", “tagMSG”) [Type: tagMSG]
[+0x000] hwnd : 0x0 [Type: HWND
*]
[+0x008] message : 0x0 [Type: unsigned int]
[+0x010] wParam : 0x0 [Type: unsigned __int64]
[+0x018] lParam : 0 [Type:__int64]
[+0x020] time : 0x0 [Type: unsigned long]
[+0x024] pt [Type: tagPOINT]

// Cast the thing at whatever the address of “CGIPTable::_palloc” in “ole32.dll” to a function of signature “int __cdecl(int, float, tagMSG)” and return the object
0:004> dx @$scriptContents.host.getModuleSymbol(“ole32.dll”, “CGIPTable::_palloc”, “int__cdecl(int, float, tagMSG)”)
@$scriptContents.host.getModuleSymbol(“ole32.dll”, “CGIPTable::_palloc”, “int __cdecl(int, float, tagMSG)”) [Type: int__cdecl(int,float,tagMSG)]

While that above example is a bit contrived (and silly), you’ll note that the DML link on what gets spit out is a DML link to disassemble and you can right click and get “Open Source File” and “Set Breakpoint [bp]” on the context menu. It’s recognized as a function. Now I will point out that if what’s passed in the ‘symbolName’ argument is indeed a function symbol (e.g.: “WinMain”), this will fail. That’ll get fixed.

If you must presently get a function (or the address) of a function from JavaScript, you can invoke the EE (though such restricts you to C/C++ language features and not LINQ, random WinDbg specific features, etc…). For example:

function getSymbolAddr(sym)
{
return host.evaluateExpression(”(unsigned __int64)(&" + sym + “)”);
}

0:000> u notepad!WinMain
notepad!WinMain
00007ff6`ac283b1c 48895c2410 mov qword ptr [rsp+10h],rbx

0:000> dx @$scriptContents.getSymbolAddr(“WinMain”)
@$scriptContents.getSymbolAddr(“WinMain”) : 0x7ff6ac283b1c

Hope that helps to clear things up!

so i need to make sure i return the proper object instead of whining
that everything is text and there is no sed awk grep in windbg :slight_smile: ok
that makes sense thanks @Bill Messmer

[quote] out of curiosity where you pull siginfo from publics [quote]

no not from public pdb’s I have other sed awk grep ctags combo to get
func sig from headers

i have around 50000 signatures for example i have 8 signatures for
ZwCreateP as below

:\>wc -l fnproto.txt
49547 fnproto.txt

:\>grep ^ZwCreateP fnproto.txt | wc -l
8

:\>grep ^ZwCreateP fnproto.txt | awk “{print $1 , $2 ,$3 ,$4 , $5}”
ZwCreatePagingFile ( In PUNICODE_STRING PageFileName,
ZwCreatePartition ( In_opt HANDLE ParentPartitionHandle,
ZwCreatePort ( Out PHANDLE PortHandle,
ZwCreatePrivateNamespace ( Out PHANDLE NamespaceHandle,
ZwCreateProcess ( Out PHANDLE ProcessHandle,
ZwCreateProcessEx ( Out PHANDLE ProcessHandle,
ZwCreateProfile ( Out PHANDLE ProfileHandle,
ZwCreateProfileEx ( Out PHANDLE ProfileHandle,

:\>

I getline() compare() ,strstr , strchr , strtok split the tokens ,
sprintf_s() m_Control->execute a precooked (.printf " " ," ") which
ouputs the result of .printf to windbg console

sprintf_s(buffer,0x200,“.printf /D "[@$csp l?%x;\">%s + %02x] [ %17s(Num Args = %02d) Returns
to ] = %s%%p%s\n", poi( @$csp
)”,numparams+1,“CSP”,0,Buffer,numparams,“poi(@$csp);u poi(@$csp);\">“,””);
m_Control->Execute(DEBUG_OUTCTL_ALL_CLIENTS,buffer,DEBUG_EXECUTE_DEFAULT);

there are apparently many limitations and hacks in the code-flow

.printf has some limitations on the input string it appears so if the
input string is x chars it will print if the input char is x+1 it will
fail mysterioulsy
saying syntax // cant evaluate // extra char // some other
undecipherable error // etc etc

i can also add function signatures dynamically when i encounter or
reverse some thing like

the second function below doesn’t seem to have any prototype declared
in any headers publicly available

:\>grep -i -r -h --include=*.h RtlpcTo * -A 1
RtlPcToFileHeader(
In PVOID PcValue,

RtlPcToFileHeader(
In PVOID PcValue,

:\>grep -i -r -h --include=*.h RtlpFind * -A 1

:\>

but the pdb does have a function entry for this

0:000> .fnent ntdll!RtlpFindUnicodeStringInSection
Debugger function entry 0295b6b8 for:
(770ed270) ntdll!RtlpFindUnicodeStringInSection | (770ed370)
ntdll!RtlFindNextActivationContextSection
Exact matches:
ntdll!RtlpFindUnicodeStringInSection ()

OffStart: 0005d270
ProcSize: 0x306
Prologue: 0xa
Params: 0n8 (0x20 bytes)
Locals: 0n11 (0x2c bytes)
Non-FPO
0:000> x ntdll!RtlpFindUnicodeStringInSection
770ed270 ntdll!RtlpFindUnicodeStringInSection ()

so i can add a dummy function with 8 args which i can rename at
leisure but i wont be have to be blind when i see it again

int
__stdcall
RtlpFindUnicodeStringInSection (
DWORD RenameMe[0n01],
DWORD RenameMe[0n02],
DWORD RenameMe[0n03],
DWORD RenameMe[0n04],
DWORD RenameMe[0n05],
DWORD RenameMe[0n06],
DWORD RenameMe[0n07],
DWORD RenameMe[0n08] );

if (Entries != 0 )
{
m_Symbols3->GetSymbolEntryString (
&Ids,0,Buffer,sizeof(Buffer),&StringSize);
}
if ( printfninfo(Buffer) == false)
{
if(Entries != 0)
{
char buff[0x100];
ULONG recbytes;
unsigned long argnum;
m_Control->OutputPrompt(DEBUG_OUTCTL_ALL_CLIENTS,“type
"yes""Number" like "yes 4" \n”);
m_Control->Input(buff,0x90,&recbytes);
if ( ( strncmp(buff,“yes”, 3) == 0 ) && (
(strchr(buff,’ ‘) - buff ) == 3 ) )
{
argnum = strtoul( (strchr(buff,’ ‘)+SKIP_TAB),0,16 );
if ( ( argnum != 0 ) && ( argnum != ULONG_MAX ) )
{
addfninfo(Buffer , argnum);
}
else
{
dprintf(“invalid response addfninfo request\n”);
}
}
else
{
dprintf(“invalid response @ addfninfo request\n”);
}
}
}

where addfninfo does this

if you want to see the spaghetti or download a tarball of the half
baked biscuits drop a hint offline

[quote 3] there are more than one occurance

yes i changed both ( the .shell - cat blah.js shows i changed both in
the post above )
and it didnt seem to work well ill test it when you signal you have
confirmed it works in win 7

ok so the intput ot getmoduleSymbol needs to be a global with type and
location ie i need a private symbol info

that is i can cast some thing to ULONG or SOME_ARCANE_TYPE only if i
have it in pdb as ULONG

0:000> x /v /t /f /d /z ole32!CGIPTable*

pub global 76608688 0 ole32!CGIPTable::vftable'<br>= <no type information><br>prv global 767061f0 4 unsigned long<br>ole32!CGIPTable::_dwCurrSeqNo = 0x100<br>prv global 76600448 4 <function> *<br>ole32!CGIPTable::_palloc$initializer$ = 0x765ff96f<br>prv global 76708994 4 int ole32!CGIPTable::_fInNAUninit = 0n0<br>prv global 76708990 4 int ole32!CGIPTable::_fInRevokeAll = 0n0<br>prv global 76707368 30 class COleStaticMutexSem<br>ole32!CGIPTable::_mxs = class COleStaticMutexSem<br>prv global 76706c94 34 class CPageAllocator<br>ole32!CGIPTable::_palloc = class CPageAllocator<br>prv global 76706a08 44 struct tagGIPEntry<br>ole32!CGIPTable::_InUseHead = struct tagGIPEntry<br><br>first two will work but not the third because it has no type<br><br>0:000&gt; dx @$scriptContents.host.getModuleSymbol("ole32.dll",<br>"CGIPTable::_dwCurrSeqNo", "unsigned long")<br>@$scriptContents.host.getModuleSymbol("ole32.dll",<br>"CGIPTable::_dwCurrSeqNo", "unsigned long") : 0x100<br><br>0:000&gt; dx @$scriptContents.host.getModuleSymbol("ole32.dll",<br>"CGIPTable::_dwCurrSeqNo", "_LARGE_INTEGER").u<br>@$scriptContents.host.getModuleSymbol("ole32.dll",<br>"CGIPTable::_dwCurrSeqNo", "_LARGE_INTEGER").u [Type:<br>_LARGE_INTEGER::<unnamed-type-u>]<br> [+0x000] LowPart : 0x100 [Type: unsigned long]<br> [+0x004] HighPart : 0 [Type: long]<br><br>0:000&gt; dx @$scriptContents.host.getModuleSymbol("ole32.dll",<br>"CGIPTable::vftable’", “_LARGE_INTEGER”).u
Error: Invalid argument to method ‘getModuleSymbol’

0:000> dx @$scriptContents.host.getModuleSymbol(“ole32.dll”,
"CGIPTable::vftable'", "int")<br>Error: Invalid argument to method 'getModuleSymbol'<br>0:000&gt; dx @$scriptContents.host.getModuleSymbol("ole32.dll",<br>"CGIPTable::_dwCurrSeqNo", "int")<br>@$scriptContents.host.getModuleSymbol("ole32.dll",<br>"CGIPTable::_dwCurrSeqNo", "int") : 0x100<br><br>the last example of extensing always seem to be elusive here in my<br>tests earlier as well as now<br><br>:\&gt;echo file contents of js\gsa.js &amp; cat js\gsa.js<br><br>file contents of js\gsa.js<br>function gsa(sym)<br>{<br> return host.evaluateExpression("(unsigned__int64)(&amp;" + sym + ")");<br>}<br><br>:\&gt;echo file contents of js\rungsa.txt &amp; cat js\rungsa.txt<br><br>file contents of js\rungsa.txt<br>.load jsprovider<br>.scriptload js\gsa.js<br>.echo "Hi my test of gsa starts here"<br>dx @$scriptContents.gsa("WinMain")<br>dx @$scriptContents.gsa(\"WinMain\")<br>dx @$scriptContents.gsa( @$ip )<br>dx @$scriptContents.gsa( 0x7ffd0000 )<br>dx @$scriptContents.gsa( "0x7ffd0000" )<br>dx @$scriptContents.host.evaluateExpression( "(long) 0x80000001" ),x<br>q<br><br>:\&gt;cdb -c "$$&gt;a&lt; js\rungsa.txt" calc<br><br>Microsoft (R) Windows Debugger Version 10.0.14951.1001 X86<br><br>0:000&gt; cdb: Reading initial command '$$&gt;a&lt; js\rungsa.txt'<br>JavaScript script successfully loaded from<br>'E:\windjs\wdbg\Debuggers\x86\js\gsa.js'<br>Hi my test of gsa starts here<br>xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx<br> ***Either you specified an unqualified symbol, or your debugger*** <br>xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx<br> ***Type referenced: WinMain*** <br><br>Error: Unable to bind name 'WinMain'<br>Error: Expected expression at '\"WinMain\")'<br>Error: Expected expression at '[object Object])'<br>Error: Unable to take address of object<br>Error: Unable to take address of object<br>@$scriptContents.host.evaluateExpression( "(long) 0x80000001" ),x :<br>0xffffffff80000001<br>quit:<br><br>:<br><br>On 11/11/16, xxxxx@microsoft.com <xxxxx> wrote:<br>&gt;&gt; [quote2]<br>&gt;&gt; [] well the Filter expression for lma <addr> seems to be<br>&gt;&gt; ok but it returns text<br>&gt;<br>&gt; Not sure I understand what you mean by "ok but it returns text". You can<br>&gt; think of a 'dx <expression>' as several steps:<br>&gt;<br>&gt; 1) evaluate the expression<br>&gt; 2) create an object for the result of the expression (or every sub-result in<br>&gt; the evaluator)<br>&gt; 3) use something **conceptually like** reflection to display that object to<br>&gt; console. For example:<br>&gt;<br>&gt; 0:000&gt; gu<br>&gt; USER32!GetMessageW+0x26:<br>&gt; 00007ffbd1cc4866 8b4b08 mov ecx,dword ptr [rbx+8]
> ds:00000040ddb0fbb8=00000200<br>&gt; 0:000&gt; dx @$matches = @$curprocess.Modules.Where (a=&gt; @rip &gt;= a.BaseAddress<br>&gt; &amp;&amp; @rip &lt; a.BaseAddress + a.Size)<br>&gt; @$matches = @$curprocess.Modules.Where (a=&gt; @rip &gt;= a.BaseAddress &amp;&amp; @rip &lt;<br>&gt; a.BaseAddress + a.Size)<br>&gt; [0x0] : C:\Windows\System32\USER32.dll<br>&gt; 0:000&gt; dx @$module = @$matches.First()<br>&gt; @$module = @$matches.First() :<br>&gt; C:\Windows\System32\USER32.dll<br>&gt; BaseAddress : 0x7ffbd1ca0000<br>&gt; Name : C:\Windows\System32\USER32.dll<br>&gt; Size : 0x165000<br>&gt; 0:000&gt; dx @$baseAddr = @$module.BaseAddress<br>&gt; @$baseAddr = @$module.BaseAddress : 0x7ffbd1ca0000<br>&gt; 0:000&gt; dx @$baseAddr+1000<br>&gt; @$baseAddr+1000 : 0x7ffbd1ca03e8<br>&gt;<br>&gt; In essence, everything evaluated (even sub-expressions) is an object. It<br>&gt; only "turns to text" by 'dx' displaying it. Anything above can also be done<br>&gt; directly in JavaScript:<br>&gt;<br>&gt; function findModuleBase(addr)<br>&gt; {<br>&gt; var matches = host.currentProcess.Modules.Where(m =&gt; addr &gt;=<br>&gt; m.BaseAddress &amp;&amp; addr &lt; m.BaseAddress + m.Size);<br>&gt; var module = matches.First();<br>&gt; var baseAddr = module.BaseAddress;<br>&gt;<br>&gt; //<br>&gt; // baseAddr is now a 64-bit library type. You can return this from the<br>&gt; method and it will return to the dx EE as a 64-bit unsigned value.<br>&gt; //<br>&gt; return baseAddr;<br>&gt; }<br>&gt;<br>&gt; 0:000&gt; .load jsprovider.dll<br>&gt; 0:000&gt; .scriptload g:\junk\js1\modBase.js<br>&gt; JavaScript script successfully loaded from 'g:\junk\js1\modBase.js'<br>&gt; 0:000&gt; .scriptload g:\junk\js1\modBase.js<br>&gt; JavaScript script successfully loaded from 'g:\junk\js1\modBase.js'<br>&gt; 0:000&gt; dx @$scriptContents.findModuleBase(@rip)<br>&gt; @$scriptContents.findModuleBase(@rip) : 0x7ffbd1ca0000<br>&gt; 0:000&gt; dx @$secondBase = @$scriptContents.findModuleBase(@rip)<br>&gt; @$secondBase = @$scriptContents.findModuleBase(@rip) : 0x7ffbd1ca0000<br>&gt; 0:000&gt; dx @$secondBase+0x1000<br>&gt; @$secondBase+0x1000 : 0x7ffbd1ca1000<br>&gt;<br>&gt;&gt; and my extension gives me<br>&gt;&gt;<br>&gt;&gt; 0:000&gt; !fnproto<br>&gt;&gt; no of entries = 1 13d1260<br>&gt;<br>&gt; Out of curiousity, where is your !fnproto pulling the signature info from on<br>&gt; the publics?<br>&gt;<br>&gt;&gt; are you running this on win7<br>&gt;&gt;<br>&gt;&gt; yes<br>&gt;&gt;<br>&gt;&gt; i changed combase.dll to ole32.dll but it still appears to be not working<br>&gt;<br>&gt; There's more than one occurrence of combase.dll in the script. When I<br>&gt; change all of them to ole32, it works (at least superficially) on my Win7<br>&gt; machine. The invalid argument error happens becuase it cannot find either<br>&gt; the module as named, the symbol as named, or the type as named. As I<br>&gt; mentioned before, I'll try to get the sample updated to work fully and<br>&gt; properly on Win7 and not just 8+.<br>&gt;<br>&gt;&gt; yeah i understood from doc that i need to provide an optional typeinfo<br>&gt;&gt;<br>&gt;&gt; but when i tried it some variations like this i couldnt find any result<br>&gt;&gt;<br>&gt;&gt; 0:000&gt; dx @$scriptContents.host.getModuleSymbol("ntdll.dll" , "_PEB" ,<br>&gt;&gt; _PEB)<br>&gt;&gt; Error: Unspecified error (0x80004005)<br>&gt;<br>&gt; The arguments to getModule symbol are as follows getModuleSymbol(moduleName,<br>&gt; symbolName, [typeName], [contextInheritor]):<br>&gt;<br>&gt; The first three arguments are **strings** and it returns an object which<br>&gt; represents that **DATA** symbol. Maybe getModuleObject(...) might have been<br>&gt; better nomenclature. You can't getModuleSymbol(...) on a type. It needs to<br>&gt; be something which is "type + location" (e.g.: a global variable). As a few<br>&gt; examples:<br>&gt;<br>&gt; // Cast the thing at whatever the address of "CGIPTable::_palloc" in<br>&gt; "ole32.dll" to "Ole32!CPageAllocator" and return the object<br>&gt; 0:004&gt; dx @$scriptContents.host.getModuleSymbol("ole32.dll",<br>&gt; "CGIPTable::_palloc", "CPageAllocator")<br>&gt; @$scriptContents.host.getModuleSymbol("ole32.dll", "CGIPTable::_palloc",<br>&gt; "CPageAllocator") [Type: CPageAllocator]<br>&gt; [+0x000] _pgalloc [Type: CInternalPageAllocator]<br>&gt; [+0x050] _hHeap : 0x0 [Type: void *]<br>&gt; [+0x058] _cbPerEntry : 0x0 [Type: unsigned __int64]<br>&gt; [+0x060] _lNumEntries : 0 [Type: long]<br>&gt;<br>&gt; // Cast the thing at whatever the address of "CGIPTable::_palloc" in<br>&gt; "ole32.dll" to "tagMSG" and return the object<br>&gt; 0:004&gt; dx @$scriptContents.host.getModuleSymbol("ole32.dll",<br>&gt; "CGIPTable::_palloc", "tagMSG")<br>&gt; @$scriptContents.host.getModuleSymbol("ole32.dll", "CGIPTable::_palloc",<br>&gt; "tagMSG") [Type: tagMSG]<br>&gt; [+0x000] hwnd : 0x0 [Type: HWND__ *]<br>&gt; [+0x008] message : 0x0 [Type: unsigned int]<br>&gt; [+0x010] wParam : 0x0 [Type: unsigned __int64]<br>&gt; [+0x018] lParam : 0 [Type:__int64]<br>&gt; [+0x020] time : 0x0 [Type: unsigned long]<br>&gt; [+0x024] pt [Type: tagPOINT]<br>&gt;<br>&gt;<br>&gt; // Cast the thing at whatever the address of "CGIPTable::_palloc" in<br>&gt; "ole32.dll" to a function of signature "int __cdecl(int, float, tagMSG)" and<br>&gt; return the object<br>&gt; 0:004&gt; dx @$scriptContents.host.getModuleSymbol("ole32.dll",<br>&gt; "CGIPTable::_palloc", "int__cdecl(int, float, tagMSG)")<br>&gt; @$scriptContents.host.getModuleSymbol("ole32.dll", "CGIPTable::_palloc",<br>&gt; "int __cdecl(int, float, tagMSG)") [Type: int<br>&gt;__cdecl(int,float,tagMSG)]<br>&gt;<br>&gt; While that above example is a bit contrived (and silly), you'll note that<br>&gt; the DML link on what gets spit out is a DML link to disassemble and you can<br>&gt; right click and get "Open Source File" and "Set Breakpoint [bp]" on the<br>&gt; context menu. It's recognized as a function. Now I will point out that if<br>&gt; what's passed in the 'symbolName' argument is indeed a function symbol<br>&gt; (e.g.: "WinMain"), this will fail. That'll get fixed.<br>&gt;<br>&gt; If you must presently get a function (or the address) of a function from<br>&gt; JavaScript, you can invoke the EE (though such restricts you to C/C++<br>&gt; language features and not LINQ, random WinDbg specific features, etc...).<br>&gt; For example:<br>&gt;<br>&gt; function getSymbolAddr(sym)<br>&gt; {<br>&gt; return host.evaluateExpression("(unsigned __int64)(&amp;" + sym + ")");<br>&gt; }<br>&gt;<br>&gt; 0:000&gt; u notepad!WinMain<br>&gt; notepad!WinMain<br>&gt; 00007ff6ac283b1c 48895c2410 mov qword ptr [rsp+10h],rbx
>
> 0:000> dx @$scriptContents.getSymbolAddr(“WinMain”)
> @$scriptContents.getSymbolAddr(“WinMain”) : 0x7ff6ac283b1c
>
> Hope that helps to clear things up!
>
> —
> WINDBG is sponsored by OSR
>
> OSR is hiring!! Info at http://www.osr.com/careers
>
>
> MONTHLY seminars on crash dump analysis, WDF, Windows internals and software
> drivers!
> Details at http:
>
> To unsubscribe, visit the List Server section of OSR Online at
> http:
></http:></http:>

Thanks for the info about the extension. It’s unfortunate that you need to jump through so many hoops to get parameter values on publics. In regards to your other questions:

first two will work but not the third because it has no type

This isn’t because it has no type. This is because the lookup of *::`vftable’ in the global scope of the module fails. I need to look into why this is. There are plenty of untyped things that this will work fine on (where the global’s type has been removed from the public symbols). As an example:

0: kd> x nt!*PsIdleProcess*
fffff800`e1d50128 nt!PsIdleProcess =
0: kd> .load jsprovider.dll
0: kd> .scriptload g:\junk\js1\findmod.js
JavaScript script successfully loaded from ‘g:\junk\js1\findmod.js’
0: kd> dx @$scriptContents.host.getModuleSymbol(“nt”, “PsIdleProcess”, “_EPROCESS *”)
@$scriptContents.host.getModuleSymbol(“nt”, “PsIdleProcess”, “_EPROCESS *”) : 0xfffff800e1d493c0 [Type: _EPROCESS *]
[+0x000] Pcb [Type: _KPROCESS]
[+0x2c8] ProcessLock [Type: _EX_PUSH_LOCK]
[+0x2d0] CreateTime : {0} [Type: _LARGE_INTEGER]


> dx @$scriptContents.gsa(“WinMain”)
> dx @$scriptContents.gsa("WinMain")
> dx @$scriptContents.gsa( @$ip )
> dx @$scriptContents.gsa( 0x7ffd0000 )
> dx @$scriptContents.gsa( “0x7ffd0000” )
> dx @$scriptContents.host.evaluateExpression( “(long) 0x80000001” ),x

Keep in mind with the JavaScript function calling host.evaluateExpression on these, it’s effectively doing a dx on the concatenation of

“(unsigned __int64)(&”

“)”

Your examples would be:

…“WinMain” : dx (unsigned__int64)(&WinMain)
If you don’t have unqualified loads on or have already loaded symbols for whatever contains WinMain, this won’t work (same as if you had just typed “u WinMain”). I suggested this as a temporary workaround. GetModuleSymbol will be fixed to deal with function symbols. EvaluateExpression ONLY allows language syntax (which means no “module!”) for a variety of reasons.

…"WinMain" : [Illegal – what’s "WinMain"]

…@$ip : dx (unsigned __int64)(&[Object Object])
The above occurs because we have no default string conversion on pointers, so it goes to JavaScript’s object prototype conversion which isn’t very useful. The resulting expression passed to the EE is a syntax error

…0x7ffd0000 : dx (unsigned__int64)(&0x7ffd0000)
You can’t take the address of a numeric literal. Hence the error

…“0x7ffd0000”: dx (unsigned __int64)(&“0x7ffd0000”)
You can’t take the address of a string literal in the EE. Hence the error.

just a query

how can i do this in windbg cmd window

0:000> .settings set Input.UseExtensionEvaluatorForCpp
Debugger.Settings.Input.UseExtensionEvaluatorForCpp : true
0:000> ?? @$modbase
@$modbase : 0x850000
Length : 0x8
0:000> dx @$modbase
@$modbase : 0x850000
Length : 0x8
0:000> ?? @$modsize
@$modsize : 0xc0000
Length : 0x7
0:000> dx @$modsize
@$modsize : 0xc0000
Length : 0x7
0:000> .writemem c:\foo.dmp @$modbase @$modsize
Bad register error at ‘@$modbase @$modsize’

i wrote a js like this and it seems to work but doing it in cmd window
doesnt seem to work

function wrimem() {
var runme = host.namespace.Debugger.Utility.Control.ExecuteCommand;
var mbcomm = host.namespace.Debugger.Sessions[0].Processes.First().Modules.First();
var modbase = mbcomm.BaseAddress.toString();
var modsize = mbcomm.Size.toString()
var cmdstr = ".writemem c:\test.dump “+ modbase + " L?” + modsize;
return runme(cmdstr);
}

0:000> ?? @$scriptContents.wrimem()
@$scriptContents.wrimem()
[0x0] : Writing c0000 bytes.

powershell -c “"{0:x}" -f (get-item c:\test.dump).length”

c0000

On 11/12/16, xxxxx@microsoft.com wrote:
> Thanks for the info about the extension. It’s unfortunate that you need to
> jump through so many hoops to get parameter values on publics. In regards
> to your other questions:
>
>> first two will work but not the third because it has no type
>
> This isn’t because it has no type. This is because the lookup of
> *::vftable' in the global scope of the module fails. I need to look into<br>&gt; why this is. There are plenty of untyped things that this will work fine on<br>&gt; (where the global's type has been removed from the public symbols). As an<br>&gt; example:<br>&gt;<br>&gt; 0: kd&gt; x nt!*PsIdleProcess*<br>&gt; fffff800e1d50128 nt!PsIdleProcess =
> 0: kd> .load jsprovider.dll
> 0: kd> .scriptload g:\junk\js1\findmod.js
> JavaScript script successfully loaded from ‘g:\junk\js1\findmod.js’
> 0: kd> dx @$scriptContents.host.getModuleSymbol(“nt”, “PsIdleProcess”,
> “_EPROCESS *”)
> @$scriptContents.host.getModuleSymbol(“nt”, “PsIdleProcess”, “_EPROCESS *”)
> : 0xfffff800e1d493c0 [Type: _EPROCESS *]
> [+0x000] Pcb [Type: _KPROCESS]
> [+0x2c8] ProcessLock [Type: _EX_PUSH_LOCK]
> [+0x2d0] CreateTime : {0} [Type: _LARGE_INTEGER]
> …
>
>
>> dx @$scriptContents.gsa(“WinMain”)
>> dx @$scriptContents.gsa("WinMain")
>> dx @$scriptContents.gsa( @$ip )
>> dx @$scriptContents.gsa( 0x7ffd0000 )
>> dx @$scriptContents.gsa( “0x7ffd0000” )
>> dx @$scriptContents.host.evaluateExpression( “(long) 0x80000001” ),x
>
> Keep in mind with the JavaScript function calling host.evaluateExpression on
> these, it’s effectively doing a dx on the concatenation of
>
> “(unsigned __int64)(&”
>
> “)”
>
> Your examples would be:
>
> …“WinMain” : dx (unsigned__int64)(&WinMain)
> If you don’t have unqualified loads on or have already loaded symbols
> for whatever contains WinMain, this won’t work (same as if you had just
> typed “u WinMain”). I suggested this as a temporary workaround.
> GetModuleSymbol will be fixed to deal with function symbols.
> EvaluateExpression ONLY allows language syntax (which means no “module!”)
> for a variety of reasons.
>
> …"WinMain" : [Illegal – what’s "WinMain"]
>
> …@$ip : dx (unsigned __int64)(&[Object Object])
> The above occurs because we have no default string conversion on
> pointers, so it goes to JavaScript’s object prototype conversion which isn’t
> very useful. The resulting expression passed to the EE is a syntax error
>
> …0x7ffd0000 : dx (unsigned__int64)(&0x7ffd0000)
> You can’t take the address of a numeric literal. Hence the error
>
> …“0x7ffd0000”: dx (unsigned __int64)(&“0x7ffd0000”)
> You can’t take the address of a string literal in the EE. Hence the
> error.
>
> —
> WINDBG is sponsored by OSR
>
> OSR is hiring!! Info at http://www.osr.com/careers
>
>
> MONTHLY seminars on crash dump analysis, WDF, Windows internals and software
> drivers!
> Details at http:
>
> To unsubscribe, visit the List Server section of OSR Online at
> http:
></http:></http:>