Собственно говоря нужно инициализировать строку таким образом, чтобы каждый символ её был изменён. К примеру имеем макрос: #define ADD(_c_) _c_ + 3 И его нужно применить к каждом символу строки при её инициализации. До этого использовал так char STR[] = { ADD('h'), ADD('e'), ADD('l'), ADD('l'), ADD('o') }; Но это очень не удобно для большого кол-ва строк. Или если строки очень длинные, то запаришься всё так оформлять. Может кто-нибудь знает как это всё оформить в виде макроса?
проверил на C/C++ VS2008 Code: /// #include <boost/preprocessor.hpp> #define CT_INIT_WTF(...) , ## __VA_ARGS__ #define CT_INIT_COUNT_PARMS2(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _, ...) _ #define CT_INIT_REPEAT_PARAMS(...) (__VA_ARGS__) #define CT_INIT_COUNT_PARMS(...) \ CT_INIT_COUNT_PARMS2 CT_INIT_REPEAT_PARAMS(CT_INIT_WTF(__VA_ARGS__) 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) #define CT_INIT_MAKESEQ(n,...) BOOST_PP_TUPLE_TO_SEQ(n, (__VA_ARGS__)) #define CT_INIT_MACRO(r,data,i,x) \ (((x)<=0xffu) ? ((x)&0xff)+(CT_INIT_MAGIC) : ((x)<=0xffffu) ? (((x)&0xff00)>>8)+(CT_INIT_MAGIC) : \ ((x)<=0xffffffu) ? (((x)&0xff0000)>>16)+(CT_INIT_MAGIC) : (((x)&0xff000000)>>24)+(CT_INIT_MAGIC)) \ , \ (((x)<=0xffu) ? 0 : ((x)<=0xffffu) ? ((x)&0xff)+(CT_INIT_MAGIC) : \ ((x)<=0xffffffu) ? (((x)&0xff00)>>8)+(CT_INIT_MAGIC) : (((x)&0xff0000)>>16)+(CT_INIT_MAGIC)) \ , \ (((x)<=0xffu) ? 0 : ((x)<=0xffffu) ? 0 : \ ((x)<=0xffffffu) ? ((x)&0xff)+(CT_INIT_MAGIC) : (((x)&0xff00)>>8)+(CT_INIT_MAGIC)) \ , \ (((x)<=0xffu) ? 0 : ((x)<=0xffffu) ? 0 : \ ((x)<=0xffffffu) ? 0 : ((x)&0xff)+(CT_INIT_MAGIC)) \ , \ BOOST_PP_IF(BOOST_PP_LESS(BOOST_PP_INC(i),data), BOOST_PP_EMPTY(), '\0') #define CT_INIT_IMPL(n,...) \ BOOST_PP_SEQ_FOR_EACH_I(CT_INIT_MACRO,n,CT_INIT_MAKESEQ(n,__VA_ARGS__)) /// #define CT_INIT_MAGIC 3 #define $(...) CT_INIT_IMPL(CT_INIT_COUNT_PARMS(__VA_ARGS__),__VA_ARGS__) int main() { char buf[]={$('byte')}; char dup[]={$('shlw','api3','2.dl','l')}; } Code: int main() { 00411250 55 push ebp 00411251 8B EC mov ebp,esp 00411253 83 EC 5C sub esp,5Ch 00411256 53 push ebx 00411257 56 push esi 00411258 57 push edi char buf[]={$('byte')}; 00411259 C6 45 F8 65 mov byte ptr [buf],65h 0041125D C6 45 F9 7C mov byte ptr [ebp-7],7Ch 00411261 C6 45 FA 77 mov byte ptr [ebp-6],77h 00411265 C6 45 FB 68 mov byte ptr [ebp-5],68h 00411269 C6 45 FC 00 mov byte ptr [ebp-4],0 char dup[]={$('shlw','api3','2.dl','l')}; 0041126D C6 45 E4 76 mov byte ptr [dup],76h 00411271 C6 45 E5 6B mov byte ptr [ebp-1Bh],6Bh 00411275 C6 45 E6 6F mov byte ptr [ebp-1Ah],6Fh 00411279 C6 45 E7 7A mov byte ptr [ebp-19h],7Ah 0041127D C6 45 E8 64 mov byte ptr [ebp-18h],64h 00411281 C6 45 E9 73 mov byte ptr [ebp-17h],73h 00411285 C6 45 EA 6C mov byte ptr [ebp-16h],6Ch 00411289 C6 45 EB 36 mov byte ptr [ebp-15h],36h 0041128D C6 45 EC 35 mov byte ptr [ebp-14h],35h 00411291 C6 45 ED 31 mov byte ptr [ebp-13h],31h 00411295 C6 45 EE 67 mov byte ptr [ebp-12h],67h 00411299 C6 45 EF 6F mov byte ptr [ebp-11h],6Fh 0041129D C6 45 F0 6F mov byte ptr [ebp-10h],6Fh 004112A1 C6 45 F1 00 mov byte ptr [ebp-0Fh],0 004112A5 C6 45 F2 00 mov byte ptr [ebp-0Eh],0 004112A9 C6 45 F3 00 mov byte ptr [ebp-0Dh],0 004112AD C6 45 F4 00 mov byte ptr [ebp-0Ch],0 } 004112B1 33 C0 xor eax,eax 004112B3 5F pop edi 004112B4 5E pop esi 004112B5 5B pop ebx 004112B6 8B E5 mov esp,ebp 004112B8 5D pop ebp 004112B9 C3 ret все равно криво приходится делить на 4 буквы вместо 1 так же неудобно
Функция не имеет возможности исполняться во время компиляции. А тут именно это и требуется, т.к. в программе после компиляции все строки уже зашифрованы должны быть. Боюсь, нормальным путем такое не реализуется даже с помощью шаблонов/C++0x.
так вынеси их в отдельный хидер и колдуй над ним на Pre-Build Event какимнить скриптом зы ток они у тя все глобальные получатся, но в любом случае с билдэвентами можно как минимум это сделать
2 sn0w ну этого была уже подобная реализация, которая запускала спец прогу которая генерила файл. НО это не удобно т.к. не даёт возможности оперативно менять значения. А скрипты (перл и php ) както не подходят
почему же не подходят? очень даже подходят, вот накидал прожект вместе с пхпешным энкодером (пришлось бинарники пхп добавить, поэтому 2метра), все на автомате, жуст пресс F7 )) ап добавил развернуто а то там дальше страсти начались (release конфиг) http://www.sendspace.com/file/thmq1i Code: // // gstrings.h // char g_name_str[] = "AAAAAAAAAAAAAAAA"; char *g_somestr_2 = "Wow it works, its \"awesome\""; char *g_somestr_3 = "And there we shift the data"; Code: // // stringtest.cpp // #include <stdio.h> #include <conio.h> #include "gstrings.enc" // edit gstrings.h instead of this header int main(int argc, char* argv[]) { printf("Encoded string: %s\n", g_name_str); printf("Encoded string: %s\n", g_somestr_2); printf("Encoded string: %s\n", g_somestr_3); return getch(); } Code: // // encode.php // <?php echo "ENCODE: executing encryption script...\r\n"; unlink("..\stringtest\gstrings.enc"); $lines = file("..\stringtest\gstrings.h"); $encheader = fopen("..\stringtest\gstrings.enc", 'wb') ; foreach ($lines as $line_num => $line) { $pos = strpos($line, '"'); fwrite($encheader, $line, $pos +1 ); for($i = $pos + 1; $i < strlen($line); $i++) { if($line[$i]==="\"") { if($line[$i-1]!=="\\") { fwrite($encheader, "\";\r\n", 4); break; } } fwrite($encheader, chr(ord($line[$i]) + 1), 1); // ALGORITHM: INCREASE BYTE VALUE BY 1 } } echo "ENCODE: done\r\n"; ?> Code: 1>------ Build started: Project: stringtest, Configuration: Release Win32 ------ 1>Build started 03.06.2011 17:58:37. 1>InitializeBuildStatus: 1> Creating "Release\stringtest.unsuccessfulbuild" because "AlwaysCreate" was specified. 1>PreBuildEvent: 1> ENCODE: executing encryption script... 1> ENCODE: done 1>ClCompile: 1> stringtest.cpp 1>Link: 1> Generating code 1> Finished generating code 1> stringtest.vcxproj -> D:\_coding\codes3\php_encode_strings\Release\stringtest.exe 1>FinalizeBuildStatus: 1> Deleting file "Release\stringtest.unsuccessfulbuild". 1> Touching "Release\stringtest.lastbuildstate". 1> 1>Build succeeded. 1> 1>Time Elapsed 00:00:00.52 ========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ========== output: Code: Encoded string: BBBBBBBBBBBBBBBB Encoded string: Xpx!ju!xpslt-!jut!]#bxftpnf]# Encoded string: Boe!uifsf!xf!tijgu!uif!ebub
Code: #include <cstdio> #define off 3 #define h ('h'+off) #define e ('e'+off) #define l ('l'+off) #define o ('o'+off) int main( void ) { char arr_init[] = { h, e, l, l, o, 0 }; printf( "str: %s\n", arr_init ); } Для каждой буквы одно макро, и все это в заголовочный файл, вот и секрет твоего счастья
Ну это понятно. Место i, j на крайняк можно написать index, idx, idx_j/i и т.д. И не обязательно header файл с макросами загружать в каждый *c файл. С пробелами? ' '+off;
i, j часто используются в for() как переменные-индексы, поэтому и говорю, что можно отказаться от этих названий.
можно кстати все строки в отдельный data_seg затолкать и после сборки проезжать по нему ксором или чем удобно. а при запуске проги, заведомо процедура с обратным ключом
можно так еще только чтоб компилятор выкинул ссылки на строки (и сами строки) надо включить оптимизацию или по размеру (O1) или по скорости (O2) или (Ox) и вот еще что если строка длиннее 103 символов вываливается ошибка .\main.c(22) : fatal error C1060: compiler is out of heap space тестил только на MSVC2008 Code: #include <stdio.h> #include <boost/preprocessor.hpp> #define CT_INIT_X2(z,n,text) BOOST_PP_TUPLE_ELEM(2, 0, BOOST_PP_TUPLE_ELEM(2, 0, text)) \ [n]=BOOST_PP_STRINGIZE(BOOST_PP_TUPLE_ELEM(2, 1, BOOST_PP_TUPLE_ELEM(2, 0, text))) \ [n]+(BOOST_PP_IF(BOOST_PP_NOT_EQUAL(n,BOOST_PP_TUPLE_ELEM(2, 1, text)),CT_INIT_MAGIC,0)) \ BOOST_PP_COMMA_IF(BOOST_PP_NOT_EQUAL(n,BOOST_PP_TUPLE_ELEM(2, 1, text))) #define CT_INIT_X1(z,n,text) (sizeof(BOOST_PP_STRINGIZE(BOOST_PP_TUPLE_ELEM(2, 1, text))) == n \ && (BOOST_PP_REPEAT(n, CT_INIT_X2, (text,BOOST_PP_DEC(n))))); #define def(buf,str) \ char buf[sizeof(#str)]; \ BOOST_PP_REPEAT_FROM_TO(2, 202, CT_INIT_X1, (buf,str)) #define CT_INIT_MAGIC 3 int main() { def(buf, zombie); printf(buf); } Code: output: }rpelhДля продолжения нажмите любую клавишу . . . Code: int main() { 00401000 55 push ebp 00401001 8B EC mov ebp,esp 00401003 51 push ecx 00401004 51 push ecx def(buf, zombie); printf(buf); 00401005 8D 45 F8 lea eax,[buf] 00401008 50 push eax 00401009 C6 45 F8 7D mov byte ptr [buf],7Dh 0040100D C6 45 F9 72 mov byte ptr [ebp-7],72h 00401011 C6 45 FA 70 mov byte ptr [ebp-6],70h 00401015 C6 45 FB 65 mov byte ptr [ebp-5],65h 00401019 C6 45 FC 6C mov byte ptr [ebp-4],6Ch 0040101D C6 45 FD 68 mov byte ptr [ebp-3],68h 00401021 C6 45 FE 00 mov byte ptr [ebp-2],0 00401025 FF 15 00 20 40 00 call dword ptr [__imp__printf (402000h)] 0040102B 59 pop ecx } 0040102C 33 C0 xor eax,eax 0040102E C9 leave 0040102F C3 ret
2 slesh вот еще одна реализация через switch компиляция быстрая нет ограничения на длинну http://pastecode.ru/765b/
Да дело всё в том, что данные должны быть именно как данные, а не код. И при надобности я бы их расшифровывал нужной мне функцией.
интересно а такой сценарий будет работать Code: int main() { /* * 1) добавлять $ в начало зашифрованных строк * в enc смотреть если $ сменился на & значит * уже была расшифрована просто возвращать адрес * иначе декодить менять $ на & и возвращать адрес */ char buf[]={enc("$crypt")}; puts(buf); call(enc("$zombie")); /* * 2) включить генерацию релоков получим все ссылки * на наши строки в Post-Build Event открываем * бинарик пробегаемся по всем адресам смотрим * если первый байт 0x24 наш $ шифруем * до терминатора (сколько микросекунд это займет ?) */ }