0

I've coded a wrapper for CryptoPP which would be used by c# app. My issue is that when calling to a specific function in my wrapper using PInvoke, throws an exception "Attempted to read or write protected memory...". Both of them are compiled as x64.

Now.. strange part is that if i compile my wrapper using /MTd or /MDd runtime, the call does not fail and everything works perfectly. But changing the runtime to /MT or /MD would throw the above exception.

I cannot use the /MTd or /MDd option for official use by my customers, as it requires lots of dlls resources to be installed or distributed into the user machine.

cpp code:

extern "C" __declspec(dllexport) int CryptBlock(bool mode, unsigned char type, unsigned char *inData, unsigned char *outData, int dataLen, unsigned char *key, int keyLen);

c# PInvoke:

[DllImport("mydll.dll", SetLastError = true, CallingConvention = CallingConvention.Cdecl)]
    public static extern int CryptBlock(bool mode, byte type, IntPtr inData, IntPtr outData, int dataLen, IntPtr key, int keyLen);

I have tried modifying my P/Invoke code in various ways: [In, Out], [Out], ref, ref byte[], byte[] etc... still throwing the exception.

Waiting for my savior...

Thank you.

Daniel Raban
  • 21
  • 2
  • 5
  • 1
    Might be a bug somewhere in your CryptBlock code which only happens to be triggered when not using /MTd or /MDd: those are the debug libraries, memory might be initialized in a different way comparing to release mode (IIRC debug crt libs tend to initialize memory to all 0 in debug but not in release, so suppose you have an unitialized variable then use it to index an array - BAM). Maybe enabling all runtime checks reveals the problem, also see e.g. http://stackoverflow.com/questions/186237/program-only-crashes-as-release-build-how-to-debug – stijn Dec 15 '15 at 20:26
  • How are you calling `CryptBlock()`? Possibly your `dataLen` or `keyLen` are wrong. – dbc Dec 16 '15 at 01:59

2 Answers2

2

You are right that you cannot distribute the debug runtime, but in fact the issue is not quite what you think. The license does not permit redistribution of the debug runtime.

The most likely explanation is in fact that your code has a defect. The fact the the defect does not manifest with the debug runtime is simply down to chance. So the correct way to proceed is to track down your defect and fix it.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
0

Consider using a bridge between Managed and Unmanaged code. It can be debug more easily...

Example:

C++ Unmanaged code:

class ExampleCpp
{
private:

    int id;

public:

    ExampleCpp();
    ~ExampleCpp();

    const int getId();

};    

C++ Managed Code:

public ref class ExampleManagedCpp
{
private:
    ExampleCpp* pImpl;

public:

    ExampleManagedCpp();
    ~ExampleManagedCpp();
    !ExampleManagedCpp();
};

http://www.codeproject.com/Articles/868230/Cplusplus-CLI-Accessing-a-managed-type-from-unmana

http://blogs.msdn.com/b/soultech/archive/2010/07/27/cli-c_2b002b00_-to-c_2300_-hello-world.aspx

Felipe P.
  • 24
  • 4