1

サード パーティのコードを呼び出す C++/CLI ラッパーを作成しましたが、たまたまメモリが破損していました。だから私はおそらくコードがC++で合法ではなかったのではないかと疑っています

以下はクラッシュしたコードです。

void Init_4bit_tab(unsigned char *dest,unsigned char *source)
        {
            unsigned char masque,i;

            masque=0x08;
            for(i=0; i<4; i++) {
                dest[i] = (*source & masque)>>(3-i);
                masque >>= 1;
            }
        }

正確なエラーは次のとおりです。保護されたメモリを読み書きしようとしました。これは多くの場合、他のメモリが破損していることを示しています。

アップデート:

サードパーティのコードをスキャンした後、渡された方法のために多次元配列のように見えますが、問題の原因はまだわかりません:

ソース関数

unsigned char Data_B[81];
...
S_Box_Calc(&Data_B[33]);

void S_Box_Calc(unsigned char *vect)
        {
              unsigned char *S_Box[8];
              unsigned lig,col,i;

              S_Box[0]=S1;
              S_Box[1]=S2;
              S_Box[2]=S3;
              S_Box[3]=S4;
              S_Box[4]=S5;
              S_Box[5]=S6;
              S_Box[6]=S7;
              S_Box[7]=S8;

              for(i=0;i<8;i++) {
                    col= 8*vect[1+6*i] + 4*vect[2+6*i] + 2*vect[3+6*i] + vect[4+6*i];
                    lig= 2*vect[6*i] + vect[5+6*i];
                    Init_4bit_tab(&vect[4*i],&S_Box[i][col+lig*16]);
              }
        }

更新 2: デバッグ モードで値を確認したところ、dest と source が null ではありません。ただし、このコードの下で (*source & masque) をすばやく見ようとすると、 dest[i] = (*source & masque)>>(3-i);

このエラーが発生します

(*source & masque) エラー: & は '*source' および 'masque' では実行できません

更新 3: S1...Sn はもともとファイルのグローバル スコープで定義されていましたが、そのままにしておくとエラーが発生するため、コンストラクターで次のように初期化しました。

unsigned char lS1[64] = { 
                14,4,13,1,2,15,11,8,3,10,6,12,5,9,0,7,
                0,15,7,4,14,2,13,1,10,6,12,11,9,5,3,8,
                4,1,14,8,13,6,2,11,15,12,9,7,3,10,5,0,
                15,12,8,2,4,9,1,7,5,11,3,14,10,0,6,13
            };
            std::copy(S1, S1 + 64, lS1);

これは問題でしょうか?

4

3 に答える 3

0

有効なポインターが渡された場合、表示するコードに問題はありません。メモリが破損している場合は、呼び出し元が有効なポインターを渡さなかった可能性があります。

編集後: ifS_Box_Calcvectequal to Data_B + 33で呼び出された場合、表示されているように、範囲[vect, vect+48)は合法です。つまり、Init_4bit_tab44 を超える値で呼び出されるべきではありません。実際、表示されているコードでは、値で呼び出されることはありません。 28 より大きいため、ここでメモリを破損することはできません。S1ただし、 ~のいずれかがS8有効なメモリを指していない場合は、指定した症状が発生します。

于 2013-09-26T09:30:38.647 に答える
0

これは構文的に完全に正当な C++ であり、コンパイルされます。意味的に正しいかどうかを確認してください。うっかり UB ランドを踏む可能性のある唯一の場所は、destポインターへのアクセスです。つまり、それが指している配列は、指している場所から少なくとも 4 文字の長さでなければなりません。また、エラーはアクセス違反に関するものでdestあるため、書き込み可能なメモリ位置を指していることを確認してください。

于 2013-09-26T09:11:13.040 に答える
0

オーバーフロー チェックはどこにありますか? 関数にサイズを渡して、オーバーフローする可能性がある場合にメモリへの書き込みを制限できるようにする必要があります。これは、BSD の strcpy() と strncpy() または strlcpy() に似ています。おそらく、これらの線に沿って何かを実装し、そうでなければ書き込まれたメモリがオーバーフローするという条件がある場合にエラーを生成すると、メモリ破損の原因が見つかる可能性があります。

于 2013-09-26T10:11:56.460 に答える