如何理解代码

时间:2016-07-06 21:36:46

标签: c

我最近得到了这个代码,我很难理解。我对整体编程很新,我还在学习。任何有关这方面的信息将不胜感激。这是出现的代码:

void enc(char* plaintxt, unsigned char key) 
{ 
    while(*plaintxt)
    { 
        *plaintxt^ = (key=(key*13)+37);
        *(plaintxt++) +=3;
    }
}

输出:

0F A8 9F FE 7A D6 E2 08 AE 2B 5F 53 25 9A

2 个答案:

答案 0 :(得分:6)

了解您拥有的具体问题会有所帮助。

简而言之,此代码使用字符串并使用键值对其进行加密/编码。这条线

*plaintxt^ = (key=(key*13)+37);

是一种非常密集的写作方式

*plaintxt = *plaintxt ^ (key * 13 + 37);
key = key * 13 + 37;

但需要注意的是,未指定更新key*plaintxt的确切顺序(IOW,原始代码key可能会在{{1}之前或之后更新更新)。

*plaintxt运算符是按位XOR运算符; ^中的每个位与*plaintext中的每个位进行异或运算。

该行

key

是一种密集的写作方式

 *(plaintxt++) +=3;

同样需要注意,未指定更新 *plaintxt = *plaintxt + 3; plaintxt = plaintxt + 1; *plaintxt的确切顺序。这一行将plaintxt添加到3,然后将指针前进到指向字符串中的下一个字符。

在C中,字符串是由*plaintext终止的字符值序列。 0是指向字符串第一个字符的指针。 plaintext循环通过测试while的值来检查我们是否未到达字符串的末尾; *plaintxtwhile ( *plaintext )相同。

所以,我们假设while ( *plaintext != 0 )指向字符串plaintext 1

"test"

并且 +---+ +----+ plaintext: | | ----> "test" | 74 | Assumes ASCII, all values in hex +---+ +----+ | 65 | +----+ +----+ key: | 1 | | 75 | +----+ +----+ | 74 | +----+ | 0 | +----+ 最初是1.

在循环开始时,key指向plaintext中的第一个t(ASCII "test")。我们用0x74的结果对此进行异或,结果为十进制50,或十六进制为0x32:

key * 13 + 37

我们将此值写回 0x74 ^ 0x32 == 0x46 ,然后将3添加到它,给我们0x49。我们将0x32保存到*plaintext。然后我们前进key指向字符串中的下一个字符,给我们:

plaintext

现在我们对 +---+ +----+ plaintext: | | --+ "Iest" | 49 | +---+ | +----+ +-------> | 65 | +----+ +----+ key: | 32 | | 75 | +----+ +----+ | 74 | +----+ | 0 | +----+

做同样的事情
e

key = 50 * 13 + 37 == 687 % 255 == 177 == 0xb1 只能存储0到2 CHAR_BIT -1的值,这在大多数现代系统中都是255; 687太大而无法存储在unsigned char中,因此它“回绕”回到177或0xb1 2

key

完成所有操作后,我们

0x65 ^ 0xb1 == 0xd4
0xd4 + 3    == 0xd7

泡沫,冲洗,重复。这将持续到 +---+ +----+ plaintext: | | --+ "I?st" | 49 | +---+ | +----+ | | d7 | +----+ | +----+ key: | b1 | +--------> | 75 | +----+ +----+ | 74 | +----+ | 0 | +----+ 指向包含0的存储器单元。

<小时/>

  1. 从技术上讲,它指的是包含字符串“test”的数组,而不是字符串文字`“test”`。字符串文字可能没有修改其内容;尝试这样做会调用未定义的行为。
  2. 仅适用于 unsigned 整数类型;有符号整数类型的溢出没有明确定义,并且可能无法按预期运行。

答案 1 :(得分:0)

我知道它有点晚了,无论你从那张卡上获得的任何安全会议都已经结束了(Raytheon Game Of Pwns)......但是让我为你省一些挫折感。 您不会找到比上面显示的代码更好的描述,但您根本不需要重新创建此代码来解决密码。 你甚至不需要知道C. 无论您选择哪种语言,都可以生成轻松破解此代码的密钥。 鉴于初始键只有256个可能的值(0-255),你可以强制它,但你可以通过有根据的猜测来解决这个问题,以获得键的第一个值。

Game of Pwns卡包含密钥,您可能会在解决解析为Key = 2EZ01的二进制编码ASCII消息时注意到这些密钥。你可以猜到第一个字符可能是一个大写的K(0x4B)。 关于XOR操作的有趣事实是它可以用来反转自身。 让我们假设第一个字符确实是K,我们已经知道第一个输出元素是0x0F(实际上是0x0C)。这告诉我们 Flag ^ key =(output-3) 诀窍是 (输出-3)^标志=键! 基于该假设,我们可以获得apply的第一个结果,即0x0C ^ 0x4B = 0x47。

两个重要的注释,代码中的13和37确实是十进制值,而不是十六进制,并且在索引到数组中的下一个char之前,标志会增加3。

使用第一个键,您可以通过创建循环以您使用的任何语言生成其余的键,以便使用下一个13键 ((key*13)+37) %256模仿C中unsigned char的环绕行为。 当你有14个密钥时,只需将列表中的每个密钥与其对应的原始输出(-3)进行异或,以获得编码消息,这很清楚...它开始于Key = 如果你还从Raytheon得到了另一张具有相似外观代码的卡,那么该卡上的所有密码都以Flag =开头,所以你可以简单地应用你在这里学到的关于XOR的知识来轻松破解那个。