C# call to C++ static class raises NullReferenceException when web.config gets modifided

A

AAguiar

Thanks for your replies. Last week, I continued working with this problem.
Trying to reproduce the error, I developed a short example and found that
the problem is related to strong name dll.

Following is the example to reproduce it.

I have a C++ project (mixed dll, managed and unmanaged), with classes:
EncodeDecode.cpp, EncodeDecode.h, DecoderRing.cpp as follows:

---------------------------
//EncodeDecode.cpp:

#include "stdafx.h"
#include <string.h>
#include "DecoderRing1.h"
#include "EncodeDecode.h"
EncodeDecode::EncodeDecode(int theKeyOffset)
{
keyOffset = theKeyOffset;
}
char* EncodeDecode::Encode(char* pMessage)
{
char* pEncoded = new char[strlen(pMessage) + 1];
char* pDest = pEncoded;
char* pSource = pMessage;
while (*pSource != '\0')
{
*pDest = *pSource + keyOffset;
pSource++;
pDest++;
}
*pDest = '\0';
return pEncoded;
}
char* EncodeDecode::Decode(char* pMessage)
{
char* pDecoded = new char[strlen(pMessage) + 1];
char* pDest = pDecoded;
char* pSource = pMessage;
while (*pSource != '\0')
{
*pDest = *pSource - keyOffset;
pSource++;
pDest++;
}
*pDest = '\0';
return pDecoded;
}
---------------------------
//EncodeDecode.h
#pragma once
__nogc
class EncodeDecode
{
private:
int keyOffset;
public:
EncodeDecode(int theKeyOffset);
char* Encode(char* message);
char* Decode(char* message);
};
---------------------------
//DecoderRing.cpp
// This is the main DLL file.
#include "stdafx.h"
#include <string.h>
using namespace System;
#include "EncodeDecode.h"
#include "DecoderRing.h"
using namespace System::Runtime::InteropServices;
class String2Char
{
char* m_sptr;
public:
String2Char(String* s)
{
IntPtr* m_ptr =__nogc new
IntPtr(System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi(s));
m_sptr = strdup((char*)m_ptr->ToPointer());
delete m_ptr;
}
~String2Char()
{
free(m_sptr);
}
operator char* ()
{
//return (m_sptr =
(char*)m_ptr.ToPointer());
return (m_sptr);
}
};
public __gc class DecoderRing
{
public:
static String* Encode(String* message)
{
char* pEncoded = (new
EncodeDecode(3))->Encode(String2Char(message));
String* encodedString =
Marshal::ptrToStringAnsi(pEncoded);

delete pEncoded;
return encodedString;

}
static String* Decode(String* message)
{
char* pDecoded = (new
EncodeDecode(3))->Decode(String2Char(message));
String* decodedString =
Marshal::ptrToStringAnsi(pDecoded);
delete pDecoded;
return decodedString;
}
};
---------------------------
// DecoderRing.h
#pragma once
#include <stdlib.h>
---------------------------

In this project, Confguration properties->C/C++->Command line=
/O2 /AI "Release" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_WINDLL" /FD /EHsc
/GS /Fo"Release/" /Fd"Release/vc70.pdb" /W3 /nologo /c /clr /TP /FU
"C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\mscorlib.dll" /FU
"C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.dll" /FU
"C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.Data.dll"

Confguration properties->Linker -> Command Line=
/OUT:"Release\EncodeDecode.dll" /INCREMENTAL:NO /NOLOGO /DLL
/INCLUDE:"__DllMainCRTStartup@12" /DEBUG /PDB:"Release/EncodeDecode.pdb"
/NOENTRY /FIXED:No msvcrt.lib kernel32.lib user32.lib gdi32.lib
winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib
uuid.lib odbc32.lib odbccp32.lib
Aditional options= /noentry /NODEFAULTLIB:LIBCMT
This project make the EncondeDecode.dll

I have a second dll: MyCrypto.dll
//MyCrypto.cs
using System;
namespace ManagedDll
{
public class DataStoreUtil_2
{
public static string LoadDataStores(string msg)
{
return (new MyCrypto()).Decode(msg);
}
}
public class MyCrypto
{
public string Decode(string msg)
{
string res1=DecoderRing.Encode(msg);
return res1;
}
}
}
I make MyCrypto.dll with MyCrypto.rsp=
/t:library
/w:0
/debug
/out:bin\MyCrypto.dll
/r:bin\log4net.dll
/r:Mixed\Release\EncodeDecode.dll
/r:system.dll
MyCrypto.cs
AssemblyInfo.cs (**)

