LINUX.ORG.RU

Функции препроцессора.

 


0

2

Hello!
Пишу программу на СИ и столкнулся вот с такой проблемой.
Конфигурация моей программы, происходит на этапе компиляции. Т.е. я вношу конфигурационные данные в исходник, потом собираю, получаю программу. Получается следующее, к примеру я в исходнике задаю пароль == 123456789 Получается простая строка, которая остаётся в бинарном файле. Простой cat ./program выводит с ходу мою строку. Мне хочется этого избежать.
Мне нужно как-то указать препроцессору, чтоб он изменил веденный мной пароль в исходниках, на этапе компиляции. Т.е. скажем я определяю функцию препроцессора , которая будет видоизменять данные по какому-то алгоритму. Далее в конфиг файле указываю пароль == 123456789 , начинаю компилировать программу, а gcc автоматически в бинарный файл не 123456789 вставляет, а результат моего алгоритма преобразования данной строки.
Как это сделать? и можно ли сделать вообще?

Deleted

Ответ на: комментарий от proofit404

Мне нужно потом будет этот оригинальный вид восстановить. А также в исходники модуля именно в открытом виде данные вводить(изза удобства).
Вопрос не только в сохранности пароля, его как пример привёл. Мне нужно будет преобразовать достаточно много разных данных.

Deleted ()
Ответ на: комментарий от Deleted

так тебе сохранность или «всё в исходниках»?
посмтри как в dwm congig.h сделан - можно всё в таком же стиле кроме пароля задать, а его у юзера спросить, верифицировать и т.д.

proofit404 ()
Последнее исправление: proofit404 (всего исправлений: 1)
Ответ на: комментарий от Deleted

Пароли в оригинальном виде хранить нельзя. На то они и пароли.

Мне нужно будет преобразовать достаточно много разных данных.

Ну так преобразуй все. Или скажи что за данные, если нельзя все преобразовать.

DesertFox ()
Последнее исправление: DesertFox (всего исправлений: 1)

1. Для выковыривания строк из бинарников есть утилита strings.

2. Ты-же понимаешь, что если пароль в принципе есть в программе, то кому надо - тот его достанет?

3. Препроцессор Си довольно дубовый, с ним такого, имхо, не сделать. Можно сделать так: вынести конфиг в отдельный файл .c, назвать его «config.c.txt». Внутри должен быть простой си-код вида «переменная = значение». Слабать на любом языке шифрующую утилиту такую, чтоб могла переваривать «config.c.txt» (т.е. не повзолять себе в этом файле никакого сложного си-синтаксиса, чтобы упростить утилиту). В мейкфайле добавить правило по генерации «config.c» из «config.c.txt» при помощи утилиты.

legolegs ★★★★★ ()
Последнее исправление: legolegs (всего исправлений: 1)

и при чём тут препроцессор :) храни такие данные отдельным файлом и сделай соотв. правило для Makefile .pass.o

MKuznetsov ★★★★★ ()
Ответ на: комментарий от legolegs

2. Ты-же понимаешь, что если пароль в принципе есть в программе, то кому надо - тот его достанет?

Да, расскажи нам про обращение криптостойких хэш-функций.

Manhunt ★★★★★ ()
Ответ на: комментарий от Manhunt

Тред не читай @ сразу овтечай?

ТС пишет:

Мне нужно потом будет этот оригинальный вид восстановить.

geekless ★★ ()
Ответ на: комментарий от MKuznetsov

MKuznetsov
Каким образом сделать это правило для Makefile ? И как потом получить доступ к этим данным в программе?

legolegs
Спасибо за совет с дополнительной утилитой (сам тоже о ней думал). Но пока надо рассмотреть варианты упрощённого решения проблемы. А то если сделаю утилиту, то скорее всего надо будет и её и код постоянно редактировать , при внесении новых функций в программу.
А насчёт второго пункта «Ты-же понимаешь, что если пароль в принципе есть в программе, то кому надо - тот его достанет?» разумеется. Но в моём случае, на данном этапе я хочу лишь видоизменить строки которые можно самым простым способом из кода вытянуть.

Хм, я тут подумал а как криптовку файла делать?

Deleted ()

Не взлетит. Препроцессор C не Тюринг полный, что есть очень хорошо.

beastie ★★★★★ ()
Ответ на: комментарий от Deleted

Нравится ли Вам LISP?

