Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 试图通过一些散列来篡改我的可执行文件,但遇到了一些意外和未知的编译器行为_C_Ubuntu_Gcc_Compilation - Fatal编程技术网

C 试图通过一些散列来篡改我的可执行文件,但遇到了一些意外和未知的编译器行为

C 试图通过一些散列来篡改我的可执行文件,但遇到了一些意外和未知的编译器行为,c,ubuntu,gcc,compilation,C,Ubuntu,Gcc,Compilation,在尝试用一些散列来防篡改我的可执行文件时,我遇到了一些意想不到的未知编译器行为 我有这样一个想法,即通过简单地将二进制文件中的所有字节相加,并使用总数的剩余部分除以256作为散列值来计算程序的简单散列值 我想,如果在我的程序中,我有一个字符串文字“0000”,并且我用上面的算法计算的哈希值是163,那么我可以通过将“0”中的一个替换为“1”得到164。然而,我得到的结果远非如此。通过用单个值替换单个字符,我得到了完全不同的哈希结果。在这个例子中,163可能变成84,这让我感到困惑 我用来计算散列

在尝试用一些散列来防篡改我的可执行文件时,我遇到了一些意想不到的未知编译器行为

我有这样一个想法,即通过简单地将二进制文件中的所有字节相加,并使用总数的剩余部分除以256作为散列值来计算程序的简单散列值

我想,如果在我的程序中,我有一个字符串文字“0000”,并且我用上面的算法计算的哈希值是163,那么我可以通过将“0”中的一个替换为“1”得到164。然而,我得到的结果远非如此。通过用单个值替换单个字符,我得到了完全不同的哈希结果。在这个例子中,163可能变成84,这让我感到困惑

我用来计算散列的函数非常简单,但这里就是了

int calcHash(const char *filename) {
    int hash = 0;
    int c;
    FILE *fh = fopen(filename, "r");

    if (!fh)
        return -1;

    while((c = fgetc(fh)) != EOF)
        hash = (hash + c) % 256;

    fclose(fh);

    return hash;
}
我用这个语句从main()调用它

int hash = calcHash(argv[0]);
编译过程中到底发生了什么?无论如何,我可以得到更可预测的散列值吗

也许并非所有编译器都会出现这种情况。我对这种意想不到的行为完全感到困惑


我在Ubuntu上使用gcc。

这是一个比看起来更难的问题,也是一个比看起来更糟糕的想法-我不推荐这个

我在一个客户系统上工作,他们在那里做了这件事,这是一件非常痛苦的事情,正如有人建议的那样,所以我最终对它进行了反向工程,以编写我自己的重新密封实用程序,这样我就可以编辑该死的文件并应用新的哈希。而这些变化始终是为了软件供应商及其客户的利益,而不是为了窃取软件或其他任何东西

但在任何情况下,正如我所记得的那样,它通过在代码中包含一些数据区域来工作:

char tamper_marker_1[] = "SOME MAGIC STRING";
int  fileSize;
unsigned checksum;
char endmarker[] = "OTHER MAGIC STRING";
外部应用seal程序将打开
.exe
并找到指向上述数据区域的神奇字符串,并将填充除seal信息区域之外的所有数据的
文件大小
校验和

可执行文件通过将自身作为文件打开并执行相同的检查来测试篡改

在Windows下,您可以使用
GetModuleFilename()
查找可执行文件的完整路径,在Linux上,您可以打开
/proc/12345/exe
(其中12345是您的进程ID),它是指向程序的符号链接,也是一样

我不知道我这样描述是否有助于让世界变得更糟,但问题和答案也是如此,也许这是合理的需要。请不要这样做,除非你真的,真的必须这样做

编辑:你可能会指出,很少有人会像我做的逆向工程那样麻烦,但我要指出的是,你所需要的只是一个人来创建重新密封工具并发布它,而你所有的聪明工作都是徒劳的


EDIT2:在我思考这个问题时,如果它只是一个程序,你就不需要对算法进行反向工程——你只需要能够将其反汇编以停止测试。

为了证明我的可执行文件的可靠性,请不要这样做。你只是让那些有合法需要对你的可执行文件进行hexedit的人的生活变得更加艰难,而且丝毫没有妨碍盗版或反向工程。为什么人们有合法需要对我的可执行文件进行hexedit?我是说,真的吗?如果你在同一个文件上多次运行你的算法,它每次都会产生相同的散列吗?这就是散列函数需要做的全部工作。事实上,您描述的行为就是您希望哈希执行的操作。这将便于检查您的exe是否已被编辑。而且我相信这个词是防篡改的,当我运行多次时,我总是得到相同的哈希结果。我想在我的可执行文件中包含这个值,这样它就可以检查自己了。然而,有了解释过的行为,这样做几乎是不可能的。谢谢你纠正我“tamper”的拼写。你到底是怎么编译的?所有可执行文件都包含内务管理信息,有些包含调试信息,有些版本甚至可能包含时间戳。建议编译两次程序,并比较结果
a.out
的十六进制转储,以查看即使您不更改任何程序文本,也会发生什么更改。如果我确实决定对程序进行防篡改,我将使用您的解决方案。我完全知道,总有一种方法可以对代码进行反向工程和反汇编。我只是想让这更难做到。