C / C ++中的简单XOR加密例程

时间:2011-02-16 06:50:35

标签: c encryption xor

我正在尝试使用XOR加密/解密文件。我有以下加密/解密例程,其中每个字节都是xor'd,结果将被位于前一个位置的字节的值减去。 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例程本身看起来是正确的,不是吗? 请注意,我还尝试从文件末尾开始加密文件直到开头。有什么想法吗?

谢谢!

3 个答案:

答案 0 :(得分: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大于零(意味着count为两个或更多),以便循环可以减去。您可以将此代码集成到您的阅读循环中,如:

while (count = fread(buffer, 1, 1024, in))
{
    do_xor_crypt(buffer, count);
    if (fwrite(buffer, 1, count, out) != count)
    {
        // ...
    }
}

答案 1 :(得分:1)

您的C代码存在一些问题。

asm代码从缓冲区的末尾开始,向下运行并在eax == 0时停止。 asm代码一次操作一个字节,xor'ing并从前一个字节中减去。

asm代码似乎不会触及缓冲区的第一个字节。

您的C代码移动索引,并将该字节索引指向的四个字节与0xC5进行异或。该代码读取的字节数太多,只影响XOR的最低字节。

另外,你的for-loop从前面开始,一直到最后 - 与你的asm例程相反。

假设字符是字节大小的,那么为了模仿asm例程,你的减法步骤将是:

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

可以改写为:

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

...假设您修复了for-loop从数组的end-1到索引1。

答案 2 :(得分:0)

您需要更改buffer以键入unsigned char,并将for循环更改为:

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

请注意,此代码从一开始就以1024字节的块的形式处理文件,然后以相反的方式处理每个块。如果你想反过来处理整个文件,你需要从它的末尾开始阅读,并对每个块中的第一个字符进行特殊处理。