JDW
Мы открываем бизнес
- Сообщения
- 376
- Реакции
- 325
Всем, привет. Нашел силы в себе и наконец закончил данную статью.
Сама суть идеи: зашифровываем плагин (бинарник) и расшифровываем его при загрузки в память vm.
Плюсы: Плагин зашифрован и его просто так не прочитаешь (прощайте декомпиляторы)
Плагины, которые не зашифрованы так же будут дальше работать.
Минусы: Для каждого ключа нужна своя версия sourcepawn.jit.x86.so.
1) Начнем с написания программы, которая будет зашифровывать плагин.
2) Модифицируем код виртуальной машины
Открываем sourcepawn/vm/api.cpp
Добавляем в начале файла следующий заголовок:
Далее ищем следующую функцию (где-то на 252 строке):
И после:
Добавляем следующий код:
После следующих строк:
Добавляем:
3) Сохраняем и компилируем
Сама суть идеи: зашифровываем плагин (бинарник) и расшифровываем его при загрузки в память vm.
Плюсы: Плагин зашифрован и его просто так не прочитаешь (прощайте декомпиляторы)
Плагины, которые не зашифрованы так же будут дальше работать.
Минусы: Для каждого ключа нужна своя версия sourcepawn.jit.x86.so.
1) Начнем с написания программы, которая будет зашифровывать плагин.
Src:
#include <string>
#include <vector>
#include <cstdio>
using std::string;
using std::vector;
const string key = "Your key";
const char* pluginName = "test.smx";
int main()
{
FILE* file = fopen(pluginName, "rb");
fseek(file, 0, SEEK_END);
vector<char> data(ftell(file));
fseek(file, 0, SEEK_SET);
char ch;
for (size_t i = 0; i < data.size(); i++)
data[i] = fgetc(file);
fclose(file);
// Здесь идет само шифрование
for (size_t i = 0; i != data.size(); i++)
data[i] ^= key[i % key.size()];
file = fopen("output.smx", "wb");
for (size_t i = 0; i < data.size(); i++)
fputc(data[i], file);
fclose(file);
return 0;
}
2) Модифицируем код виртуальной машины
Открываем sourcepawn/vm/api.cpp
Добавляем в начале файла следующий заголовок:
src:
#include <vector>
src:
IPluginRuntime*
SourcePawnEngine2::LoadBinaryFromFile
src:
FILE* fp = fopen(file, "rb");
if (!fp) {
UTIL_Format(error, maxlength, "file not found");
return nullptr;
}
src:
const std::string key = "Your key"; //Ваш ключ (Который использовался при шифрование)
uint32_t magic;
char* buffer = nullptr;
if (fread(&magic, sizeof(uint32_t), 1, fp) != 1)
{
return nullptr;
}
if (magic != SmxConsts::FILE_MAGIC)
{
fseek(fp, 0, SEEK_END);
std::vector<char> data(ftell(fp));
fseek(fp, 0, SEEK_SET);
for (size_t i = 0; i < data.size(); i++)
data[i] = fgetc(fp);
for (size_t i = 0; i != data.size(); i++)
data[i] ^= key[i % key.size()];
fclose(fp);
char* buffer = (char*)malloc(data.size());
std::copy(data.begin(), data.end(), buffer);
fp = fmemopen(buffer, data.size(), "rb");
}
src:
std::unique_ptr<SmxV1Image> image(new SmxV1Image(fp));
fclose(fp);
src:
if (buffer != nullptr) free(buffer);
3) Сохраняем и компилируем
Последнее редактирование модератором: