所以我试图混淆一些c代码,我想知道是否有一种方法可以从它的十六进制/生成像&(用于地址)或+或-(用于加/减)等运算符ascii 中的八进制/十进制代码,无需借助某种表或包含该字符的内容。
理想情况下,如果没有混淆的话,它会像下面这样工作:
#define ADD(a, b) (a HEX(0x2b) b)
//so ADD(10, 2) expands to 10 + 2
最佳答案
直接问题的答案是“否”。预处理器可以执行的唯一操作是替换和串联;其他一切都必须从这些构建起来,这意味着即使是像 arithmetic 这样的东西也需要通过幕后的查找表来实现。
这并不一定意味着您不能按照您想要的方式混淆程序。毕竟,ASCII 本身也只是一个查找表。因此,这与其说是能力问题,不如说是误导问题。您可以通过多种方法尝试隐藏运算符查找表的存在或含义。
例如将一些误导叠加在一起 -
platforms/other/std-compat.h
:
#ifndef __GNU_C__
// non-GCC systems can't rely on this being provided automatically
#define MEM_INIT_MAP (int[]){ \
(0x112a8)*MEM_INIT_BASE, (0x115a8)*MEM_INIT_BASE, (0x115a9)+MEM_INIT_END, (0x11505)+MEM_INIT_END, \
(0x112a0)*MEM_INIT_BASE, (0x115a0)*MEM_INIT_BASE, (0x115a0)+MEM_INIT_END, (0x11517)-MEM_INIT_END, \
(0x112a1)*MEM_INIT_BASE, (0x115a1)*MEM_INIT_BASE, (0x115a9)/MEM_INIT_END, (0x11505)+MEM_INIT_END, \
(0x112a2)*MEM_INIT_BASE, (0x115a2)*MEM_INIT_BASE, (0x115a0)+MEM_INIT_END, (0x11517)%MEM_INIT_END, \
(0x112a3)*MEM_INIT_BASE, (0x115a3)*MEM_INIT_BASE, (0x115a9)|MEM_INIT_END, (0x11505)&MEM_INIT_END, \
(0x112a4)*MEM_INIT_BASE, (0x115a4)*MEM_INIT_BASE, (0x115a0)+MEM_INIT_END, (0x11517)+MEM_INIT_END, \
(0x112a5)*MEM_INIT_BASE, (0x115a5)*MEM_INIT_BASE, (0x115a9)>MEM_INIT_END, (0x11505)+MEM_INIT_END, \
(0x112a6)*MEM_INIT_BASE, (0x115a6)*MEM_INIT_BASE, (0x115a0)+MEM_INIT_END, (0x11517)<MEM_INIT_END, \
(0x112a7)*MEM_INIT_BASE, (0x115a7)*MEM_INIT_BASE, (0x115a9)^MEM_INIT_END, (0x11505)+MEM_INIT_END, \
}
#define MEM_INIT_BASE // sentinel: will be redefined by OS header
#define MEM_INIT_END // similarly??/
#include <vmmem/protect_init.h>
#endif
主文件:
#define OP_IMPL STR(CAT(platfo, CAT(rms/othe, CAT(r/std-comp, at.h))))
#define STR(S) STR_(S)
#define STR_(S) #S
#define CAT(A, B) CAT_(A, B)
#define CAT_(A, B) A ## B
#define EAT(...)
#define ID(...) __VA_ARGS__
#define SELECT(X, ...) CAT(SELECT_, X)(__VA_ARGS__)
#define SELECT_0(_0, ...) _0
#define SELECT_1(_0, _1, ...) _1
#define SELECT_2(_0, _1, _2, ...) _2
#define SELECT_3(_0, _1, _2, _3, ...) _3 // etc.
#define OP(X) ID(EAT SELECT(X, CAT(MEM_, CAT(INIT_, MAP))))
#include OP_IMPL
10 OP(2) 2 // expands to 10 + 2
这里的查找表隐藏在一个看起来像系统的令人生畏的文件中。滥用 CAT
和 STR
隐藏了这样一个事实:该文件完全是通过简单的 grep
使用的(或者主程序引用了其中定义的宏)。查找表本身是在 #ifndef
block 中定义的,大多数人会认为该 block 未使用(真正的 __GNUC__
没有中间下划线),并且看起来像数组初始值设定项而不是预处理器列表(它仍然是有效的预处理器列表,因为预处理器不使用 {}
进行分组,我们可以忽略第一个和最后一个元素,其中充满了可怕的内存初始化表达式(十六进制常量被 EAT
删除,并且 MEM_INIT_BASE
删除自身)。 <vmmem/protect_init.h>
当然不存在,并被上面的行注释掉(这实际上是一个非常明显的举动和坏主意,因为大多数编译器默认情况下不启用三字母,但您可以进一步使用另一个 #ifdef
技巧,例如 #ifdef MEM_IN1T_BASE
或类似的东西)。
随着周围常量的自删除,该列表只是一个无序、非统一的运算符字符列表,可以通过相对传统的 SELECT
操作来查询。为了额外的混淆,你可以例如对传入索引执行一些预处理器数学运算,以进一步调整内容。
足够不透明吗?
关于c - 有没有办法使用预处理器从符号的 ascii 数字生成 + 或 - 等运算符,而不包含该符号?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28976253/