我正在创建一个散列程序,该程序采用一个文件或标准输入,然后将散列输出到另一个文件中,或者通过标准输出输出到终端。我的问题是,由于参数的十六进制值发生变化,因此基于相同的stdin获得了不同的哈希值。

我的代码中发生这种情况的部分在这里:

    for (i = 3; i < argc; i++) {
        if (strcmp(argv[i], "-i") == 0 && argv[i+1] != NULL) {
            in = argv[i+1];
            in = strtok(in, " ");
    printf("arg \"%s\" hex: %02x\n", argv[i+1], argv[i+1]);
            inCheck = 1;
            i++;
        }
        else if (strcmp(argv[i], "-o") == 0 && argv[i+1] != NULL) {
            out = argv[i+1];
            i++;
        }
        else
            printf("Unknown argument %s. Ignoring.\n", argv[i]);
    }


基本上,我在这里检查命令行中“ -i”后面的输入的十六进制值。当我输入:

./executable hash -sha -i hello -o world我得到输出arg "hello" hex: ce4a2823
当我输入:

./executable hash -sha -i hello我得到输出arg "hello" hex: 247f582c
当我输入:

./executable hash -sha -o world -i hello我得到输出arg "hello" hex: 57e2f82c

所以我想知道为什么字符串的十六进制值会不断变化?

最佳答案

您不是在打印一些“字符串的十六进制值”,而是在打印字符串的地址。如果要打印字符串中第一个字符的十六进制值,可以执行以下操作:

printf("arg \"%s\" hex: %02x\n", argv[i+1], argv[i+1][0]);


十六进制值可能会有所不同,因为您的操作系统会在每次运行程序时随机分配堆栈的位置,以使缓冲区溢出/欠载漏洞利用更加困难。并且argv[]字符串可以存储在堆栈中(无需检查,我认为它们必须是可修改的,并且它们的长度当然不是静态的,因此在程序启动时将它们放入堆栈是一种自然的解决方案)。



由于您谈论“字符串的十六进制值”,因此请注意:C字符串基本上只是包含1个或多个char的内存(例如char数组)的地址:字符串的字符,以及终止'\0'字节的字符串(即使字符串为空也必须存在)。与大多数其他语言的字符串类型相比,这是非常原始的事情。

10-08 11:01