1

XOR を使用してファイルを暗号化/復号化しようとしています。次の暗号化/復号化ルーチンがあり、すべてのバイトが xor され、結果が前の場所にあるバイトの値によって減算されます。ASM の表現は次のとおりです。

crypt:
mov dl, [eax+ecx]   ; read byte
xor dl, 0C5h        ; xor it with oxC5
sub dl, [eax+ecx-1] ; sub the previous byte
mov [eax+ecx], dl   ; save the new byte
dec eax             ; decrement pointer
test   eax, eax
jg   short crypt     ;

これが私の暗号化ルーチンの外観です。これをこの C/C++ に移植しようとしています。私のコードは次のとおりです

#include <stdio.h>

unsigned int xorkey = 0xC5;

int main(int argc, char *argv[])
{
if(argc < 3)
{
    printf("usage: encoder input output\n");
    return -1;
}

FILE *in = fopen(argv[1], "rb");
if(in == NULL)
{
    printf("failed to open: %s", argv[2]);
    return -1;
}

FILE *out = fopen(argv[2], "wb");

if(out == NULL)
{
    fclose(in);
    printf("failed to open '%s' for writing.",argv[2]);
    return -1;
}

int count;
char buffer[1024];

while(count = fread(buffer, 1, 1024, in))
{
    int i;
    int end = count;

    for(i = 0;i < end; ++i)
    {
            ((unsigned int *)buffer)[i] ^= xorkey;
    }
    if(fwrite(buffer, 1, count, out) != count)
    {
            fclose(in);
            fclose(out);

            printf("fwrite() error\n");

            return -1;
    }
}

fclose(in);
fclose(out);

return 0;
}

C++ でバイトを減算する方法がわかりません。XOR ルーチン自体は正しいように見えますが、そうではありませんか? ファイルの最後から最初までファイルを暗号化しようとしていることに注意してください。何か案は?

ありがとう!

4

3 に答える 3

2

このアセンブリ言語関数をCで記述する方法は次のとおりです。変数名をレジスタ名と同じにしたので、さまざまな部分がどのように一致するかを確認できます。

void do_xor_crypt(char *buffer, int count) {
    char *ecx = buffer;
    int eax = count - 1;
    if (eax > 0) {
        do {
            char dl = ecx[eax];
            dl ^= 0xC5;
            dl -= ecx[eax-1];
            ecx[eax] = dl;
            eax--;
        } while (eax > 0);
    }
}

eaxループに減算するものがあるように、がゼロより大きい(つまりcount2つ以上)ことを確認したことに注意してください。このコードを次のように読み取りループに統合できます。

while (count = fread(buffer, 1, 1024, in))
{
    do_xor_crypt(buffer, count);
    if (fwrite(buffer, 1, count, out) != count)
    {
        // ...
    }
}
于 2011-02-16T07:27:24.453 に答える
1

C コードにはいくつか問題があります。

asm コードはバッファの末尾から始まり、下方向に動作し、eax == 0 のときに停止します。asm コードは一度に 1 バイトずつ操作し、前のバイトから xor と減算を行います。

asm コードは、バッファの最初のバイトをそのままにしておくように見えます。

C コードはインデックスを移動し、そのバイト インデックスが指す 4 バイトを 0xC5 で xor します。そのコードは 3 バイトを読みすぎており、XOR を使用して最下位バイトにのみ影響を与えています。

さらに、for ループは先頭から始まり、最後まで機能します。これは、asm ルーチンとは逆です。

文字がバイトサイズであると仮定すると、asm ルーチンを模倣するために、減算ステップは次のようになります。

buffer[i] = buffer[i] - buffer[i-1];

次のように書き換えることができます。

buffer[i] -= buffer[i-1];

... for ループを修正して、配列の末尾 1 からインデックス 1 に移動すると仮定します。

于 2011-02-16T07:00:14.313 に答える
0

buffertypeunsigned charに変更し、forループを次のように変更する必要があります。

for (i = count - 1; i > 0; i--)
{
    buffer[i] ^= xorkey;
    buffer[i] -= buffer[i - 1];
}

ただし、このコードは最初から 1024 バイトのチャンクでファイルを処理し、その後各チャンクを逆方向に処理することに注意してください。ファイル全体を逆方向に処理したい場合は、ファイルの最後から読み取りを開始し、各チャンクの最初の文字を特別に処理する必要があります。

于 2011-02-16T08:49:51.170 に答える