MSVC++环境下是否有宏/模板快捷方式在栈帧中定义char数组?
MSVC环境下逐字符构建栈数组的宏实现
实现方案
方案1:无第三方依赖的固定最大长度版本
不需要引入任何外部库,直接使用MSVC原生预处理器实现,以下版本支持最长64字符的字符串,需要更长的话自行在宏中添加对应下标的行即可:
// 最长支持64字符的字符串,需要更长可按相同格式添加更多行 #define MACRO(arr, s) char arr[] = { \ #s[0], #s[1], #s[2], #s[3], #s[4], #s[5], #s[6], #s[7], \ #s[8], #s[9], #s[10], #s[11], #s[12], #s[13], #s[14], #s[15], \ #s[16], #s[17], #s[18], #s[19], #s[20], #s[21], #s[22], #s[23], \ #s[24], #s[25], #s[26], #s[27], #s[28], #s[29], #s[30], #s[31], \ #s[32], #s[33], #s[34], #s[35], #s[36], #s[37], #s[38], #s[39], \ #s[40], #s[41], #s[42], #s[43], #s[44], #s[45], #s[46], #s[47], \ #s[48], #s[49], #s[50], #s[51], #s[52], #s[53], #s[54], #s[55], \ #s[56], #s[57], #s[58], #s[59], #s[60], #s[61], #s[62], #s[63], \ 0 \ }
方案2:自适应任意长度的Boost实现
如果可以引入纯头文件的Boost.Preprocessor库,可实现自动适配任意长度的输入字符串,无需手动调整宏的长度上限:
#include <boost/preprocessor/stringize.hpp> #include <boost/preprocessor/seq/for_each_i.hpp> #include <boost/preprocessor/punctuation/comma_if.hpp> #define GEN_CHAR(r, _, idx, ch) BOOST_PP_COMMA_IF(idx) ch #define STR_TO_SEQ(s) BOOST_PP_SEQ_FOR_EACH_I(GEN_CHAR, ~, s) #define MACRO(arr, s) char arr[] = { STR_TO_SEQ(BOOST_PP_STRINGIZE(s)), 0 };
效果验证
按示例用法调用:
int main() { MACRO(arr, thisisasuperlongstring); }
MSVC预处理器展开后会直接生成期望的逐字符初始化数组,不会在常量区生成额外的字符串副本,编译后会直接在栈帧原位构建字符数组,完全符合shellcoding场景的要求。
注意事项
- 若需要传入带空格、特殊字符的字符串,可将宏中的
#s/BOOST_PP_STRINGIZE(s)修改为直接使用s,调用时传入带引号的字符串字面量即可,例如MACRO(arr, "test string 123!")。 - 编译时配合MSVC的
/O1优化选项,可确保编译器完全生成逐字符压栈的代码,无额外内存引用。
内容的提问来源于stack exchange,提问作者wmi
相关产品推荐
相关产品推荐

