none
C++ /CLR corruption of data during NTDLL call, example project

    Question

  • The following issue has been reproduced on two XP64 machines.

    One byte of a stack array of ULONGLONG[] type appears to be corrupted during a call to NTDLL however only due to code changes which are, at least in part, apparently totally irrelevant to the functionality in question. We suspect this may be a corruption of the /CLR stack where the data structure is held.

    Could it be, perhaps, that part of the stack array is being held in a register, and is being corrupted by the Kernel during the call to NTFSControlFile?

    Example project at:
    http://rapidshare.com/files/254219150/TestNTFS.zip


    Friday, July 10, 2009 3:44 PM

Answers

  • Hmya, not quite sure what kind of miracle you expect in a forum when you use undocumented API functions.  You don't even know if your structure declarations are correct and have the proper packing.  It could well be a bug in the API, this isn't one that gets a lot of exercise.  I'd normally direct you to Microsoft Support, but that's pointless.  If you think this is a CLR induced problem, write an unmanaged version first.  If that works, you've got something you can show at connect.microsoft.com

    Hans Passant.
    Friday, July 10, 2009 4:11 PM
  • It's most likely going to be an alignment problem on a struct, that's where I'd look. Just off the top of my head, you probably need to be on a 8-byte alignment boundary.
    Phil Wilson
    Friday, July 10, 2009 6:21 PM

All replies

  • Hmya, not quite sure what kind of miracle you expect in a forum when you use undocumented API functions.  You don't even know if your structure declarations are correct and have the proper packing.  It could well be a bug in the API, this isn't one that gets a lot of exercise.  I'd normally direct you to Microsoft Support, but that's pointless.  If you think this is a CLR induced problem, write an unmanaged version first.  If that works, you've got something you can show at connect.microsoft.com

    Hans Passant.
    Friday, July 10, 2009 4:11 PM
  • It's most likely going to be an alignment problem on a struct, that's where I'd look. Just off the top of my head, you probably need to be on a 8-byte alignment boundary.
    Phil Wilson
    Friday, July 10, 2009 6:21 PM
  • The code is from Mark Russinovich's secure delete utility he wrote at SysInternals. Actually the API is widely in use, as are many undocumented functions. He documents it at
    http://technet.microsoft.com/en-us/sysinternals/bb897427.aspx

    The unmanaged version works perfectly, as does using "new" to create CRT heap memory, or using a pinned GC object. It is only in the supplied /clr Stack array implementation that the results are strangely corrupted which is why I wonder if it is a managed code issue.

    The wierdest thing is the steps needed to corrupt the results seem to bear absolutely no relation whatsoever to the API call e.g. commenting out an unrelated wchar_t array on the stack.

    I assume that the CLR virtual machine is corrupting the stack on the return value from the NTDLL. To attempt to establish this, I have tried to Step Into Specific into the NTDLL call but this fails in Visual Studio. I wonder if that is because of the way the API is declared as a typedef in the code. I have Symbol Server support on. If I could step into the NTDLL function it would surely be easy to see whether the API is returning the correct data or not before we returned to managed code.
    Saturday, July 11, 2009 12:49 PM
  • I've tried

    #pragma pack(8)

    as the first line of TestNtFsControlFile_MSDN.cpp,  but that seems to make no difference to the results at all, which seems a bit strange. I've tried other values, e.g. 15 to see if it breaks, but it changes nothing.

    Does that pragma work in /clr code?


    Saturday, July 11, 2009 12:58 PM
  • The default packing is already 8.  Increasing it isn't going to make a difference.

    If you can get the unmanaged version to work, then use unmanaged code:

    #pragma managed(push, off)
    // Your code
    //...
    #pragma managed(pop)


    Hans Passant.
    Saturday, July 11, 2009 1:04 PM