$ cat c.c
#define s(a) a^0xc
#define o(p, q) s(p), q

char password[]={o(
'p',o(
'a',o(
's',o(
's',o(
'w',o(
'o',o(
'r',s(
'd'))))))))};

$ cpp c.c
# 1 "c.c"
# 1 "<command-line>"
# 1 "c.c"



char password[]={'p'^0xc, 'a'^0xc, 's'^0xc, 's'^0xc, 'w'^0xc, 'o'^0xc, 'r'^0xc, 'd'^0xc







           };
Manhunt ★★★★★ ()
Ответ на: Нравится ли Вам LISP? от Manhunt

Очень сильно боюсь показаться глупым) но если не сложно прокомментируйте выше описанный код.

Deleted ()

Т.е. sha512 придумали для чего-то другого?

Eddy_Em ☆☆☆☆☆ ()
Ответ на: комментарий от Deleted

Мне нужно потом будет этот оригинальный вид восстановить

Ну, ты понял, кем надо быть, чтобы пароли в восстанавливаемом виде хранить…

Eddy_Em ☆☆☆☆☆ ()
Ответ на: Нравится ли Вам LISP? от Manhunt
$ cat c.c
#define o(p, q) p, p ^ q

char password[]={o(
'p',o(
'a',o(
's',o(
's',o(
'w',o(
'o',o(
'r',
'd')))))))};

$ cpp c.c
# 1 "c.c"
# 1 "<command-line>"
# 1 "c.c"


char password[]={'p', 'p' ^ 'a', 'a' ^ 's', 's' ^ 's', 's' ^ 'w', 'w' ^ 'o', 'o' ^ 'r', 'r' ^ 'd'







          };
Manhunt ★★★★★ ()
Ответ на: комментарий от Deleted

Каждая буква пароля, который я в столбик вбил в исходном коде, была силами препроцессора проксорена с числом 0xC.

Manhunt ★★★★★ ()
Ответ на: комментарий от beastie

Препроцессор C не Тюринг полный

Вот же блин! Облазил всю педивикию, так и не врубился, что за хрень такая — полнота по Тьюрингу!

Пишут, что мол, если можно сделать что угодно — это полнота по Тьюрингу. А если нельзя что угодно — не полнота. Но при этом т.к. количество оперативки и реальные тики ограничены — хрена с два где есть полнота по Тьюрингу в общем, однако, в частном она много где есть.

/0 Ушел в "атсрал".

Eddy_Em ☆☆☆☆☆ ()
Ответ на: комментарий от beastie

Препроцессор C не Тюринг полный, что есть очень хорошо

Это не есть, это давиться. Ужаснись:
http://www.boost.org/doc/libs/1_53_0/libs/preprocessor/doc/examples/array_ari...
http://www.boost.org/doc/libs/1_53_0/libs/preprocessor/doc/examples/duffs_dev...
http://www.boost.org/doc/libs/1_53_0/libs/preprocessor/doc/examples/linear_fib.c

Люди пишут на препроцессоре циклы, в том числе вложенные, итерируются по спискам, и творят прочие бесчинства. Если задуматься, то привычные нам микропроцессоры тоже не тюринг-полны: компьютерной памяти на планете Земля ограниченное количество. При ограниченном количестве памяти это никакая не машина Тюринга, а унылый конечный автомат. Но кого это останавливало?

Manhunt ★★★★★ ()
Последнее исправление: Manhunt (всего исправлений: 4)
Ответ на: комментарий от Manhunt

Ужаснулся. Это содомия. Но всё равно это только кодогенерация. На самом препроцессоре где сядешь там и встанешь. Но извратиться, можно конечно по славному. В прочем, за такое кастрировать надо, дабы не размножались. ☺

beastie ★★★★★ ()
Последнее исправление: beastie (всего исправлений: 1)
Ответ на: комментарий от Deleted

Каким образом сделать это правило для Makefile ? И как потом получить доступ к этим данным в программе?

см. пщщду (google) по поводу objcopy binary blob - там всё написано. И плюс man make

MKuznetsov ★★★★★ ()
Ответ на: комментарий от Manhunt

