LINUX.ORG.RU

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

 


0

2

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

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

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

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

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

Deleted
()
Ответ на: комментарий от 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
$ 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 ★★★★★
()
Ответ на: комментарий от Deleted

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

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

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

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

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 ★★★★★
()
Ответ на: комментарий от Deleted

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

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

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

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

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