Невозможно скопировать указатель (IntPtr) в byte [] из метода CryptGetHashParam - PullRequest
1 голос
/ 25 января 2011

Я работал над этим весь день, и я все еще застрял, я портировал этот код с c / c ++ на c # im так близко, но я получаю эти исключения

Исключение типа 'System.ExecutionEngineException' было брошено,и Попытка чтения или записи защищенной памяти.Это часто указывает на то, что другая память повреждена.

вот код, код не очищен / не оптимизирован, но я все еще тестирую его

    public unsafe static void GetHash(string data, byte[] hash)
    {
        byte[] input = System.Text.UnicodeEncoding.Unicode.GetBytes(data);
        hash = new byte[128];
        IntPtr hProv = IntPtr.Zero;
        IntPtr hHash = IntPtr.Zero;

        Crypto.CryptAcquireContext(ref hProv, string.Empty, string.Empty, Crypto.PROV_RSA_FULL, 0);

        if (Crypto.CryptCreateHash(hProv, Crypto.CALG_SHA1, IntPtr.Zero, 0, ref hHash))
        {
            if (Crypto.CryptHashData(hHash, input, ((input.Length) + 1) * 2, 0))
            {
                byte[] buffer = new byte[20];
                IntPtr pBuffer = IntPtr.Zero;
                int length = 20;

                if (Crypto.CryptGetHashParam(hHash, Crypto.HP_HASHVAL, ref pBuffer, ref length, 0))
                {
                    Crypto.CryptDestroyHash(hHash);
                    Crypto.CryptReleaseContext(hProv, 0);  
                    byte tail = 0;

                    unsafe
                    {
                        //no matter what i do it stops here!!!!! :(
                        //one error is "Exception of type 'System.ExecutionEngineException' was thrown."
                        //the other is "System.AccessViolationException crossed a native/managed boundary
                        //Attempted to read or write protected memory. This is often an indication that other memory is corrupt."

                        try
                        {
                             //-------------------------- This is where the exepctions starts
                            //I have commented the code, cause im kinda getting tired of this Exception
                            //I tried 2 ways of getting a byte[] from a pointer

                            //the 1e way, does not work
                            //for (int i = 0; i < length; i++)
                                //buffer[i] = (byte)Marshal.ReadByte(pBuffer, i);

                            //the 2e way does not work
                            //System.Runtime.InteropServices.Marshal.Copy(pBuffer,buffer, 0, 20);

                            //--------------------------
                        }
                        catch (Exception ex)
                        { 

                        }
                    }

                    //there is more code here, but i removed
                    //since i only want till where code goes sofare
                }
            }
        }
    }

надеюсь, что кто-нибудь может мне помочьздесь,

Спасибо заранее

JB

Ответы [ 2 ]

2 голосов
/ 26 января 2011

Я исправил это без использования unsafe или оператора fixed, то, что я сделал, было просто 2, как большинство проблем с кодировкой tmp

У меня есть этот класс Crypto, где у меня есть все функции advapi.dll ифункция вернула указатель на байтовый массив в памяти, и это то, что нужно функции перед моим изменением.

        [DllImport("advapi32.dll", SetLastError = true)]
    public static extern bool CryptGetHashParam(
        IntPtr hHash,
        Int32 dwParam,
        ref IntPtr pbData, // this is where my problem was!!!!
        ref Int32 pdwDataLen,
        Int32 dwFlags

я изменил функцию на

        [DllImport("advapi32.dll", SetLastError = true)]
    public static extern bool CryptGetHashParam(
        IntPtr hHash,
        Int32 dwParam,
        Byte[] pbData, //i changed it from IntPtr to byte array
        ref Int32 pdwDataLen,
        Int32 dwFlags

, и это решило мою проблемупроблема с памятью Надеюсь, что эта проблема поможет кому-то другому, работающему с CryptGetHashParam

Я портировал этот код из c / c ++, потому что там нет примера c # в сети, поэтому вот один из первых.

Спасибо за попытку выручить меня, но я исправил это сам

JB

1 голос
/ 25 января 2011

Я не уверен, но, скорее всего, потому, что ваши объекты .Net не закреплены в памяти. Смотрите это: http://dotnet.dzone.com/news/net-memory-control-use-gchandl. Суть в том, что объекты .Net могут перемещаться в памяти после того, как вы прошли их через взаимодействие, и когда это происходит, вещи начинают сходить с ума.

К сожалению, я сейчас на нетбуке и не могу попробовать это сам. Это помогает?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...