ОГРОМНОЕ СПАСИБО
Кажется это то что нужно.. очень удобно в мой код вставлять.
А теперь хочу уточнить как надо макрос подредактировать , чтоб преобразование делать над строками. Такое возможно вообще?
Допустим у меня есть массив строк
stroki[COUNT_STRINGS][len_2] = { {STROKA_1}, {STROKA_2} }
как сделать такоеже преобразование как в вашем верхнем примере? только для каждого символа в массиве строк?

Deleted ()

1. Шифруешь данные <твой-любимый-симметричный-алгоритм-шифрования>.

2. Линкуешься с библиотекой которая твой алгоритм реализвует.

3. Во время выполнения программы спрашиваешь у пользователя пароль, из пароля получаешь ключь, пробуешь расшифровать данные.

4. Если первая буква в данных верная (ее можно хранить незашифрованную), то данные верные - можно работать дальше.

5. Теперь ты настоящий неуловимый Джо!

trex6 ★★★★★ ()
Ответ на: комментарий от trex6

ее можно хранить незашифрованную

Плохой совет. Лучше взять MAC из той библиотеки.

i-rinat ★★★★★ ()
Ответ на: комментарий от i-rinat

Главное ключ шифрования 3х мегабитный исопльзовать, буква не решает.

trex6 ★★★★★ ()

Народ, как указать препроцессору? чтоб он произвел xor над каждым элементом строки?
У меня есть массив строк, и я каждую строку передаю в макрос препроцессора. Тоесть:

STRINGS_array = {
my_crypt({STRING_0}),
my_crypt({STRING_1}),
my_crypt({STRING_2})
};

Допустим STRING_0 = «тестовая строка»
my_crypt это название моей «функции препроцессора» которая должна преобразовать строку.
Как написать макрос? чтоб препроцессор произвёл xor над каждой буквой данной строки???

Deleted ()
Ответ на: комментарий от Manhunt

Вот эта вот штука:

char password[]={'p', 'p' ^ 'a', 'a' ^ 's', 's' ^ 's', 's' ^ 'w', 'w' ^ 'o', 'o' ^ 'r', 'r' ^ 'd'}
Будет очень плохо заоптимизирована кучей инструкций, записывающих по байтику я об этом даже писал в тред Хеллоуворлд на С из ассемблерных вставок (комментарий) и в маил-лист http://gcc.1065356.n5.nabble.com/Ways-to-fill-the-stack-td912561.html#none

Да, эти байтики будут вписаны в память уже в отксореном по сдвигу на байтик виде. Похожим образом работает дельта-кодирование. Процедура шифрования и расшифровки должна будет ксорить это, по ней не сложно будет узнать пароль. Серьезной защитой тут и не пахнет, лучше считать перед компиляцией хеш с солью от пароля, результат записывать в файл, который потом куда-то там инклудится в исходный код. Это называется метапрограммированием.

SZT ★★★ ()
Ответ на: комментарий от SZT

Мне нужно не с паролем работать. Его я привёл как пример. Мне нужно просто на данном этапе скрыть строки в программе, которые легко можно выдернуть через strings или cat .
И пока вопрос остаётся открытым, как написать функцию препроцессора, чтоб она произвела модификацию каждого символа, в переданной ей строке.

Deleted ()
Ответ на: комментарий от Deleted

А теперь хочу уточнить как надо макрос подредактировать , чтоб преобразование делать над строками. Такое возможно вообще?

Если и возможно, то я такого способа не знаю. Лучше вместо препроцессора использовать сторонние программы: в духе того, что предложил MKuznetsov

Manhunt ★★★★★ ()
Ответ на: комментарий от SZT

Вот эта вот штука Будет очень плохо заоптимизирована кучей инструкций, записывающих по байтику

По-моему, всё отлично оптимизировано:

$ cat c.c
char password[]={'p', 'p' ^ 'a', 'a' ^ 's', 's' ^ 's', 's' ^ 'w', 'w' ^ 'o', 'o' ^ 'r', 'r' ^ 'd'};

$ gcc -O2 -S c.c
$ cat c.s
	.file	"c.c"
	.globl	password
	.data
	.type	password, @object
	.size	password, 8
password:
	.byte	112
	.byte	17
	.byte	18
	.byte	0
	.byte	4
	.byte	24
	.byte	29
	.byte	22
	.ident	"GCC: (SUSE Linux) 4.7.1 20120723 [gcc-4_7-branch revision 189773]"
	.section	.comment.SUSE.OPTs,"MS",@progbits,1
	.string	"Ospwg"
	.section	.note.GNU-stack,"",@progbits

