2011-01-27 9 views
1

私はC++暗号化メソッドをC#に変換する作業を行っています。問題は、暗号化/復号化することができないためです。C#XOR暗号化関数を変換する

アイデアはシンプルで、パケットをキャプチャして解読します。出力は次のようになります。 パケットサイズ - コマンド/アクション - ヌル(終了)

(最初と最後の2つのバイトオフ暗号解読カット)

C++のコードはこれです:

// Crypt the packet with Xor operator 
void cryptPacket(char *packet) 
{ 
    unsigned short paksize=(*((unsigned short*)&packet[0])) - 2; 

    for(int i=2; i<paksize; i++) 
    { 
     packet[i] = 0x61^packet[i]; 
    } 
} 

だから私は、私はポインタを使用したくなかった場合は、これはC#で働くだろうと思った:

public static char[] CryptPacket(char[] packet) 
{ 
    ushort paksize = (ushort) (packet.Length - 2); 

    for(int i=2; i<paksize; i++) 
    { 
     packet[i] = (char) (0x61^packet[i]); 
    } 

    return packet; 
} 

それはない - ブタ、返される値はちょうどrubishの別のラインの代わりに、decrypですted値。与えられた出力は次のとおりです。..O²&/OOOe。

まあ、少なくとも '/'は何らかの理由で適切な場所にあります。

いくつかのより多くの情報:

進値:

  • 私が使用しているテストパケットがこれです0C 00 E2 66 65 47 4E 09 04 13 65 00

    プレーンテキスト:... feGN ... e。復号化された

    :XX/hereXX

    X =不明値が、私は本当に覚えてカントが、それは問題ではありません。

    • あなたがパケットをこのように復号化することができ六角ワークショップを使用して:、
      1. 特別CF_TEXTとして進値を貼り付け「を扱うように16進数の値」ボックスがチェックされていることを確認します。
      2. その後、最初と最後の2バイトを除いて、貼り付けたばかりの16進数値からすべてを選択します。
      3. [ツール]> [操作]> [Xor]に移動します。
      4. 「データを8ビットデータとして扱う」を選択し、値を「61」に設定します。
      5. 「OK」を押すと完了です。私は私の頭の上からこれを書いているので、私は、現時点で与えることができるすべての情報です

    ありがとうございます。

    あなたがこの中に質問が表示されない場合:

    を誰かがそれで間違っているものを見るために、コードを見てみることができれば、またはそれを行うための別の方法があります場合、それは素晴らしいことです。私はこのコードを変換します。なぜなら、私はC++には恐ろしいので、そのコードでC#アプリケーションを作成したいからです。

    Ps:コードタグなどは痛みだったので、スペーシングなどがちょっと台無しになったらごめんなさい。

+0

マークダウンにコードとしてフォーマットする必要があることを指示するには、すべてを4つのスペースでインデントします。コードブロック全体を選択して、ツールバーの「コード」ボタン(中括弧付き)をクリックすることもできます。それはあなたのためにいるように見えるほど難しいはずはありません。 –

+0