And I have a dll for the aspx=
//simplehandler.cs
using System.Web;
using System;
using ManagedDll;
namespace Programs
{
public class simplehandler : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
try
{
string res1 =
DataStoreUtil_2.LoadDataStores("test");
context.Response.Write("<br>res1=" + res1 +
"<br><br> ");
context.Response.Write("<br><br>Hello
World");

}
catch(Exception e)
{
context.Response.Write("<br>error=" +
e.Message + "<br><br> " + e.StackTrace);
}
}
public bool IsReusable
{
get
{
return true;
}
}
}
}
The web.config file=
<configuration>
<system.web>
<trace enabled="true" />
<identity impersonate="true" />
<httpHandlers>
<add verb="*" path="*.aspx"
type="Programs.simplehandler,simplehandler" />
</httpHandlers>
</system.web>
</configuration>

To reproduce the error:
1) Go to http://localhost/services/simplehandler.aspx (this is OK, you can
see the message "hello world"),
2) Restart the aspnet_wp process (windows task manager),
3) Press F5 in page 1) (this is OK)
4) Modify web.config file (Add to it a blank space for example),
5) F5 in page 1) => The following error appears = Object reference not set
to an instance of an object. at ManagedDll.MyCrypto.Decode(String msg).
This error (step 5) only appears when AssemblyInfo.cs (**) have a
AssemblyKeyFile (is a strong name dll), but doesn't appear when it isn't a
strong name dll.

Any help or direction regarding the resolution of this problem is welcomed.
Thanks in advance.
 
S

Steven Cheng[MSFT]

Hi AAguiar,


Thank you for the response. Regarding on the issue, I am finding proper
resource to assist you and we will update as soon as posible. In the
meantime, If you have any new findings, please feel free to post here.



Steven Cheng
Microsoft Online Support

Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)
 
A

AAguiar

OK. Thank you.
I don't have new findings for now, but I'm continue working on this issue.

I hope the example helps to reproduce the error.

Any help would be greatly appreciated.
 
S

Steven Cheng[MSFT]

Hi AAguiar,


I'm still focus on this issue and trying to repro it via the code you
provided. I'll let you know as soon as I've got any progress.


Steven Cheng
Microsoft Online Support

Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)
 
A

AAguiar

Ok. Thank you

I hope you can reproduce the error with the supplied code, if you have any
question about it, please ask me.
 
S

Steven Cheng[MSFT]

Hi AAguiar,


I'm sorry for keeping you waiting for so long time. Currently I've done
serveral tests on the code you provided. However, some conditions are a bit
different from your description, here is what I found:
1. I tried build all the components without any strong-named, and test the
handler following the repro steps you mentioned. then all is ok.

2. As you said, the problem occured only when you build the "MyCrpto"
component as strong-named. Did you also build the "EncodeDecode.dll" as
strong-named? Did you use VS.NET IDE to build them? I used the VS.NET ide
to build them and found that if only "MyCrypto" is strong-named and
"EncodeDecode" is not strong-named , then when I try build the them,
VS.NET will popup a exception said that "EncodeDecode" is not strong-named
which will prevent me from successfully build the MyCrypto. So I'd like to
confirm you with this.
If you use other means to build all the assemblies which didn't occur such
error, I think the cause of the problem is likely due to "EncodeDecode"
assembly is not strong-named also.

3. In addition, I've also test the case that I set both "EncodeDecode" and
"MyCrypto" assembies as strong-named and then
use them as the repro steps above in a ASP.NET web app. The result is the
same as in 1, no exception occured.

So please check out the suggestions I mentioned above. If you have any
questions or new findings, please feel free to let me know.



Regards,

Steven Cheng
Microsoft Online Support

Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)
 
A

AAguiar

Steven, thanks for the reply.

1. Ok. I agree.

2. Yes, I always built EncodeDecode.dll as strong name, and I used VS.NET
2003.

3. In this case is where I get the exception after I follow the 5 steps that
I described in my previous post.

I have windows xp and IE 6.0

I think maybe I have different settings in the EncodeDecode project.

Which settings do you have in your C/C++ Command Line and Linker Command
Line ?.

Thanks again.
 
S

Steven Cheng[MSFT]

Hi AAguiar,

Thanks for your reply and the further info you provided. I've attached the
test solution which contains all the test projects. You may check on it to
see whether there're any difference , also you can have a test on it on
your side. If still remains the problem, I think we need to look for some
other things for throubleshooting , do you think so? In the mean time, I'll
do some further tests on my side to see whether I've lose any thing.
If you have questions or any findings, please feel free to post here.


Regards,

Steven Cheng
Microsoft Online Support

Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)
 
A

AAguiar

Steven,
Thank you for sending me the test solution.
I already tested it and I'm getting the same error.

I agree with you, that we need to look for some other things for
troubleshooting.

The application is very simple; perhaps we have differences in other things
like virtual directory or user's permissions:

- My virtual directory ("services") isn't checked for anonymous access, and
is checked for Integrated Windows Authentication.