$ gcc -O2 -c c.c
$ objdump -s --section=.data c.o

c.o:     file format elf64-x86-64

Contents of section .data:
 0000 70111200 04181d16                    p.......        

Manhunt ★★★★★ ()
Ответ на: комментарий от Manhunt

Попробуй этот пароль в main{} объявить и потом вызвать некую функцию foo(password);

SZT ★★★ ()
Ответ на: комментарий от Deleted

На макросах так на макросах

#include <string.h>
#include <unistd.h>

#define encodepass(var, pass)\
char var[sizeof(pass)-1];\
{\
  char _tmp[sizeof(pass)-1] = (pass);\
  char *_a= _tmp;\
  do\
  {\
    *_a ^= *(_a+1);\
    _a++;\
  } while( _a < &(_tmp[sizeof(pass)-1]) - 1 );\
  memcpy(var, _tmp, sizeof(pass)-1);\
}

#define decodepass(enc, dec)\
memcpy(dec, enc, sizeof(dec));\
{\
  char *_a= dec+sizeof(dec)-2;\
  do\
  {\
    *_a ^= *(_a+1);\
    _a--;\
  }while( _a >= dec);\
}



int main(void)
{
  encodepass(a, "asdasd"); // Создает переменную char a[длина_пароля] и пишет в нее зашифрованный пароль
  char b[sizeof(a)];
  decodepass(a, b); // Пишет в b расшифрованный пароль

  write(1, b, sizeof(b));
  return 0;
}

SZT ★★★ ()

давай ты будешь азы учить? Почитай про Принцип Керкгоффса, и поймёшь, что твой подход был признан убогим ещё в позапрошлом веке.

drBatty ★★ ()
Ответ на: комментарий от Deleted

Мне нужно не с паролем работать. Его я привёл как пример. Мне нужно просто на данном этапе скрыть строки в программе, которые легко можно выдернуть через strings или cat .

зашифруй. Используй общедоступные библиотеки для шифрования. Часто «шифрование» можно использовать одностороннее. Например тот же пароль вовсе не обязательно расшифровывать. Необходимо и достаточно только _проверять_, и ничто тебе не мешает проверять уже зашифрованные пароли, даже если обратная расшифровка принципиально невозможна. Это общепринятая практика, ты говоришь «это пример», хорошо, а что НЕ пример?

drBatty ★★ ()
Ответ на: комментарий от SZT

Этот метод не решает поставленную перед ТС задачу.

legolegs ★★★★★ ()

Вопрос всё ещё открыт.

Deleted ()
Ответ на: комментарий от Deleted

Сишный препроцессор для этого не предназначен. Нужно или использовать другой препроцессор, или средства самого языка

SZT ★★★ ()
Ответ на: комментарий от Deleted

Вопрос как раз закрыт. Сишный препроцессор не предназначен для таких извращений. Добиться то конечно этого можно, но это будет так уродливо, что лучше и не пытаться.

beastie ★★★★★ ()
Ответ на: комментарий от SZT

не посоветуете какойнить подходящий препроцессор?

Deleted ()

НАРОД! помогайте! не пропадайте) посоветуйте хотябы альтернативу! Как закриптовать строки в бинарнике??? (хеши не предлагайте. мне нужно восстанавливать данные)

Deleted ()

Ну так задай пароль "\0xdd\0xa1\0x56\0x52\0xa6\0xf6\0x4e..."

ziemin ★★ ()
Ответ на: комментарий от ziemin

Автоматизировать както упрощённо можно? «кодировку» строк?

Deleted ()
Ответ на: комментарий от Deleted
$head -c 10 /dev/random | hd | sed 's/ /\\0x/g'
00000000\0x\0x4f\0xfc\0x55\0x0a\0xbc\0x2c\0x3a\0x0b\0x\0x46\0x16\0x\0x\0x\0x\0x\0x\0x\0x\0x\0x\0x\0x\0x\0x\0x\0x\0x\0x\0x\0x|O.U..,:.F.|
0000000a

И копируешь середину.
ziemin ★★ ()
Ответ на: комментарий от Manhunt

Да, расскажи нам про обращение криптостойких хэш-функций.

Если программа может использовать с пользой хэш, можно выдрать хэш, нафига тебе оригинальный пароль, если достаточно хэша?

unC0Rr ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.