有没有办法使用预处理器生成像+或 - 的运算符,从符号的ascii数字,而不包括该符号?

时间:2015-03-10 23:59:00

标签: c c-preprocessor

所以我试图模糊一些c代码,我想知道是否有办法生成类似&的运算符。 (对于地址),或者+或 - (用于加法/减法)等,来自它在ascii中的十六进制/八进制/十进制代码,而不是诉诸某种表或包含该字符的东西。

理想情况下,如果它没有被混淆,这将如下所示:

#define ADD(a, b) (a HEX(0x2b) b)
//so ADD(10, 2) expands to 10 + 2 

1 个答案:

答案 0 :(得分:1)

直接问题的答案是" no"。预处理器可以执行所有的唯一操作是替换和连接;其他一切都必须从这些构建起来,这意味着甚至像arithmetic之类的东西也需要在幕后查找表来实现。

这并不一定意味着您可以按照自己的方式对程序进行模糊处理。毕竟,ASCII本身也只是一个查找表。因此,这不是功能的问题,而是一种误导。有几种方法可以尝试隐藏运算符查找表的存在或含义。

e.g。将错误一起分层 -

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

这里查找表隐藏在一个令人生畏的系统外观文件中。滥用CATSTR隐藏了一个事实,即文件完全来自一个简单的grep(或主程序引用其中定义的宏)。查找表本身是在#ifndef块中定义的,大多数人都认为它是未使用的(真正的__GNUC__没有中间下划线),并且看起来像一个数组初始化器而不是预处理器列表(它仍然是一个有效的预处理器列表,因为预处理器没有使用{}进行分组,我们可以忽略填充了可怕内存初始化表达式的第一个和最后一个元素(十六进制常量被{{1除去) }},EAT删除自己)。 MEM_INIT_BASE当然不存在并且被上面的行注释掉(这实际上是一个非常明显的举动和坏主意,因为大多数编译器默认情况下不启用三字符,但你可以使用另一个<vmmem/protect_init.h>进一步向下,例如#ifdef或类似的东西。)

在周围常量自我删除的情况下,列表只是一个非有序的,非统一的运算符字符列表,可以通过相对传统的#ifdef MEM_IN1T_BASE操作进行查询。对于额外的混淆,你可以例如对传入的索引执行一些预处理器数学运算,以便将事情稍微改变一下。

不够透明?