Source for library routine chkesp?

When you use the /GZ flag in the VC++ 6.0 compiler, it tries to link with
__chkesp. This is located in MSVCRTD.DLL.

However, I’m doing kernel stuff, and so I want to write my own CHKESP.

Does anyone have the source for that function so I can write my own? I
thought that the source for the libraries was available, but I was unable to
find it on the MSVC++ CDs or online.

Thanks!

I believe this is an acceptable version of the function for VC 6.0, it could
change in the future. I would not ship a “deliverable” with the flag set,
this would just be for debug.

extern “C” void __declspec ( naked ) _chkesp(void)
{
_asm { ret }
}

I derived this by looking at the assembly generated by the compiler. The
actual function tests the ESP register and calls a C runtime routine on test
failure. You could also test the register and bugcheck on failure. In any
case, if the test fails there is nothing you can do. As far as I can tell,
the stack is shot.

-----Original Message-----
From: Taed Nelson [mailto:xxxxx@vertical.com]
Sent: Thursday, March 02, 2000 1:21 PM
To: NT Developers Interest List
Subject: [ntdev] Source for library routine chkesp?

When you use the /GZ flag in the VC++ 6.0 compiler, it tries to link with
__chkesp. This is located in MSVCRTD.DLL.

However, I’m doing kernel stuff, and so I want to write my own CHKESP.

Does anyone have the source for that function so I can write my own? I
thought that the source for the libraries was available, but I was unable to
find it on the MSVC++ CDs or online.

Thanks!


You are currently subscribed to ntdev as: xxxxx@moore-solutions.com
To unsubscribe send a blank email to $subst(‘Email.Unsub’)

> extern “C” void __declspec ( naked ) _chkesp(void)

{
_asm { ret }
}

Actually, I want a functional chkesp, but I don’t think that would work
anyway (see below). I never found the source for that assembly file, but
used SoftICE to look at the user-mode version, and then made my own.

However, now that I have an assembly file – and don’t have MASM – how do I
compile it? BUILD didn’t seem to know what to do with it, and other
examples I found all use MASM.

Note that I think I have to not use VC++ to compile it (that is, I can’t
just use the _asm statement in a C file) because it uses a non-standard
stack-frame entry code. If I used inline _asm, like the example above, it
would still insert the standard C stack-frame entry and exit.

Worse yet, if I compile it with the /GZ flag enabled, it will insert the
“call __chkesp” code at the stack-frame exit, and thus, it will become
infinitely recursive.

For that reason, I don’t see how your example would have worked – had you
ever tried it before?

Here’s what I came up with for a quick-and-dirty CHKESP.ASM:

title chkesp - Check if the ESP was changed for use with /GZ flag
in VC++ 6.0.
CODESEG
public _chkesp
_chkesp proc
jnz bad_stack
ret
bad_stack:
int 3
ret

The code that is inserted by VC++ after every function call and at the end
of every stack-frame exit is:
mov esi, esp
… possible function call …
cmp esi, esp
call __chkesp

From: “Taed Nelson”
Sent: Thursday, March 02, 2000 5:36 PM

> > extern “C” void __declspec ( naked ) _chkesp(void)
> > {
> > _asm { ret }
> > }
>
> Actually, I want a functional chkesp, but I don’t think that would work
> anyway (see below). I never found the source for that assembly file, but
> used SoftICE to look at the user-mode version, and then made my own.

[snip]

> Worse yet, if I compile it with the /GZ flag enabled, it will insert the
> “call__chkesp” code at the stack-frame exit, and thus, it will become
> infinitely recursive.
>
> For that reason, I don’t see how your example would have worked – had you
> ever tried it before?

I think the trick above is the use of “__declspec ( naked )”, which
instructs the compiler to definitely NOT generate any extra prologue or
epilogue code.

That is, the compiler will not “dress up” the above implementation of
_chkesp() with the stack-checking code (or anything else). The code in the
function – namely, a single “ret” instruction – will stay “naked”.

[snip]

Regards,

Matt Arnold
Professional Music Products
Mark of the Unicorn, Inc.
http://www.motu.com

To obtain my real address, please replace “biteme” with “motu”. My use of a
fake address is an anti-spam tactic. Sorry for the inconvenience.

I see several object modules in the CRT source code tree for Visual C++ 6.0.
I don’t see any source. I don’t think that using the /GZ option is valid
for device drivers. The stack is fixed and already allocated.

----- Original Message -----
From: “Taed Nelson”
To: “NT Developers Interest List”
Sent: Thursday, March 02, 2000 5:36 PM
Subject: [ntdev] RE: Source for library routine chkesp?