これはあまり洗練された暗号化ではありません(各バイトに固定定数をXORする)。実際には、基本的にはこれと変わりません。 ROT13!参照としてASCIIチャート(例:http://www.asciitable.com/)を使用すると、それが機能していない理由を確認し、それがうまくいかない理由がわかります。デバッガとトレースステートメントで既に何を学んだことがありますか? –

+0

@Codyそれは私がやったことですが、タグが別の場所に現れたので、タグをカット/ペーストしようとしましたが、いくつかの行が乱れました。 *一口* @Oli私は命令どおりに動いていることを学んだが、意図通りではないことを学んだ。 – Nick

答えて

1

私はちょうどあなたの機能を試してみましたが、それはOKらしい:

class Program 
{ 
    // OP's method: http://stackoverflow.com/questions/4815959 
    public static byte[] CryptPacket(byte[] packet) 
    { 
     int paksize = packet.Length - 2; 
     for (int i = 2; i < paksize; i++) 
     { 
      packet[i] = (byte)(0x61^packet[i]); 
     } 
     return packet; 
    } 

    // http://stackoverflow.com/questions/321370 :) 
    public static byte[] StringToByteArray(string hex) 
    { 
     return Enumerable.Range(0, hex.Length). 
       Where(x => 0 == x % 2). 
       Select(x => Convert.ToByte(hex.Substring(x, 2), 16)). 
       ToArray(); 
    } 

    static void Main(string[] args) 
    { 
     string hex = "0C 00 E2 66 65 47 4E 09 04 13 65 00".Replace(" ", ""); 
     byte[] input = StringToByteArray(hex); 
     Console.WriteLine("Input: " + ASCIIEncoding.ASCII.GetString(input)); 
     byte[] output = CryptPacket(input); 
     Console.WriteLine("Output: " + ASCIIEncoding.ASCII.GetString(output)); 
     Console.ReadLine(); 
    } 
} 

コンソール出力:

Input: ...feGN..... 
Output: ...../here.. 
(where '.' represents funny ascii characters) 

あなたのCryptPacket方法は、出力値との最初の配列を上書きしていることを少し臭いらしいです。そして、無関係な文字は切り取られません。しかし、あなたが何かを移植しようとしているなら、あなたはあなたが何をしているのかを知っておくべきだと思います。

入力配列をトリミングして、不要な文字を最初に削除し、汎用ROT13メソッド(this oneなど)を使用することもできます。あなたが代わりのようなもので、暗号機能自体の内部2バイトのオフセットを使用して独自の「専門的な」バージョンを持ってこの方法:

public static byte[] CryptPacket(byte[] packet) 
{ 
    // create a new instance 
    byte[] output = new byte[packet.Length]; 

    // process ALL array items 
    for (int i = 0; i < packet.Length; i++) 
    { 
     output[i] = (byte)(0x61^packet[i]); 
    } 

    return output; 
} 
+0

ユニコード文字列からバイト配列への変換のためのより適切な方法:System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding(); byte [] byteArray = encoding.GetBytes( "サンプル文字列"); – rkellerm

+2

なぜユニコードだと思いますか? – Groo

+0

コードをありがとう、それは魅力のように動作します!無関係なデータも適切に復号化できますが、文字列の最後まで「/」で始まる文字列を抽出するだけでよいので、余分なデータを入れる必要はありません。再度、感謝します! – Nick

2

.NETのcharがunicodeなので、いくつかの文字が複数のバイトを使用していて、ビットマスクが1バイトしかないことが問題です。したがって、最も重要なバイトは変更されないままになります。

+2

+1それは正しいです、 'char'を' byte'に置き換えることはそのトリックを行うべきです。 – Groo

+0

試しましたが、結果は '..O♦&/ OOOe。'でした。私は、しかし、/と「e」が正しい場所にあることを知っているので、近づいています。 = P回答していただきありがとうございます、私はあなたが何か他のことを考えることができれば幸いです。 – Nick

1

は、ここでC++からC#にはほとんど直訳だし、動作するようです:

var packet = new byte[] { 
          0x0C, 0x00, 0xE2, 0x66, 0x65, 0x47, 
          0x4E, 0x09, 0x04, 0x13, 0x65, 0x00 
         }; 

CryptPacket(packet); 

// displays "....../here." where "." represents an unprintable character 
Console.WriteLine(Encoding.ASCII.GetString(packet)); 

// ... 

void CryptPacket(byte[] packet) 
{ 
    int paksize = (packet[0] | (packet[1] << 8)) - 2; 

    for (int i = 2; i < paksize; i++) 
    { 
     packet[i] ^= 0x61; 
    } 
} 
+0

ありがとう、私はすでに動作するコードを受け取りましたが、このバージョンは私が取り組んでいる別のプロジェクトで大変助けになります! – Nick

関連する問題