14

DotPeekを使用して、問題をデバッグするためにサードパーティのソースを逆コンパイルしました。出力コードには、AFAIKが有効なC#ではないいくつかの異常な演算子が含まれているため、それらが何を意味するのか疑問に思っています...

抜粋は次のようになります(おそらく関連性があるため、Dotpeekコメントが含まれています)。

protected internal void DoReceive(ref byte[] Buffer, int MaxSize, out int Written)
{
    Written = 0;
    .
    .
    .        
    // ISSUE: explicit reference operation
    // ISSUE: variable of a reference type
    int& local = @Written;
    int num = SomeMethod();
    .
    .
    .
    // ISSUE: explicit reference operation
    ^local = num;
}

それで、そこにある3つの珍しい演算子はint& = @Written、@文字で無意味に名前が付けられた変数にポインターを割り当てているようです。

しかし、何^local = num;ですか?

OK、これはILSpyからの同等のスニペットです。これはより理にかなっています。C#への逆コンパイルでは有効な同等のスニペットが生成されなかったと思いますか?

「C#」

 int& local = @Written;
 byte[] numArray2 = this.FInSpool;
 int num = (int) __Global.Min(numArray2 == null ? 0L : (long) numArray2.Length, (long) MaxSize);
 ^local = num;

IL

 byte[] expr_22 = this.FInSpool;
 Written = (int)__Global.Min((long)((expr_22 == null) ? 0 : expr_22.Length), (long)MaxSize);

それで、私は「C#」が完全に有効ではないと思いますか?そのILは有効なC#であり、DotPeekが出力を生成した理由はわかりません。たぶん私はこれのためにILSpyに固執するでしょう...?

4

3 に答える 3

9

生のIL(IL Spyを介したC#の同等物ではなく、ildasmから)を見ると、逆コンパイラーが何を言おうとしているのかを理解するのに役立つ場合があります。'Out'パラメーターは、(管理された)型付き参照を使用して表されます。これは、C#で型として明示的に公開されていません。このタイプの「インスタンス」は通常、型付き参照を受け入れるメソッドにパラメーターとしてのみ渡すことができます(「ref」または「out」パラメーター)。詳細については、 OpCodes.Mkrefanyを参照してください。

dotPeekが不満を言っているのは、この「out」型の参照が引数からローカル変数スロットに格納され、後でローカルスロットを介して書き込まれたことです。'@'および'^'は、逆コンパイラー(ISSUEコメントで説明されているもの)によって検出されたこの予期しない動作を示すために使用されるプレースホルダーです。

コードがC++/ CLIからコンパイルされた可能性があるため、ILは通常のC#コンパイラの出力とは異なって見えます。これは、逆コンパイラーを混乱させるためのある程度の難読化である可能性もあります(私はそうは思いませんが)。これは、引数からの参照を操作スタックに直接ロードすることと機能的に異なるとは思いません(ローカル変数スロット)、しかし私は間違っている可能性があります。

于 2012-12-17T23:32:33.623 に答える
3

名前の@前にaを付けると、変数に予約された名前を使用できます。たとえば、という変数returnが必要な場合は、これを行う必要があります。

public int Weird()
{
    int @return = 0;
    return @return;
}

詳細については、このSOの質問を参照してください。


名前の前にa^を付ける...うーん、手がかりはありません。(XORとして使用されていない場合の意味についての情報を見つけることができたので、調査しながら更新します)^

于 2012-12-17T22:30:53.600 に答える
0

これは明らかに逆コンパイルの問題です。サポートされている言語のセットが広いため、特定の言語への逆コンパイラーは常に完全に一致するとは限りませんが、それでも何らかの出力を生成しようとします。逆コンパイラは、次のように、ある程度同等の出力を生成しようとする場合があります。

protected internal void DoReceive(ref byte[] Buffer, int MaxSize, out int Written)
{
    Written = 0;
    .        
    int num = SomeMethod();
    .
    Written = num;
}

しかし、それは本当にこれを行うべきですか?この場合、逆コンパイラーは実際にヒントを提供してくれたので、いくつかの副作用があるかもしれないので、これがあなたの特定のケースにとって重要であるかどうかを決めることができます。

于 2013-04-02T15:01:23.360 に答える