- The test user (which I'm logged in) is member of the Administrators group.

- The error always disappears if MyCrypto.dll and EncodeDecode.dll haven't
got a strong name, or if I set impersonation="false" in web.config file.

It's very strange. Do you think that it would help if I reinstall aspnet ?.
 
S

Steven Cheng[MSFT]

Hi AAguiar,

Thanks for your response. Yes, in addtion to something with the code, the
problem is likely due to some security related configuration settings.
Currently, I'm still not sure on this since I've not repro the same error.
However, I recommend that you try the code on other machine and see whether
is able to repro this error. If not, try compare the different server
enviroment or confirguation between the different machines. As for to
reinstall the ASP.NET, I think you may try this in the end :). Meanwhile,
I'll continue to try repro the problem on my side, and I'll update you as
soon as I've any new update!


Regards,

Steven Cheng
Microsoft Online Support

Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)
 
M

Mike Moore [MSFT]

Hi AAguiar,

Please pardon the delay in answering your question. We are still
researching and will post more information as soon as we can.

Thank you, Mike
Microsoft, ASP.NET Support Professional

Microsoft highly recommends to all of our customers that they visit the
http://www.microsoft.com/protect site and perform the three straightforward
steps listed to improve your computer’s security.

This posting is provided "AS IS", with no warranties, and confers no rights.


--------------------
X-Tomcat-ID: 178918413
References: <[email protected]>
<[email protected]>
<[email protected]>
<[email protected]>
<[email protected]>
<f95#[email protected]>
<#[email protected]>
<[email protected]>
MIME-Version: 1.0
Content-Type: text/plain
Content-Transfer-Encoding: 7bit
From: (e-mail address removed) (Steven Cheng[MSFT])
Organization: Microsoft
Date: Wed, 21 Jan 2004 07:25:11 GMT
Subject: Re: C# call to C++ static class raises NullReferenceException when web.config gets modifided
X-Tomcat-NG: microsoft.public.dotnet.framework.aspnet
Message-ID: <tQhqA$#[email protected]>
Newsgroups: microsoft.public.dotnet.framework.aspnet
Lines: 21
Path: cpmsftngxa07.phx.gbl
Xref: cpmsftngxa07.phx.gbl microsoft.public.dotnet.framework.aspnet:203794
NNTP-Posting-Host: tomcatimport2.phx.gbl 10.201.218.182

Hi AAguiar,

Thanks for your response. Yes, in addtion to something with the code, the
problem is likely due to some security related configuration settings.
Currently, I'm still not sure on this since I've not repro the same error.
However, I recommend that you try the code on other machine and see whether
is able to repro this error. If not, try compare the different server
enviroment or confirguation between the different machines. As for to
reinstall the ASP.NET, I think you may try this in the end :). Meanwhile,
I'll continue to try repro the problem on my side, and I'll update you as
soon as I've any new update!


Regards,

Steven Cheng
Microsoft Online Support

Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)
 
S

Steven Cheng[MSFT]

Hi AAguiar,


I've done some further tests following your repro steps. And I've a good
news that I've also encountered an error when modified the web.config file
and restart the web app to recycle the workerprocess. The difference is
that what I met is a "Access Denied" error, which occurs in the "MyCrpto"
components. Currently, I'm doing further research on it, it may cost
certain period time to find the cause, but I'll notice you as soon as I've
any new findings. If you have any new update, please feel free to post here.


Regards,

Steven Cheng
Microsoft Online Support

Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)
 
A

AAguiar

Steven, thanks for your answers and your time.

The solution I have found to the problem is to install the assembly
EncodeDecode.dll in the GAC. If I uninstall the EncodeDecode.dll from the
GAC the error comes again.

I think that the NullReferenceException is related to the way the dlls are
loaded. In fact I think that the order that the AspNET Worker process loads
the dlls when it recycles them is different to the way they are loaded when
it is restarted. This brings errors when the dlls are static, mixed (managed
and unmanaged) and referenced by other ones. May when the dll is in the GAC
the loading order changes ?

At least now I don't have the error, but if you have any other suggestion to
solve this problem please let me know.

Thanks again and Regards.
 
S

Steven Cheng[MSFT]

Hi AAguiar,


Thanks for your reply. I'm glad that you've found the method to workaround
this problem. And I agree with you that the problem is actually caused by
the different behaviors when the asp.net runtime looking for the assemblies
if the workerprocess start first time or have recycled. I'll still pay
attention on this issue and will update you if I've got any further
progress. Thanks again for your understanding and patience.


Regards,

Steven Cheng
Microsoft Online Support

Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)
 
S

Steven Cheng[MSFT]

Hi AAguiar,


Regarding on this issue, we haven't got any further information. I think
currently you may use "install the assembly EncodeDecode.dll in the GAC" to
workaround it. If you encounter any new problems on it or need any further
assistance, please feel free to let me know. I'll be willing to assist you.


Regards,

Steven Cheng
Microsoft Online Support

Get Secure! www.microsoft.com/security
(This posting is provided "AS IS", with no warranties, and confers no
rights.)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top