Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/56.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
有没有办法使用预处理器生成像+;或-从符号的ascii数字,不包括该符号?_C_C Preprocessor - Fatal编程技术网

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

有没有办法使用预处理器生成像+;或-从符号的ascii数字,不包括该符号?,c,c-preprocessor,C,C Preprocessor,因此,我试图混淆一些c代码,我想知道是否有一种方法可以从ascii中的十六进制/八进制/十进制代码生成像&(用于地址)或+或-(用于加法/减法)之类的运算符,而不必求助于某种表或包含字符的东西 理想情况下,如果没有混淆,它的工作原理如下: #define ADD(a, b) (a HEX(0x2b) b) //so ADD(10, 2) expands to 10 + 2 直接问题的答案是“不”。预处理器可以执行的唯一操作是替换和连接;其他一切都必须从这些基础上构建,这意味着,甚至像这样的事

因此,我试图混淆一些c代码,我想知道是否有一种方法可以从ascii中的十六进制/八进制/十进制代码生成像&(用于地址)或+或-(用于加法/减法)之类的运算符,而不必求助于某种表或包含字符的东西

理想情况下,如果没有混淆,它的工作原理如下:

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

直接问题的答案是“不”。预处理器可以执行的唯一操作是替换和连接;其他一切都必须从这些基础上构建,这意味着,甚至像这样的事情也需要在幕后通过查找表来实现

这并不一定意味着你不能按照你的想法混淆程序。毕竟,ASCII本身也只是一个查找表。因此,这与其说是一个能力问题,不如说是一个误导问题。有几种方法可以试图隐藏运算符查找表的存在或意义

e、 g.将一些错误的方向叠加在一起-

平台/其他/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
在这里,查找表隐藏在一个看起来吓人的系统文件中。滥用
CAT
STR
隐藏了这样一个事实,即该文件在简单的
grep
中使用(或主程序引用其中定义的宏)。查找表本身是在大多数人都认为未使用的
#ifndef
块中定义的(真正的
uuu GNUC_uu
没有中间下划线),它看起来像一个数组初始值设定项,而不是一个预处理器列表(它仍然是一个有效的预处理器列表,因为预处理器不使用
{}
用于分组,我们可以忽略第一个和最后一个元素),其中填充了可怕的内存初始值设定项表达式(十六进制常量由
EAT
删除,而
MEM\u INIT\u BASE
删除自身)
当然不存在,上面的一行注释掉了它(这实际上是一个非常明显的举动,也是一个坏主意,因为大多数编译器在默认情况下不启用Trigraph,但您可以使用另一个
#ifdef
技巧,例如
#ifdef MEM\u in t\u BASE
或类似的东西)

随着周围常数的自动删除,该列表只是一个非有序、非统一的运算符字符列表,可以通过相对传统的
SELECT
操作进行查询。对于额外的模糊处理,例如,您可以对传入索引执行一些预处理器数学运算,以使内容更加混乱


足够不透明吗?

如果你想要纯C的解决方案,我认为你运气不好。你需要在某处提到“+”。我试图用通用字符名来破解它(它允许您编写
\uxxx
来获取代码点XXXX处的Unicode字符——它需要
-fextended标识符才能使用
g++
),但您不能这样指定“+”(通用字符名只能使用某些字符)。它也不适用于宏。呃,适用于
gcc
。我认为它们是在C99中为C添加的。这并不是我真正想要的,但足够邪恶,足以让我标记为回答,特别是当我问“有没有办法”而不是“我怎么做”。
#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