Windows System Software -- Consulting, Training, Development -- Unique Expertise, Guaranteed Results

Home NTDEV

Before Posting...

Please check out the Community Guidelines in the Announcements and Administration Category.

More Info on Driver Writing and Debugging


The free OSR Learning Library has more than 50 articles on a wide variety of topics about writing and debugging device drivers and Minifilters. From introductory level to advanced. All the articles have been recently reviewed and updated, and are written using the clear and definitive style you've come to expect from OSR over the years.


Check out The OSR Learning Library at: https://www.osr.com/osr-learning-library/


Source for library routine chkesp?

OSR_Community_UserOSR_Community_User Member Posts: 110,217
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!

Comments

  • OSR_Community_UserOSR_Community_User Member Posts: 110,217
    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:[email protected]]
    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: [email protected]
    To unsubscribe send a blank email to $subst('Email.Unsub')
  • OSR_Community_UserOSR_Community_User Member Posts: 110,217
    > 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
  • OSR_Community_UserOSR_Community_User Member Posts: 110,217
    From: "Taed Nelson" <[email protected]>
    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.
  • David_J._CraigDavid_J._Craig Member Posts: 1,885
    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" <[email protected]>
    To: "NT Developers Interest List" <[email protected]>
    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: [email protected]
    > To unsubscribe send a blank email to $subst('Email.Unsub')
    >
  • OSR_Community_UserOSR_Community_User Member Posts: 110,217
    > > > 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
  • Don_Burn_1Don_Burn_1 Member Posts: 4,311
    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
  • OSR_Community_UserOSR_Community_User Member Posts: 110,217
    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:[email protected]]
    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: [email protected]
    To unsubscribe send a blank email to $subst('Email.Unsub')
  • OSR_Community_UserOSR_Community_User Member Posts: 110,217
    > 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...
  • OSR_Community_UserOSR_Community_User Member Posts: 110,217
    > 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
  • OSR_Community_UserOSR_Community_User Member Posts: 110,217
    > 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
  • OSR_Community_UserOSR_Community_User Member Posts: 110,217
    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: [email protected] [SMTP:[email protected]]
    Sent: Friday, March 03, 2000 7:59 PM
    To: NT Developers Interest List
    Subject: [ntdev] RE: Source for library routine chkesp?
Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. Sign in or register to get started.

Upcoming OSR Seminars
OSR has suspended in-person seminars due to the Covid-19 outbreak. But, don't miss your training! Attend via the internet instead!
Kernel Debugging 30 January 2023 Live, Online
Developing Minifilters 20 March 2023 Live, Online
Internals & Software Drivers 17 April 2023 Live, Online
Writing WDF Drivers 22 May 2023 Live, Online