From: Richard Lewis Haggard Richard Lewis on
Can WinDbg's script processor do string processing and use the results as
addresses? Here's an example of what I'd like to do -

I want to know when ssonsvr.exe has terminated. To do this, I want to
monitor writes to the Type field of the object header of the process object.
I can manually do this with the following WinDbg commands:

First, getting the EPROCESS address of ssonsvr.exe -

kd> !process 0 0 ssonsvr.exe
PROCESS 85d1a020 SessionId: 0 Cid: 094c Peb: 7ffde000 ParentCid: 0910
DirBase: 24240560 ObjectTable: e1047890 HandleCount: 24.
Image: ssonsvr.exe

The number after the string 'PROCESS' is the _EPROCESS address that I'm
interested in. Taking that address, I can get the encapsulating object
header. (For demonstration purposes, this is done in steps but normally I'd
just take the object address and subtract 0x18 from it to get the same
result.)

First, get the encapsulating object:

kd> !object 85d1a020
Object: 85d1a020 Type: (867c6e38) Process
ObjectHeader: 85d1a008 (old version)
HandleCount: 1 PointerCount: 8

Embedded in the return string is ObjectHeader: and the following address is
where the object header is located. Using that address, we can gain access to
the

kd> dt nt!_OBJECT_HEADER 85d1a008
+0x000 PointerCount : 8
+0x004 HandleCount : 1
+0x004 NextToFree : 0x00000001
+0x008 Type : 0x867c6e38 _OBJECT_TYPE
<snipped for brevity>

When Type changes then the process object is no longer valid so I want to
set a break point when this address is written to. For convenience, I'll go
ahead and write some cosmetic space and follow that with a stack dump. This
is done with

kd> ba w4 85d1a008+8 ".echo *** end of ssonsvr ***;.echo*;kb200"

This break point is the real meat of the matter. Is it possible to write a
WinDbg script that would automate the essentials of the above example?
From: Scott Noone on
I'm not sure that there's any way to do it in the way that you're trying.
There's a different way to approach it that I think might work, I don't have
a live system in front of me to actually try this but I seem to be getting
the right results...

The "Debugger Command Program Examples" section of the docs already has an
example of how to walk the active process list and dump out the image name
of each process. So my idea was to leverage that script to get you want you
want:

$$ Get process list LIST_ENTRY in $t0.
r $t0 = nt!PsActiveProcessHead

$$ Iterate over all processes in list.
..for (r $t1 = poi(@$t0);
(@$t1 != 0) & (@$t1 != @$t0);
r $t1 = poi(@$t1))
{
r? $t2 = #CONTAINING_RECORD(@$t1, nt!_EPROCESS, ActiveProcessLinks);
as /x Procc @$t2

$$ Get image name into $ImageName.
as /ma $ImageName @@c++(&@$t2->ImageFileName[0])

.block
{
$$ Print out the name...
.echo ${$ImageName}

$$ SJN - Start my changes...Match the name that we want?
.if $sicmp("${$ImageName}", "Explorer.exe") == 0
{
$$ Yes! Print out the process address
.echo Found the process at ${Procc}

$$ Calculate the base address of the object header
r? @$t3 = ${Procc} - #FIELD_OFFSET(nt!_OBJECT_HEADER, Body)

$$ Print it out so we can verify
.printf /on "Object header at 0x%p\n", @$t3

$$ Put the address of the type field into t4
r? @$t4 = @$t3 + #FIELD_OFFSET(nt!_OBJECT_HEADER, Type)

$$ Print it out so we can verify
.printf /on "Setting bp on 0x%p\n", @$t4

$$ Set the breakpoint.
ba w4 @$t4

}
}

ad $ImageName
ad Procc
}

(If that gets mangled in the post feel free to email me directly: snoone at
osr dot com)

Like I said I don't have a live system to run that against, but the results
give me the correct addresses:

vmnetdhcp.exe
alg.exe
SvcGuiHlpr.exe
explorer.exe
Found the process at 0xffffffff896488d8
Object header at 0x896488c0
Setting bp on 0x896488c8

And to verify:

lkd> !object 0xffffffff896488d8
Object: 896488d8 Type: (8a701ca0) Process
ObjectHeader: 896488c0 (old version)
HandleCount: 6 PointerCount: 21


"Richard Lewis Haggard" <Richard Lewis Haggard(a)discussions.microsoft.com>
wrote in message news:F6348D61-AF67-42EC-B261-6EE99FCE73A7(a)microsoft.com...
> Can WinDbg's script processor do string processing and use the results as
> addresses? Here's an example of what I'd like to do -
>
> I want to know when ssonsvr.exe has terminated. To do this, I want to
> monitor writes to the Type field of the object header of the process
> object.
> I can manually do this with the following WinDbg commands:
>
> First, getting the EPROCESS address of ssonsvr.exe -
>
> kd> !process 0 0 ssonsvr.exe
> PROCESS 85d1a020 SessionId: 0 Cid: 094c Peb: 7ffde000 ParentCid:
> 0910
> DirBase: 24240560 ObjectTable: e1047890 HandleCount: 24.
> Image: ssonsvr.exe
>
> The number after the string 'PROCESS' is the _EPROCESS address that I'm
> interested in. Taking that address, I can get the encapsulating object
> header. (For demonstration purposes, this is done in steps but normally
> I'd
> just take the object address and subtract 0x18 from it to get the same
> result.)
>
> First, get the encapsulating object:
>
> kd> !object 85d1a020
> Object: 85d1a020 Type: (867c6e38) Process
> ObjectHeader: 85d1a008 (old version)
> HandleCount: 1 PointerCount: 8
>
> Embedded in the return string is ObjectHeader: and the following address
> is
> where the object header is located. Using that address, we can gain access
> to
> the
>
> kd> dt nt!_OBJECT_HEADER 85d1a008
> +0x000 PointerCount : 8
> +0x004 HandleCount : 1
> +0x004 NextToFree : 0x00000001
> +0x008 Type : 0x867c6e38 _OBJECT_TYPE
> <snipped for brevity>
>
> When Type changes then the process object is no longer valid so I want to
> set a break point when this address is written to. For convenience, I'll
> go
> ahead and write some cosmetic space and follow that with a stack dump.
> This
> is done with
>
> kd> ba w4 85d1a008+8 ".echo *** end of ssonsvr ***;.echo*;kb200"
>
> This break point is the real meat of the matter. Is it possible to write a
> WinDbg script that would automate the essentials of the above example?