Мне нужно защитить часть кода от изменения, этот код расположен в функции-члене. Как мне получить адрес памяти в которой расположен этот код чтобы рассчитать его контрольную сумму? Примеры из интернета предоставляют указатель на функцию-член, но он в дальнейшем используется для вызова этого метода, да и к void* его не приведёшь, он занимает больше байт.
Здравствуйте, zheka2, Вы писали:
Z>Мне нужно защитить часть кода от изменения, этот код расположен в функции-члене. Как мне получить адрес памяти в которой расположен этот код чтобы рассчитать его контрольную сумму? Примеры из интернета предоставляют указатель на функцию-член, но он в дальнейшем используется для вызова этого метода, да и к void* его не приведёшь, он занимает больше байт.
Если твой код изменят, то изменить проверку CRC с jz на jnz так же легко. Озаботился защитой программы, почитай форум Shareware и бизнес, там про это много говорится.
Здравствуйте, zheka2, Вы писали:
Z>Мне нужно защитить часть кода от изменения, этот код расположен в функции-члене. Как мне получить адрес памяти в которой расположен этот код чтобы рассчитать его контрольную сумму? Примеры из интернета предоставляют указатель на функцию-член, но он в дальнейшем используется для вызова этого метода, да и к void* его не приведёшь, он занимает больше байт.
CRC предназначен для защиты от случайных изменений — помехоустойчивый код. Нельзя с помощью него защищать от злонамеренного изменения. Ненадежно.
Здравствуйте, baily, Вы писали:
B>Здравствуйте, zheka2, Вы писали:
Z>>Мне нужно защитить часть кода от изменения, этот код расположен в функции-члене. Как мне получить адрес памяти в которой расположен этот код чтобы рассчитать его контрольную сумму? Примеры из интернета предоставляют указатель на функцию-член, но он в дальнейшем используется для вызова этого метода, да и к void* его не приведёшь, он занимает больше байт.
B>CRC предназначен для защиты от случайных изменений — помехоустойчивый код. Нельзя с помощью него защищать от злонамеренного изменения. Ненадежно.
Спасибо за совет, ну пусть не CRC, алгоритм можно подобрать и потом, сейчас я указатель не могу получить.
Здравствуйте, Igore, Вы писали:
I>Здравствуйте, zheka2, Вы писали:
Z>>Мне нужно защитить часть кода от изменения, этот код расположен в функции-члене. Как мне получить адрес памяти в которой расположен этот код чтобы рассчитать его контрольную сумму? Примеры из интернета предоставляют указатель на функцию-член, но он в дальнейшем используется для вызова этого метода, да и к void* его не приведёшь, он занимает больше байт.
I>Если твой код изменят, то изменить проверку CRC с jz на jnz так же легко. Озаботился защитой программы, почитай форум Shareware и бизнес, там про это много говорится.
Всё же лучше чем ничего, я планирую разместить проверку в совсем другой части программы и замаскировать. От дурака поможет.. В любом случае, как получить указатель?
За ссылку спасибо, посмотрю
Здравствуйте, zheka2, Вы писали: Z>Мне нужно защитить часть кода от изменения, этот код расположен в функции-члене. Как мне получить адрес памяти в которой расположен этот код чтобы рассчитать его контрольную сумму? Примеры из интернета предоставляют указатель на функцию-член, но он в дальнейшем используется для вызова этого метода, да и к void* его не приведёшь, он занимает больше байт.
Сейчас я тебе покажу одно черное шаманство, которое сам когда-то использовал по молодости. Ты только никому не говори, что это я тебе посоветовал.
Допустим, функция, дамп тела которой ты хочешь получить, выглядит так:
Теперь, чтоб осуществить задуманное, нам надо добавить к списку параметров этой функции пару указателей (на указатели), которые будут принимать адреса начала и конца тела функции. Ну и добавить в саму функцию код, заполняющий эти указатели нужными значениями:
Эти два новых параметра мы снабжаем нулевыми значениями по умолчанию. Теперь эту функцию можно вызывать в двух режимах: если последние два параметра не указаны, то функция выполняет свою штатную работу как и раньше:
foo("Hello, World!!!");
Если же последние два параметра заданы, то функция вместо своей штатной работы возвращает через них начало и конец своего тела:
Никто не может гарантировать, что полезный код функции будет располагаться между метками _begin и _end.
Сама функция может оказаться встроенной (inline), если компилятор так решит.
И нужно уточнить у автора, сможет ли он обойтись без кроссплатформенности.
Здравствуйте, zheka2, Вы писали:
Z>Мне нужно защитить часть кода от изменения, этот код расположен в функции-члене. Как мне получить адрес памяти в которой расположен этот код чтобы рассчитать его контрольную сумму? Примеры из интернета предоставляют указатель на функцию-член, но он в дальнейшем используется для вызова этого метода, да и к void* его не приведёшь, он занимает больше байт.
Вот так я это делаю у себя:
#ifdef PLATFORM_32
typedef agg::int32u hack_label;
#elif PLATFORM_64
typedef agg::int64u hack_label;
#endif
}
#ifdef WIN
#define set_label_address( to, lbl ) __asm { mov dword ptr to, offset lbl }
#else
#define set_label_address( to, lbl ) to = reinterpret_cast<hack_label>(&&lbl)
#endif
#define define_label( name ) \
name: ;
#define define_label_begin( name ) \
name##_BEGIN: ;
#define define_label_end( name ) \
name##_END: ;
#define label_begin( name ) name##_BEGIN
#define label_end( name ) name##_END
#define define_var_label_begin( name ) \
code_hacks::hack_label var_##name; \
set_label_address( var_##name, name ); \
name:
#define define_var_label_end( name ) \
name: \
code_hacks::hack_label var_##name; \
set_label_address( var_##name, name );
Использование:
void foo()
{
hack_label lb, le, len;
set_label_address( lb, label_begin(protect_code) );
set_label_address( le, label_end(protect_code) );
//длинна
le -= lb;
//делаешь чо тебе там надо
define_label_begin( protect_code )
//protected codeint kkk = 0;
kkk += 1;
define_label_end( protect_code )
}
Во общем разберешься. Это работает как для Win так и для Mac в том числе ppc.
Dump или что там тебе надо делаешь до меток.
Проблема в другом, всякое изменение кода, даже не в этом модуле трансляции повлечет изменения сгенерированого кода между между метками
, в частности особенно если в коде используются инструкции перехода или сравнения.
Как это победить уже думай сам.
Здравствуйте, zheka2, Вы писали:
Z>Мне нужно защитить часть кода от изменения, этот код расположен в функции-члене. Как мне получить адрес памяти в которой расположен этот код чтобы рассчитать его контрольную сумму? Примеры из интернета предоставляют указатель на функцию-член, но он в дальнейшем используется для вызова этого метода, да и к void* его не приведёшь, он занимает больше байт.
Проблемы-то нет.
1) Выносишь метод в отдельный cpp
2) Транслируешь его до asm'а
3) asm обрабатываешь зашифровщиком и добавляешь туда две метки на начало и на конец кода + добавляешь, например, две функции, одна возвращает начало. а другая длину...
Только не понятно как ты будешь это всё грузить. Так как загрузчик при загрузке настраивает адреса...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, rg45, Вы писали: R>Здравствуйте, zheka2, Вы писали: Z>>Мне нужно защитить часть кода от изменения, этот код расположен в функции-члене. Как мне получить адрес памяти в которой расположен этот код чтобы рассчитать его контрольную сумму? Примеры из интернета предоставляют указатель на функцию-член, но он в дальнейшем используется для вызова этого метода, да и к void* его не приведёшь, он занимает больше байт. R>Сейчас я тебе покажу одно черное шаманство, которое сам когда-то использовал по молодости. Ты только никому не говори, что это я тебе посоветовал. R>Допустим, функция, дамп тела которой ты хочешь получить, выглядит так: R>
R>Теперь, чтоб осуществить задуманное, нам надо добавить к списку параметров этой функции пару указателей (на указатели), которые будут принимать адреса начала и конца тела функции. Ну и добавить в саму функцию код, заполняющий эти указатели нужными значениями: R>
R>Эти два новых параметра мы снабжаем нулевыми значениями по умолчанию. Теперь эту функцию можно вызывать в двух режимах: если последние два параметра не указаны, то функция выполняет свою штатную работу как и раньше: R>
R>foo("Hello, World!!!");
R>
R>Если же последние два параметра заданы, то функция вместо своей штатной работы возвращает через них начало и конец своего тела: R>
Здравствуйте, andrey_nado, Вы писали:
_>Здравствуйте, rg45, Вы писали:
_>Никто не может гарантировать, что полезный код функции будет располагаться между метками _begin и _end. _>Сама функция может оказаться встроенной (inline), если компилятор так решит. _>И нужно уточнить у автора, сможет ли он обойтись без кроссплатформенности.
Посмотрю в отладчике, на inline она вроде не тянет, слишком большая. За заметку спасибо.
А кроссплатформенность там вообще не нужна
Спасибо за ответ, хочу уточнить
N>Проблема в другом, всякое изменение кода, даже не в этом модуле трансляции повлечет изменения сгенерированого кода между между метками N>, в частности особенно если в коде используются инструкции перехода или сравнения.
это имеется в виду, что если я вношу изменения в текст программы не имеющий отношения к защищаемой функции, то её контрольной значение поменяется из-за изменения адресов в jmp инструкциях, так?
Здравствуйте, Erop, Вы писали:
E>3) asm обрабатываешь зашифровщиком и добавляешь туда две метки на начало и на конец кода + добавляешь, например, две функции, одна возвращает начало. а другая длину...
Здравствуйте, andrey_nado, Вы писали:
_>Никто не может гарантировать, что полезный код функции будет располагаться между метками _begin и _end. _>Сама функция может оказаться встроенной (inline), если компилятор так решит. _>И нужно уточнить у автора, сможет ли он обойтись без кроссплатформенности.
Ну побороть inline не трудно — просто выносишь определение функции в отдельный модуль.
А в том, что этот код не переносим меня можно не убеждать, я и сам это прекрасно понимаю. Я ж сразу написал — шаманство черное
--
Не можешь достичь желаемого — пожелай достигнутого.
Здравствуйте, zheka2, Вы писали:
Z>Здравствуйте, nen777w
Z>Спасибо за ответ, хочу уточнить
N>>Проблема в другом, всякое изменение кода, даже не в этом модуле трансляции повлечет изменения сгенерированого кода между между метками N>>, в частности особенно если в коде используются инструкции перехода или сравнения.
Z>это имеется в виду, что если я вношу изменения в текст программы не имеющий отношения к защищаемой функции, то её контрольной значение поменяется из-за изменения адресов в jmp инструкциях, так?
Не обязательно такое случается если это происходит в другом модуле компиляции (тут как линкеру понравится), но гарантировано если в этом же.
По крайней мере мне пришлось у себя бороть эту проблему.
Борол кстати таким образом.
Брал под метки код защищаемой части и отдельно под метки ту часть которая сбрасывала код.
Код который занимался сбросом защищаемой части также сбрасывал в файл свой размер.
Код который сбрасывал защищаемую часть был описан макросами это давало возможность в одном режиме (в зависимости от конфигурации макросов) сбрасывать в другом генерировать вместо него инструкции nop, благодаря тому что размер nop — 1 байт.
Чуть сложнее пришлось под ppc там nop занимает аж 4-ре байта, поэтому пришлось предусмотреть выравнивание.
Здравствуйте, zheka2, Вы писали: Z>это имеется в виду, что если я вношу изменения в текст программы не имеющий отношения к защищаемой функции, то её контрольной значение поменяется из-за изменения адресов в jmp инструкциях, так?
И даже от загрузке к загрузке может меняться...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Erop, Вы писали:
E>Здравствуйте, zheka2, Вы писали: Z>>это имеется в виду, что если я вношу изменения в текст программы не имеющий отношения к защищаемой функции, то её контрольной значение поменяется из-за изменения адресов в jmp инструкциях, так?
E>И даже от загрузке к загрузке может меняться...
разве что в длл, в конкретном скомпилированном экземпляре EXE файла CRC участка будет неизменна при всех загрузках.
Проблемы никакой нет, есть куча протектором, позволяющих маркирвать участки кода и проверять их целосность либо дешифровывать в процессе работы программы. И написать такое — это 2 вечера посидеть.
Здравствуйте, nen777w, Вы писали:
N>Здравствуйте, zheka2, Вы писали:
Z>>Здравствуйте, nen777w
Z>>Спасибо за ответ, хочу уточнить
N>>>Проблема в другом, всякое изменение кода, даже не в этом модуле трансляции повлечет изменения сгенерированого кода между между метками N>>>, в частности особенно если в коде используются инструкции перехода или сравнения.
Z>>это имеется в виду, что если я вношу изменения в текст программы не имеющий отношения к защищаемой функции, то её контрольной значение поменяется из-за изменения адресов в jmp инструкциях, так?
N>Не обязательно такое случается если это происходит в другом модуле компиляции (тут как линкеру понравится), но гарантировано если в этом же. N>По крайней мере мне пришлось у себя бороть эту проблему. N>Борол кстати таким образом. N>Брал под метки код защищаемой части и отдельно под метки ту часть которая сбрасывала код. N>Код который занимался сбросом защищаемой части также сбрасывал в файл свой размер. N>Код который сбрасывал защищаемую часть был описан макросами это давало возможность в одном режиме (в зависимости от конфигурации макросов) сбрасывать в другом генерировать вместо него инструкции nop, благодаря тому что размер nop — 1 байт. N>Чуть сложнее пришлось под ppc там nop занимает аж 4-ре байта, поэтому пришлось предусмотреть выравнивание.
В общих чертах понятно, но вопросы есть, если мы заменяем код сброса в файл хеша на nop'ы как избежать перекомпиляции? это опять приведёт к изменению хеша
На данный момент я не могу понять как запихнуть полученный хэш в программу, так чтобы после сборки он не изменился. Работаю в Visual C++ 2008 и после изменению любого файла проекта хеш получается новый. Разве что править в hex-редакторе