【问题标题】:Simple XOR encryption routine in C/C++C/C++ 中的简单 XOR 加密例程
【发布时间】:2011-06-28 03:40:57
【问题描述】:

我正在尝试使用 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 例程本身看起来是正确的,不是吗? 请注意,我也在尝试从文件末尾到开头加密文件。有什么想法吗?

谢谢!

【问题讨论】:

  • 有点难以在同一个句子中阅读“加密”和“异或”,而没有否定之间......混淆?当然。是的。完全。加密?没那么多。
  • 没有像 C/C++ 这样的语言。它是 C C++。选一个。 (我希望你为这段代码选择 C。)
  • @Keith 你显然从来没有上过密码学课,甚至懒得去阅读加密这个词的定义。 XOR cipher is absolutely an encryption method.
  • @Keith 如果有足够聪明的头脑解决问题,几乎任何问题都可以变得微不足道。加密就是加密,它不是一个松散定义的术语。
  • @Keith 告诉你,我会在 5 分钟内拼凑出一个 XOR 算法,如果我给你 5 年,你自己也无法解决 :) 这一切都取决于上下文。

标签: c encryption xor


【解决方案1】:

以下是您如何使用 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)
    {
        // ...
    }
}

【讨论】:

  • 抱歉,我不知道如何实现。
  • @Brian Blankenship:我已经修改了我的答案,以明确向您展示如何将其集成到您现有的代码中。
  • @Brian,这正是您正在寻找的答案。
【解决方案2】:

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

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

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

【讨论】:

    【解决方案3】:

    您的 C 代码有一些问题。

    asm 代码从缓冲区的末尾开始,向下运行,并在 eax == 0 时停止。 asm 代码一次对一个字节进行操作,对前一个字节进行异或运算。

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

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

    另外,您的 for 循环从前面开始并一直运行到最后 - 与您的 asm 例程相反。

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

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

    可以改写为:

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

    ...假设您将 for 循环修复为从数组的 end-1 到索引 1。

    【讨论】:

    • +1:可靠的分析,但提出这个问题的人可能仍然难以理解您解释中所需的修复。归结为首先读取文件的最后一部分(或一次全部读入内存),然后使用((unsigned char *)buffer)[i] 向下异或递增,减去前一个字节。
    • 好吧,我知道我的 C/C++ 代码不正确,但我正在尝试完全按照 ASM 代码中的方式实现算法。从下到上处理缓冲区并跳过第一个字节。我该怎么做呢?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-14
    • 1970-01-01
    相关资源
    最近更新 更多