原理超简单...使用FormatMessageA获取错误信息文本, 用里面的字符拼出字符串, 这样程序编译出来就不直接带有字符串明文了
#include <stdio.h>
#include <string>
#include <iostream>
#include <windows.h>
#include <boost/preprocessor.hpp>
#include <boost/mpl/string.hpp>
std::string GetErrText(DWORD errc, WORD lang_id) {
char *msg_buf;
if (0 == FormatMessageA(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, errc, lang_id, reinterpret_cast<char*>(&msg_buf), 0, NULL))
return "";
std::string ret(msg_buf);
LocalFree(msg_buf);
return ret;
}
#ifndef STRING_MAX_LENGTH
#define STRING_MAX_LENGTH 32
#endif
template <int N>
constexpr char at(char const(&s)[N], int pos) {
return pos >= N ? '\0' : s[pos];
}
template <typename S, char C, bool EOS>
struct push_back_if_c :
boost::mpl::push_back<S, boost::mpl::char_<C>> {};
template <typename S, char C>
struct push_back_if_c<S, C, true> : S {};
#define PRE_RTS(_, __, ___) push_back_if_c<
#define POST_RTS(_, n, s) , at(s, n), (n >= sizeof(s)-1)>::type
#define _RTS(s) \
BOOST_PP_REPEAT(STRING_MAX_LENGTH, PRE_RTS, _) \
boost::mpl::string<> \
BOOST_PP_REPEAT(STRING_MAX_LENGTH, POST_RTS, s)
#define RTS(s) \
[] () { \
typedef _RTS(s) str; \
return StringBuilder<boost::mpl::begin<str>::type, \
boost::mpl::end<str>::type>()(); \
}()
#define ENGLISH_ID MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US)
#define CHINESE_ID MAKELANGID(LANG_CHINESE_SIMPLIFIED, SUBLANG_CHINESE_SIMPLIFIED)
//! (char, err_code, lang_id, pos)
#define CHAR_LIST \
((' ', 0, ENGLISH_ID, 3)) \
(('i', 16, ENGLISH_ID, 5)) \
(('a', 0, ENGLISH_ID, 8)) \
(('b', 7, ENGLISH_ID, 20)) \
(('c', 8, ENGLISH_ID, 38)) \
(('d', 9, ENGLISH_ID, 27)) \
(('e', 10, ENGLISH_ID, 2)) \
(('f', 11, ENGLISH_ID, 56)) \
(('g', 14, ENGLISH_ID, 8)) \
(('h', 15, ENGLISH_ID, 1)) \
(('j', 52, ENGLISH_ID, 74)) \
(('k', 53, ENGLISH_ID, 10)) \
(('l', 55, ENGLISH_ID, 47)) \
(('m', 56, ENGLISH_ID, 19)) \
(('n', 57, ENGLISH_ID, 2)) \
(('o', 58, ENGLISH_ID, 25)) \
(('p', 59, ENGLISH_ID, 7)) \
(('q', 61, ENGLISH_ID, 12)) \
(('r', 62, ENGLISH_ID, 12)) \
(('s', 63, ENGLISH_ID, 34)) \
(('t', 64, ENGLISH_ID, 16)) \
(('u', 66, ENGLISH_ID, 16)) \
(('v', 70, ENGLISH_ID, 14)) \
(('w', 86, ENGLISH_ID, 17)) \
(('x', 101, ENGLISH_ID, 5)) \
(('y', 108, ENGLISH_ID, 30)) \
(('z', 223, ENGLISH_ID, 11)) \
(("中"[0], 2, CHINESE_ID, 10)) \
(("中"[1], 6, CHINESE_ID, 6)) \
(("文"[0], 8, CHINESE_ID, 14)) \
(("文"[1], 11, CHINESE_ID, 19)) \
(("成"[0], 14, CHINESE_ID, 20)) \
(("成"[1], 16, CHINESE_ID, 4)) \
(("功"[0], 32, CHINESE_ID, 15)) \
(("功"[1], 51, CHINESE_ID, 61))
#define GENERATE_BUILDER_(_, __, elem) \
template<> \
struct _StringBuilder<BOOST_PP_TUPLE_ELEM(0, elem)> { \
std::string operator () () { \
return std::string(1, GetErrText(BOOST_PP_TUPLE_ELEM(1, elem), \
BOOST_PP_TUPLE_ELEM(2, elem))[BOOST_PP_TUPLE_ELEM(3, elem)]); \
} \
};
#define GENERATE_BUILDER(char_list) \
template<char C> struct _StringBuilder; \
BOOST_PP_SEQ_FOR_EACH(GENERATE_BUILDER_, _, char_list) \
template<typename itr, typename last> \
struct StringBuilder { \
std::string operator () () { \
return _StringBuilder<itr::type::value>()() + \
StringBuilder<typename boost::mpl::next<itr>::type, last>()(); \
} \
}; \
template<typename last> \
struct StringBuilder<last, last> { \
std::string operator () () { \
return ""; \
} \
};
GENERATE_BUILDER(CHAR_LIST)
int main() {
std::cout << RTS("hello world") << std::endl;
std::cout << RTS("中文成功") << std::endl;
return 0;
}
用到了boost的preprocessor和mpl, 另外还有一些c++11的特性, 得用对新标准支持比较好的编译器
[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法