В конечном счете, вы не можете остановить кого-то, кто определен, но вы можете сделать несколько вещей, чтобы усложнить жизнь неавторизованным пользователям.
Очевидным было бы зашифровать (по крайней мере, большую часть) кода вDLL.Имейте единственную точку входа, которую пользователь должен вызвать, чтобы получить (например) таблицу указателей на реальные функции.Когда вызывается точка входа, должен быть предоставлен ключ, который используется для расшифровки остальной части содержимого, а затем возвращаются указатели.Если пользователь вводит неправильный ключ, он получает указатели, но данные не будут расшифрованы правильно, поэтому, когда они пытаются вызвать его, он не работает.
Это не надежно ни в коем случае.Просто для наглядного примера: если кто-то запускает авторизованную программу под отладчиком, он может увидеть, какой ключ передан, и просто повторно использовать его.Если вы хотите немного усложнить жизнь злоумышленнику, вы можете сделать что-то, например, заставить DLL выполнить контрольную сумму на исполняемом файле и использовать ее в качестве ключа (и пользователю придется встраивать некоторые данные, чтобы получить контрольную сумму)прямо).Это все еще можно выяснить, но это по крайней мере потребует некоторой работы.
Редактировать: Точное шифрование не имеет большого значения.Я бы, вероятно, использовал AES, просто потому, что легко найти реализацию и она работает довольно быстро, поэтому нет особой причины использовать что-то еще.
Что касается работы вызывающего кода, то это будетчто-то вроде этого:
struct functions {
rettype1 (*func1)(args1);
rettype2 (*func2)(args2);
rettype3 (*func3)(args3);
// ...
};
void entry_point(key_type key) {
functions f;
decrypt(data_block);
f.func1 = data_block.offset1;
f.func2 = data_block.offset2;
// ...
return f;
}
В вызывающем коде у вас будет инициализация, например:
functions f = entry_point(myKey);
, а затем вызов функции будет выглядеть примерно так:
f.whatever(arg1, arg2, arg3);
По сути, вы воссоздаете небольшой кусочек объектно-ориентированного программирования, и ваша точка входа возвращает своего рода "объект", с реальными функциями DLL в качестве "функций-членов" этого "объекта".
Что касается получения контрольной суммы, я не продумал ее до мелочей.В основном просто хочу адрес, где хранится исполняемый файл.Вы можете пройтись по модулям с помощью VirtualQuery или использовать GetModuleHandle (NULL).