> > extern “C” void __declspec ( naked ) _chkesp(void)
> > {
> > _asm { ret }
> > }
>
> Actually, I want a functional chkesp, but I don’t think that would work
> anyway (see below). I never found the source for that assembly file, but
> used SoftICE to look at the user-mode version, and then made my own.
>
> However, now that I have an assembly file – and don’t have MASM – how do
I
> compile it? BUILD didn’t seem to know what to do with it, and other
> examples I found all use MASM.
>
> Note that I think I have to not use VC++ to compile it (that is, I can’t
> just use the _asm statement in a C file) because it uses a non-standard
> stack-frame entry code. If I used inline _asm, like the example above, it
> would still insert the standard C stack-frame entry and exit.
>
> Worse yet, if I compile it with the /GZ flag enabled, it will insert the
> “call__chkesp” code at the stack-frame exit, and thus, it will become
> infinitely recursive.
>
> For that reason, I don’t see how your example would have worked – had you
> ever tried it before?
>
> Here’s what I came up with for a quick-and-dirty CHKESP.ASM:
>
> title chkesp - Check if the ESP was changed for use with /GZ flag
> in VC++ 6.0.
> CODESEG
> public _chkesp
> _chkesp proc
> jnz bad_stack
> ret
> bad_stack:
> int 3
> ret
>
> The code that is inserted by VC++ after every function call and at the end
> of every stack-frame exit is:
> mov esi, esp
> … possible function call …
> cmp esi, esp
> call __chkesp
>
> —
> You are currently subscribed to ntdev as: xxxxx@mindspring.com
> To unsubscribe send a blank email to $subst(‘Email.Unsub’)
>

> > > extern “C” void __declspec ( naked ) _chkesp(void)

> > {
> > _asm { ret }
> > }
>

> Actually, I want a functional chkesp, but I don’t think that would
work…
> Worse yet, if I compile it with the /GZ flag enabled, it will insert the
> “call __chkesp” code at the stack-frame exit, and thus, it will become
> infinitely recursive.

I think the trick above is the use of “__declspec ( naked )”, which
instructs the compiler to definitely NOT generate any extra
prologue or epilogue code.

Yup, you’re right, and I messed up when I had tried it. But, the code
wasn’t perfect – you need an additional __cdecl to get the name mangling
correct.

Thus, what I ended up with is listed below.

Thanks to all for your help!

#ifdef __cplusplus
extern “C” {
#endif
void __declspec (naked) __cdecl _chkesp (void)
{
_asm { jz exit_chkesp };
_asm { int 3 };
exit_chkesp:
_asm { ret };
}
#ifdef __cplusplus
}
#endif

The real question with chkesp is what are you doing that causes it
to be invoked. My experience is that calls to this routine are only
generated if you are allocating a large amount of stack space in a
function. This is a bad idea in the kernel.

Take a look at the module you get the complaint from, and I suspect
you have a routine that uses 2k+ of stack.

Don Burn

I believe you have confused the -Gs flag with what appears to be a new -GZ
flag defined in VC 6.0. A brief reading of the documentation indicates that
the checking is for stack corruption, not just stack overflow. In
particular, it can detect a object module that calls a function using the
wrong calling convention, such as __cdecl vs __stdcall. I see no harm in
using the flag for debug and Taed’s full version of the function seems as
good as any.

-----Original Message-----
From: Don Burn [mailto:xxxxx@acm.org]
Sent: Friday, March 03, 2000 7:51 AM
To: NT Developers Interest List
Subject: [ntdev] RE: Source for library routine chkesp?

The real question with chkesp is what are you doing that causes it
to be invoked. My experience is that calls to this routine are only
generated if you are allocating a large amount of stack space in a
function. This is a bad idea in the kernel.

Take a look at the module you get the complaint from, and I suspect
you have a routine that uses 2k+ of stack.

Don Burn


You are currently subscribed to ntdev as: xxxxx@moore-solutions.com
To unsubscribe send a blank email to $subst(‘Email.Unsub’)

> I believe you have confused the -Gs flag with what appears to

be a new -GZ
flag defined in VC 6.0. A brief reading of the documentation
indicates that
the checking is for stack corruption, not just stack overflow.

Correct. Unfortunately, they lumped together a two different features with
the /GZ flag, so it’s both or none. The useful one will initialize the
local variable section to 0xCC (fills every byte), which is, of course,
useful for catching the use of unininitialized local variables. (Although
the compiler does do a great job at this, it will not catch the
uninitialization of array elements, for example.) The second is the
validation of the call stack, which is where the _chkesp function comes in.

We have some code somewhere that corrupts the stack very rarely, and I
suspect it’s a DPC or interrupt, because some of the local variables in the
code that dies end up with impossible values (such as a boolean with the
value 0x54), even though they were clearly initialized. I’m hoping that
this will help me catch it. With about 20 drivers in our system, it’s not
easy to point fingers…

> Note that I think I have to not use VC++ to compile it (that is, I can’t

just use the _asm statement in a C file) because it uses a non-standard
stack-frame entry code.

__declspec(naked) will suppress the standard VC’s prolog/epilog code
(including the final “ret” instruction) & will allow you to write your own
in the
assembly using __asm{}

Max

> We have some code somewhere that corrupts the stack very rarely, and I

suspect it’s a DPC or interrupt, because some of the local variables in
the
code that dies end up with impossible values (such as a boolean with the
value 0x54), even though they were clearly initialized. I’m hoping that

This is __stdcall/__cdecl mismatch - almost 100%.

Max

Hi Dray,
I am back to disturb you again.As you know that i am working on NDIS 3.5.1
for Windows 98.
I have found a interesting thing.I observed that my driver crashes after
soemtimes when it tries to execute DbgPrint ststement.But it is not
crashing everytime.I do not understand why is this happening.Do you have
some idea???
Are IRQ levels in NT and 98 implemented in the same way??
Can IRQ levels cause the problem??

Please help me ,
Ajitabh Prakash.

-----Original Message-----
From: xxxxx@moore-solutions.com [SMTP:xxxxx@moore-solutions.com]
Sent: Friday, March 03, 2000 7:59 PM
To: NT Developers Interest List
Subject: [ntdev] RE: Source for library routine chkesp?