我们可以在 C 或 C++ 中打乱声明顺序吗?

Can we scramble the declaration order in C or C++?

本文关键字:声明 顺序 C++ 我们      更新时间:2023-10-16

是否有一个方法/插件/插件可以忽略以下子句(对于某些c/c ++编译器)?在与预处理器或类似程序相同的阶段对结构中成员的声明重新排序?也许通过添加一个关键字,如 volatile 或类似于结构声明前面的东西。

我在想:编译器选项、内置关键字或编程方法。

C99 §6.7.2.1 第13条规定:

在结构对象中, 非位字段成员和单元 哪些位字段具有地址 增加的顺序 他们被宣布。

C++似乎有一个类似的条款,我也对此感兴趣。这两个子句都指定了一个合理的功能,即在以后的声明中具有更大的内存偏移量。但是,出于接口目的或其他目的,我通常不需要知道结构的声明顺序。最好编写一些代码,例如:

scrambled struct foo {
    int a;
    int bar;
};

或者,假设顺序对于这个结构并不重要。

scrambled struct foo {
    int bar;
    int a;
};

因此,每次编译时,ab的声明都会随机交换。我相信这也适用于留出堆栈内存。

main() {
    scrambled int a;
    scrambled int foo;
    scrambled int bar;
    ..

我为什么要问?

我很想知道程序机器人是如何创建的。我看到一些人在运行将创建黑客的程序时分析内存偏移的变化。

似乎过程是:观察内存偏移并记下给定偏移的目的。稍后,hack 程序将在这些偏移处将所需值注入内存。

现在假设每次编译程序时,这些内存偏移量都会更改。也许这会阻碍或劝阻个人花时间去理解你宁愿他们不知道的事情。

运行时

狐狸是最好的方法,那么你只需要发布一个版本。如果struct具有多个相同类型的字段,则可以改用数组。第 1 步。使用数组代替具有三个int字段的结构

#define foo 0
#define bar 1
#define zee 2
struct abc {
    int scramble [3];
};
...
value = abc.scramble[bar];

第 2 步,现在使用每次程序运行时随机化的索引数组。

int abcindex [3];               // index lookup 
int abcpool  [3];               // index pool for randomise
for (i=0; i<3; i++)             // initialise index pool
    abcpool[i] = i;
srand (time(NULL));
for (i=0; i<3; i++) {           // initialise lookup array
    j = rand()%(3-i);
    abcindex[i] = abcpool[j];   // allocate random index from pool
    abcpool[j] = abcpool[2-i];  // remove index from pool
    }
value = abc.scramble[abcindex[bar]];

另一种试图欺骗黑客的方法是包含诡计变量,这些变量的行为就好像它们与它有关,但如果被篡改,会使程序退出。最后,您可以保留密钥变量的某种校验和或加密副本,以检查它们是否被篡改。

你的意图是好的,但解决方案不是(对不起)。通常,您无法在每次运行之前重新编译程序。攻击者将入侵检查的程序。但是,有一种解决方案,称为ASLR。操作系统可以为您更改加载地址,从而使"面向返回的编程"和"像黑客一样返回libc变得更加困难"。